iOS Swift で SQLiteをタイプセーフなラッパーSQLite.swift経由で利用する
SQLiteを利用して、INSERTボタンで登録、FETCHボタンで画面表示、DELETEボタンで削除のサンプルを作成する。
標準ライブラリ(?) SQLite3をそのまま利用して、DB作成を行なったが、
iOS SwiftでSqliteを使う。シミュレータ上に作成されたSQLiteファイルをMacで確認する | Glob (typea.info)
タイプセーフなSQLite3のラッパーライブラリを使用して、実施する。
GitHub – stephencelis/SQLite.swift: A type-safe, Swift-language layer over SQLite3.
1.Packageの追加
プロジェクトのコンテキストメニューから、Add Packages を選択し、Swift Package Mangerを起動
https://github.com/stephencelis/SQLite.swift.git
を右上に入力すると、SQLite.swiftが表示されるので、Add Package
ファイルエクスプローラーにパッケージ情報が表示される。
CocoaPods など、他の導入方法もサイトに記述あり
2.コード
前回参考にした動画同様、DBHelperをViewControllerから呼び出す形式とする。
Readme.mdのUseageを見ながら試してみたのだが、”<-“ 演算子の意味がわからず少し悩んだ。
Swiftの本とかにも記述ないし、、ググっても出てこないし、、とソースを見ていったら、独自に演算子定義していた。
独自演算子の定義例
infix operator *** { associativity none precedence 130 } func ***(lhs: Int, rhs: Int) -> Int { return lhs * rhs }
軽く混乱するな。。
import SQLite で利用できる。
import Foundation import SQLite class DBHelper { var db: Connection? let grade = Grade() init() { self.db = createDb() self.createTable() } func createDb() -> Connection? { do { let filePath = try! FileManager.default.url( for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) .appendingPathComponent("mydb.sqlite") let db = try Connection(filePath.absoluteString) print("Db has been created with path = \(filePath)") return db } catch { print("Creating DB Error.") return nil } } func createTable() { do { let query = grade.table.create(block: { builder in builder.column(grade.id, primaryKey: true) builder.column(grade.name) builder.column(grade.result) builder.column(grade.list) }) print("CREATE TABLE : \(query)") try self.db?.run(query) } catch { print("Creating Table Error.") } } func insert() { do { let insert = self.grade.table.insert(grade.name <- "name-\(Int.random(in:1 ... 999))", grade.result <- " result-\(Int.random(in:1 ... 99))", grade.list <- "\(Int.random(in:1 ... 99))") let rowid = try self.db?.run(insert) print("Inserted rowid : \(String(describing: rowid))") } catch { print("Insert Error") } } func fetch() -> String { var ret = "" do { if let db = self.db { for entity in try db.prepare(self.grade.table) { let line = rowFormat(entity: entity) print(line) ret.append(line) } } } catch { print("Fetch Error") } return ret } func delete(id: String) { do { if let rowId = Int64(id) { let delentity = self.grade.table.filter(self.grade.id == rowId) try self.db?.run(delentity.delete()) } } catch { print("Delete Error") } } func rowFormat(entity:Row) -> String { let g = self.grade return "id:\(entity[g.id]), name:\(entity[g.name]), result:\(entity[g.result]), list:\(entity[g.list])\n" } } class Grade { // create table if not exists grade(id integer primary key autoincrement, name text, result text, list text); let table = Table("grade") let id = Expression("id") let name = Expression("name") let result = Expression("resut") let list = Expression("list") }
ViewController側で、DBHelperを、ボタンのActionで呼び出す。
import UIKit class ViewController: UIViewController { let db = DBHelper() @IBOutlet weak var entityText: UITextView! @IBOutlet weak var idText: UITextField! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. entityText.text = "" entityText.layer.borderColor = UIColor.black.cgColor } @IBAction func doInsert(_ sender: Any) { self.db.insert() } @IBAction func doFetch(_ sender: Any) { self.entityText.text = self.db.fetch() } @IBAction func doDelete(_ sender: Any) { self.db.delete(id: idText.text!) } }
実行すると、冒頭のアニメーションGIFみたいな挙動。
割と使いやすそう。他にも同様のライブラリもあるみたい。