SwiftDataを徹底的に解説!これでDB怖くない!(永久保存版)

どうも3urpriseのヤマサキです。

タイトルにある通り私の苦手なDBを克服するべく流行りのSwiftDataを徹底解説します。

まさに永久保存版なので私含めた初心者は穴があくほど眺めるのをお勧めします。

 

SwiftDataとは

Objective-C時代にDBとを使うと言えばCoreDataかSQLiteのFMDBが主流だったと思います。

(あくまで主観です、ちなみに私たちの作成アプリ iDrawer はSQLiteのFMDBを使っています)

 

SwiftData : 商用可能 , 無料 , SQLiteラッパー , 記述が少しで済む

う〜ん、最高ですね。使わない訳が無い。

開発者様、ありがとうございます!

それでは簡単な説明も終わりましたので本題の解説に入ります。

まずはファイルをゲッツします。

https://github.com/ryanfowler/SwiftData

 

スクリーンショット 2015-02-04 22.58.31

 

右下のZIPをクリックしてダウンロードしたらSwiftDataのファイルは準備OKです。

それでは新規プロジェクトを立ち上げます。

Xcode > File > SingleView > プロジェクト名 > Swift言語使用 > Create でプロジェクト作成

今回はSwiftDataを理解しよう!のコーナーなのでStoryboardなどは極力使いません。ボタンぐらいかな。

状態の確認は全てデバックエリア(Logが出てくるエリア)で見る事にします。

スクリーンショット 2015-02-04 23.04.51

赤字が名称で黒字がショートカットです。

それではSwiftDataを使える様にしましょう。

まずはFrameworks and Librariesにlibsqlite3.dylib

スクリーンショット 2015-02-04 23.20.52

写真では追加した後ですが番号4をクリックして

 

スクリーンショット 2015-02-04 23.21.27

 

libsqlite3.dylibをクリックして下さい。

 

スクリーンショット 2015-02-04 23.25.32

 

プロジェクトの中に追加されればOKです。

次に先ほどダウンロードしたSwiftData.swiftをlibsqlite3.dylibの下にでもドラッグして追加しましょう。

 

スクリーンショット 2015-02-04 23.28.09

できたらヘッダーファイルを作成します。

写真の様に右クリックから

スクリーンショット 2015-02-04 23.31.19

スクリーンショット 2015-02-04 23.31.32

スクリーンショット 2015-02-04 23.31.54

 

スペル間違いだけ気を付けて下さい。(私はスペル間違いでもの凄い時間と精神力を削がれた)

Briding-Header

Briding-Headerと入力しCreateボタンを押すとBriding-Header.hが作成されますのでその中に一行追加します。

#import “sqlite3.h”

 

スクリーンショット 2015-02-04 23.36.20

 

次で準備は完了です、もうちょっと頑張って!

スクリーンショット 2015-02-04 23.37.35

写真通りの手順でクリックしていき、番号5はobjective-c bを入力

番号6は空なのでダブルクッリックし入力します。

この時もスペル間違いに気を付けて下さい。

ここまでで準備は完了です。

 

Sponsored Link

 

ここからはSwiftDataのデータ内容をコードで追加していきます。

ファイルの作成はさっきと同じく右クリックのFileから

スクリーンショット 2015-02-04 23.43.44

スクリーンショット 2015-02-04 23.43.58

スクリーンショット 2015-02-04 23.44.12

 

ファイル名はMySwiftDataにしました。

Createボタンを押してファイルができたらクリックして入力していきます。

そしてこのコードを全てコピーしましょう。

内容は別の記事にて解説するかSQLで検索するといっぱい出てきますのでそちらにて理解してもらいましょう。

とりあえずSwiftDataの使い方という記事ですので

 

//
//  MySwiftData.swift
//  iNotice006.1_SwiftDataBase
//
//  Created by tarou yamasaki on 2015/02/04.
//  Copyright (c) 2015年 tarou yamasaki. All rights reserved.
//

import Foundation

class MySwiftData {
    
    // テーブル作成
    init() {
        let (tb, err) = SD.existingTables()
        /**
            sample_table_001を変更して使う
            sample_table_001の部分をプロジェクト名_sample_table_001
           :%s/置換前文字列/置換後文字列/gc
        */
        // sample_table_001が無ければ
        if !contains(tb, "sample_table_001") {
            
            // sample_table_001を作成,その際"id"は自動生成 dataはStringVal = string型
            if let err = SD.createTable("sample_table_001", withColumnNamesAndTypes: ["data":.StringVal, "data2":.StringVal]) {
                
            } else {
                // created successfully
            }
        }
        // databaseのパスを表示
         println(SD.databasePath())
    }
    
    /**
        INSERT文(追加)
        var add = 自作databaseクラス.add("3urprise") これでdatabaseに"3urprise"と追加される
    */
    func add(str:String,str2:String) -> String {
        
        var result:String? = nil
        if let err = SD.executeChange("INSERT INTO sample_table_001 (data,data2) VALUES (?,?)", withArgs: [str,str2]) {
            // there was an error during the insert, handle it here
        } else {
            // no error, the row was inserted successfully
            // lastInsertedRowID = 直近の INSERT 文でデータベースに追加された行の ID を返す
            let (id, err) = SD.lastInsertedRowID()
            if err != nil {
                // err
            }else{
                // ok
                result = String(id)
            }
        }
        return result!
    }
    
    /**
        DELETE文
        var del = 自作databaseクラス.delete(Int) これでテーブルのID削除
    */
    func delete(id:Int) -> Bool {
        if let err = SD.executeChange("DELETE FROM sample_table_001 WHERE ID = ?", withArgs: [id]) {
            // there was an error during the insert, handle it here
            return false
        } else {
            // no error, the row was inserted successfully
            return true
        }
    }
    
    /**
        SELECT文
        var selects = 自作databaseクラス.getAll() これでNSMutableArray型の内容が取得出来る
    */
    func getAll() -> NSMutableArray {
        var result = NSMutableArray()
        // 新しい番号から取得する場合は "SELECT * FROM sample_table_001 ORDER BY ID DESC" を使う
        let (resultSet, err) = SD.executeQuery("SELECT * FROM sample_table_001")
        if err != nil {
            // nil
        } else {
            for row in resultSet {
                if let id = row["ID"]?.asInt() {
                    let dataStr = row["data"]?.asString()!
                    let dataStr2 = row["data2"]?.asString()!
                    
                    let dic = ["ID":id, "data":dataStr!, "data2":dataStr2!]
                    result.addObject(dic)
                }
            }
        }
        return result
    }
}

 

ここまでSwiftDataは完成です。

ViewControllerのコードを見てもらいます

 

//
//  ViewController.swift
//  iNotice006.1_SwiftDataBase
//
//  Created by tarou yamasaki on 2015/02/04.
//  Copyright (c) 2015年 tarou yamasaki. All rights reserved.
//

import UIKit

class ViewController: UIViewController {
    
    /**
        SwiftDataクラス(DB)を使う時の変数の宣言
    */
    var _mySwiftData = MySwiftData()
    var _getDB_MutableArray = NSMutableArray()
    
    /**
        インスタンス化された時(初回の一度だけ)
        viewDidLoad
    */
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // データをMutableArray型で取得 or データの更新で使える
        _getDB_MutableArray = _mySwiftData.getAll()
    }
    
    /**
        データの追加
        一回押すとデータの追加が実行される
        追加内容は指定した文字列と現在時間(どちらもString型)
        SwfitDataの内容を変更すればどんな型も追加できる
    */
    @IBAction func _dbAddButton(sender: AnyObject) {
        // 現在時刻の取得
        let nowData = NSDate()
        // フォーマットの変換
        let formatter = NSDateFormatter()
        // フォーマットの指定
        formatter.dateFormat = "yyyy/MM/dd HH:mm"
        // String型に
        let dataStr = formatter.stringFromDate(nowData)
        
        // データの追加 【新規IDに "ボタンを押したよ!" の文字と 現在時刻】
        _mySwiftData.add("button push", str2:dataStr)
        // データの更新
        _getDB_MutableArray = _mySwiftData.getAll()
        // データの内容をデバックエリアに表示
        println("現在のデータベースの状態(AddButton): \(_getDB_MutableArray)")
    }
    /**
        DBの行削除
        一回押すとDBの行削除が実行される
    */
    @IBAction func _dbDeleteButton(sender: AnyObject) {
        
        // データの更新
        _getDB_MutableArray = _mySwiftData.getAll()
        
        // データベースの中身が空っぽの場合ifの分岐で何もしない動作にしないとエラーになる
        if _getDB_MutableArray.lastObject == nil {
            // 動作無し
        } else {
            /*
            deleteを扱う場合前提としてInt型にしなければならない
            _getDB_MutableArray.lastObject!["ID"] as Intの内訳は
            _getDB_MutableArray.lastObject! = NSMutableArrayの最後のObject
            ["ID"] = _getDB_MutableArrayはSwiftDataが入っているので最後のObjectの中のIDを
            as Int = Int型に
            */
            _mySwiftData.delete(_getDB_MutableArray.lastObject!["ID"] as Int)
        }
        
        // データの更新
        _getDB_MutableArray = _mySwiftData.getAll()
        // データの内容をデバックエリアに表示
        println("現在のデータベースの状態(DeleteButton): \(_getDB_MutableArray)")
    }
    /**
        DBの更新
    */
    @IBAction func _dbUpdataButton(sender: AnyObject) {
        // データをMutableArray型で取得 or データの更新で使える
        _getDB_MutableArray = _mySwiftData.getAll()
        // データの内容をデバックエリアに表示
        println("現在のデータベースの状態(UpdataButton): \(_getDB_MutableArray)")
    }

    /**
        memoryWarning
    */
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

 

Storyboardにボタンを3つ作成します。

追加用(ボタンを押すと現在時刻が記録される)

 

削除用(押すとリストの古い番号から削除する)

 

更新用(現在のデータベースの状態を確認する)

 

 

スクリーンショット 2015-02-05 0.21.09

 

これらをActionで紐付けます。

以上で終わりになります。

詳しく解説したいのですが今回はSQLを理解している、もしくはSQLは知らんけどDB使えたらそれでいいって方が対象ですので簡単にしてしまいました。

ゴチョゴチョ使っていると何となくわかってくるんですが細かく理解しようとするとなかなか難しいですね。

それにSwiftはOption型といってnilの場合別の型に変化させる特性がありますので ! や ? など初心者は意味不明なエラーに悩まされる事があるとおもいます。

しかしxcodeのDBに限ってはこのコードの全コピーで使いまわせると思いますので色々いじってみてください。

ちなみにもっと詳しく知りたい方は https://github.com/ryanfowler/SwiftData をスクロールしていけば英語ですが説明があります。

翻訳などしても十分わかる簡潔なものになっていますのでそちらもご覧ください。

私の説明が不十分、間違っているなどの指摘があればコメント下さい。

即刻修正します。

Sponsored Link
ツイートツイート

SwiftDataを徹底的に解説!これでDB怖くない!(永久保存版)

3 thoughts on “SwiftDataを徹底的に解説!これでDB怖くない!(永久保存版)

  • 2016年6月10日 at 12:22
    Permalink

    こんにちは。
    私はDB初心者のものです。
    SwiftDataに挑戦しようと思い、こちらのサイトにたどり着きました。
    先ずは簡単な内容から理解していこうと思い、上記の通りやってみましたが、疑問が2点出てきたので質問させて下さい。
    ・SwiftDate.swiftのファイルで、変数の宣言をしていないため「SD」の部分にエラーが立ちます。
     恐らくSwiftDataの省略形だと思いますがどうすれば良いですか?
    ・libsqlite3.tbdをドラッグしたのですが、ファイルの形が四角に右隅が折れ曲がったファイルの形のアイコンになりました。上記のような盾の形になりませんでしたが、これで良いのでしょうか?

    以上よろしくお願いします。

    Reply
    • 2016年6月12日 at 10:00
      Permalink

      こんにちは。ヤマサキです。

      ・「SD」の部分にエラーが立つ。この部分に関しては私も最初のインストール時にSDの部分にエラーが立ちました。
      このエラーの原因は結局わからず、最初から手順を見直したら何事もなかったように動きました。
      おそらくBriding-Headeの関係ではないでしょうか?

      ・libsqlite3.tbdをドラッグとありますがどの手順のことでしょうか?

      Reply
    • 2016年8月5日 at 13:51
      Permalink

      tdbファイルをインポートする同じところで引っかかったため。

      1. FrameworkをTargets -> Build Phases -> Link Binary With Libraries を開く。
      2. “+”ボタンをクリック。
      3. Framework選択ダイアログ画面で、”Add Other…”ボタンをクリック。
      3. “Shift” + “Command” + “G”を同時押しして、ファイルパス入力画面を表示。
      4. “/usr/lib”を入力して”Go”ボタンをクリック。
      5. インポートしたいdylibファイルを選択。

      これで解決。

      Reply

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です