概要
今回は、iOSアプリ開発でローカルストレージを使用するため、"GRDB"を使ったサンプルを作ってみた
GRDBってなに?
iOS アプリ開発において SQLite を扱いやすくするためのライブラリ(ラッパークラス)
要は JDBC とか 、.NET の System.Data.SQLite みたいなもので
クライアント言語によりそった簡易なデータベース接続と操作 API を提供してくれる。
CocoaPodsってなに?
iOS/Mac向けのアプリを作成する際のライブラリ管理をしてくれるもの。
.Netでいう「Nuget」、pythonでいう「pip」とかそんな感じ
準備
- pod init[←で、Podfileを生成する]
- vim Podfile
- pod 'GRDB.swift' → pod install
- {Project Name}.xcworkspace をクリック
以下、Podfileの記載例
target 'Mock'{application name} do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for Mock
pod 'GRDB.swift'
end
全体ソース
XXXX.sqliteファイルは、プロジェクトの直下でよい
import Foundation
import GRDB
class DatabaseManager {
let databaseFile: String!
init(){
databaseFile = NSHomeDirectory() + "/Documents/" + "taisaku.sqlite"
}
/*
データベースファイルをコピーする処理
マスターデータファイルをアプリ実行時のディレクトリにコピーする
*/
func createDatabase(){
let fileManager = FileManager.default
guard let documentsUrl = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
let finalDatabaseURL = documentsUrl.appendingPathComponent("taisaku.sqlite")
do {
if !fileManager.fileExists(atPath: finalDatabaseURL.path) {
print("DB does not exist in documents folder")
if let dbFilePath = Bundle.main.path(forResource: "taisaku", ofType: "sqlite") {
try fileManager.copyItem(atPath: dbFilePath, toPath: finalDatabaseURL.path)
} else {
print("Uh oh - foo.db is not in the app bundle")
}
} else {
print("Database file found at path: \(finalDatabaseURL.path)")
}
} catch {
print("Unable to copy foo.db: \(error)")
}
}
/*
init データ取り込み前にローカルDBの中身を初期化(DEL)する処理
*/
func initDatabase(){
let queue = try! DatabaseQueue(path: self.databaseFile)
try! queue.write({ (db) in
try! db.execute(sql: "DELETE FROM taisaku;")
})
}
func entryTaisakuData(taisakus : [Taisaku]){
for taisaku in taisakus {
}
}
/// 本メソッドをCALLすると、「"taisaku"テーブルに、"name"カラムに"hoge"を設定し、Insertする」
func testInsert(){
let queue = try! DatabaseQueue(path: self.databaseFile)
try! queue.write { (db) in
do {
var user = try User(name: "hoge")
try! user.insert(db)
print(user.id)
// Optional(1)
} catch {
}
}
}
// DB操作用クラス
class User: Record {
var id: Int64?
var name: String
var description: String
var issueId: String
let issueName: String
// テーブル名
override static var databaseTableName: String {
return "taisaku"
}
enum Columns {
static let id = Column("id")
static let name = Column("name")
static let age = Column("description")
static let score = Column("issueId")
static let createdAt = Column("issueName")
}
init(name: String) {
self.name = name
self.description = ""
self.issueId = ""
self.issueName = ""
super.init()
}
required init(row: Row) {
self.id = row["id"]
self.name = row["name"]
self.description = row["description"]
self.issueId = row["issueId"]
self.issueName = row["issueName"]
super.init(row: row)
}
override func encode(to container: inout PersistenceContainer) {
container["id"] = self.id
container["name"] = self.name
container["description"] = self.description
container["issueId"] = self.issueId
container["issueName"] = self.issueName
}
override func didInsert(with rowID: Int64, for column: String?) {
// Insert時にidに反映
self.id = rowID
}
}
}
使用例
@IBAction func btnTapped(_ sender: Any) {
// newする
var databaseManager = DatabaseManager()
databaseManager.testInsert()
}
注意点
一度作っている[build -> run]とうまくコピーされず空のsqliteファイルが
エミュレータ上に【残り続ける】のでそういう時は一度エミュレータ上のアプリを
削除することでマスタデータありのsqliteファイルがコピーされます
参考
GRDB.swiftというSQLiteライブラリがイイ感じだった
★Swift 4 GRDB.swift(SQLite)を使ってみた
GRDB.swiftの生SQL発行とマイグレーション