iOS Swift で SQLiteをタイプセーフなラッパーSQLite.swift経由で利用する

SQLiteを利用して、INSERTボタンで登録、FETCHボタンで画面表示、DELETEボタンで削除のサンプルを作成する。

Sqlite ios

標準ライブラリ(?) 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を起動

add_package01

https://github.com/stephencelis/SQLite.swift.git

を右上に入力すると、SQLite.swiftが表示されるので、Add Package

add_package02

ファイルエクスプローラーにパッケージ情報が表示される。

add_package03

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みたいな挙動。

割と使いやすそう。他にも同様のライブラリもあるみたい。

Follow me!

コメントを残す

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