どうも3urpriseのヤマサキです。
タイトルにある通り私の苦手なDBを克服するべく流行りのSwiftDataを徹底解説します。
まさに永久保存版なので私含めた初心者は穴があくほど眺めるのをお勧めします。
SwiftDataとは
Objective-C時代にDBとを使うと言えばCoreDataかSQLiteのFMDBが主流だったと思います。
(あくまで主観です、ちなみに私たちの作成アプリ iDrawer はSQLiteのFMDBを使っています)
SwiftData : 商用可能 , 無料 , SQLiteラッパー , 記述が少しで済む
う〜ん、最高ですね。使わない訳が無い。
開発者様、ありがとうございます!
それでは簡単な説明も終わりましたので本題の解説に入ります。
まずはファイルをゲッツします。
https://github.com/ryanfowler/SwiftData
右下のZIPをクリックしてダウンロードしたらSwiftDataのファイルは準備OKです。
それでは新規プロジェクトを立ち上げます。
Xcode > File > SingleView > プロジェクト名 > Swift言語使用 > Create でプロジェクト作成
今回はSwiftDataを理解しよう!のコーナーなのでStoryboardなどは極力使いません。ボタンぐらいかな。
状態の確認は全てデバックエリア(Logが出てくるエリア)で見る事にします。
赤字が名称で黒字がショートカットです。
それではSwiftDataを使える様にしましょう。
まずはFrameworks and Librariesにlibsqlite3.dylib
写真では追加した後ですが番号4をクリックして
libsqlite3.dylibをクリックして下さい。
プロジェクトの中に追加されればOKです。
次に先ほどダウンロードしたSwiftData.swiftをlibsqlite3.dylibの下にでもドラッグして追加しましょう。
できたらヘッダーファイルを作成します。
写真の様に右クリックから
スペル間違いだけ気を付けて下さい。(私はスペル間違いでもの凄い時間と精神力を削がれた)
Briding-Header
Briding-Headerと入力しCreateボタンを押すとBriding-Header.hが作成されますのでその中に一行追加します。
#import “sqlite3.h”
次で準備は完了です、もうちょっと頑張って!
写真通りの手順でクリックしていき、番号5はobjective-c bを入力
番号6は空なのでダブルクッリックし入力します。
この時もスペル間違いに気を付けて下さい。
ここまでで準備は完了です。
Sponsored Link
ここからはSwiftDataのデータ内容をコードで追加していきます。
ファイルの作成はさっきと同じく右クリックのFileから
ファイル名は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つ作成します。
追加用(ボタンを押すと現在時刻が記録される)
削除用(押すとリストの古い番号から削除する)
更新用(現在のデータベースの状態を確認する)
これらをActionで紐付けます。
以上で終わりになります。
詳しく解説したいのですが今回はSQLを理解している、もしくはSQLは知らんけどDB使えたらそれでいいって方が対象ですので簡単にしてしまいました。
ゴチョゴチョ使っていると何となくわかってくるんですが細かく理解しようとするとなかなか難しいですね。
それにSwiftはOption型といってnilの場合別の型に変化させる特性がありますので ! や ? など初心者は意味不明なエラーに悩まされる事があるとおもいます。
しかしxcodeのDBに限ってはこのコードの全コピーで使いまわせると思いますので色々いじってみてください。
ちなみにもっと詳しく知りたい方は https://github.com/ryanfowler/SwiftData をスクロールしていけば英語ですが説明があります。
翻訳などしても十分わかる簡潔なものになっていますのでそちらもご覧ください。
私の説明が不十分、間違っているなどの指摘があればコメント下さい。
即刻修正します。
Sponsored Link
ツイート
こんにちは。
私はDB初心者のものです。
SwiftDataに挑戦しようと思い、こちらのサイトにたどり着きました。
先ずは簡単な内容から理解していこうと思い、上記の通りやってみましたが、疑問が2点出てきたので質問させて下さい。
・SwiftDate.swiftのファイルで、変数の宣言をしていないため「SD」の部分にエラーが立ちます。
恐らくSwiftDataの省略形だと思いますがどうすれば良いですか?
・libsqlite3.tbdをドラッグしたのですが、ファイルの形が四角に右隅が折れ曲がったファイルの形のアイコンになりました。上記のような盾の形になりませんでしたが、これで良いのでしょうか?
以上よろしくお願いします。
こんにちは。ヤマサキです。
・「SD」の部分にエラーが立つ。この部分に関しては私も最初のインストール時にSDの部分にエラーが立ちました。
このエラーの原因は結局わからず、最初から手順を見直したら何事もなかったように動きました。
おそらくBriding-Headeの関係ではないでしょうか?
・libsqlite3.tbdをドラッグとありますがどの手順のことでしょうか?
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ファイルを選択。
これで解決。