はじめに
経緯
圧倒的要員不足で、私がiOSアプリの制作を学ばなければならなかったのだが、なにから学べばいいのかわからなかった。いろいろ考えた結果、メモアプリを制作することになった。
GRDBとは
iOSとかmacOS向けのデータベースを制作できるようにするものらしい。早くて安全とかなんとか...一番これがしっくりきたので選んだ。Android
のようにもっと簡単にできないものか...
1.設定
まず公式のGitHubからzipをダウンロード。)MacOS
なら自動で解凍してくれるらしい。プロジェクトファイル(ProjectName.xcodeproj)を選択した状態で、ツールバーの「File」>「Add File to "ProjectName"」を選択し、解凍したファイル内のGRDB.xcodeproj
を選択。
ProjectName.xcodeproj 直下にGRDB.xcodeproj
がインポートされると思います。ProjectName.xcodeprojを選択した状態に戻し、Build Phases
タブを選択しましょう。Target Dependencies
という項目を開き、+を押してGRDBiOS
を追加して下さい。
次はGeneral
タブへ移り、スクロールしてEmbedded Binaries
にGRDB.framwork(iOS)
(なお、カッコ内は薄文字)を追加。これでOKです。
2.データベースを作る
新しいSwift Fileをプロジェクト内に作ってこう書きましょう。
import Foundation
import GRDB
class UserTable: Record {
// テーブル名
override static var databaseTableName: String {
return "memoList"
}
var id: Int64?
var title: String
var body: String
static func create(_ db: Database) throws {
try db.create(table: databaseTableName, body: { (t: TableDefinition) in
t.column("id", .integer).primaryKey(onConflict: .replace, autoincrement: true)
t.column("title", .text).notNull().unique() // 重複を許さないのなら.unique()をつける
t.column("body", .text).notNull() // Nullを許さないのなら.notNull()をつける
})
}
enum Columns {
static let id = Column("id")
static let title = Column("title")
static let body = Column("body")
}
init(title: String, body: String) {
self.title = title
self.body = body
super.init()
}
required init(row: Row) {
self.id = row["id"]
self.title = row["title"]
self.body = row["body"]
super.init(row: row)
}
override func encode(to container: inout PersistenceContainer) {
container["id"] = self.id
container["title"] = self.title
container["body"] = self.body
}
override func didInsert(with rowID: Int64, for column: String?) {
self.id = rowID
}
}
これでデータベースがどんな形なのかを指定できた。もちろん追記しても構わないです。しかし、これではまだ作られてないのでさらに別のファイルを追加しましょう。
import Foundation
import GRDB
class DatabaseHelper {
private struct Const {
static let dbFileName = NSTemporaryDirectory() + "database.db"
}
init() {
self.creatDatabase()
}
func inDatabase(_ block: (Database) throws -> Void) -> Bool {
do {
let dbQueue = try DatabaseQueue(path: Const.dbFileName)
try dbQueue.inDatabase(block)
}catch _ {
return false
}
return true
}
private func creatDatabase() {
if FileManager.default.fileExists(atPath: Const.dbFileName) {
return
}
let result = inDatabase {(db) in
try UserTable.create(db)
}
if !result {
do {try FileManager.default.removeItem(atPath: Const.dbFileName)} catch {}
}
}
}
特に変えるところはないのでコピペで大丈夫だと思います。アプリが初めて起動した時に自動で呼ばれ、データベースファイルが生成されます。
3.使い方
3.1 行の追加
let helper = DatabaseHelper()
let result = helper.inDatabase{(db) in
let user = UserTable(title: /*titleの文字列*/ ?? "", body: /*bodyの文字列*/ ?? "")
try user.insert(db)
}
if (!result) {
// 失敗
} else {
// 成功
}
3.2 行の選択(削除や上書きの時に使う)
title
の文字列をもとに探す場合。
let helper = DatabaseHelper()
let result = helper.inDatabase{(db) in
let user = try UserTable.filter(sql: "title = ?", arguments: [/*titleの文字列*/]).fetchOne(db)
}
これはSQL文を使った特定方法。.filter()
で条件に該当する行を全てマークして.fetchOne(db)
で一つだけ取り出す。
title
はデータベースを設定する際、.unique()
を設定してるので重複はない。だから一つだけでいいのです。また、sql'
で条件をColumn名 = ?
と書き、その値は後ろのarguments:
で配列で渡す。ちなみに複数条件はこう。(多分orもできる)
let user = try UserTable.filter(sql: "title = ? AND body = ?", arguments: [/*titleの文字列*/, /*bodyの文字列*/]).fetchOne(db)
3.3 行の変更
let helper = DatabaseHelper()
let result = helper.inDatabase{(db) in
let user = try UserTable.filter(sql: "title = ?", arguments: [/*変更前のtitleの文字列*/]).fetchOne(db) // さっきの
user?.title = /*変更後のtitleの文字列*/!
user?.body = /*変更後のbodyの文字列*/
try user?.update(db)
}
3.4 行の削除
let helper = DatabaseHelper()
let databaseResult = helper.inDatabase{(db) in
let user = try UserTable.filter(sql: "title = ?", arguments: [/*変更前のtitleの文字列*/]).fetchOne(db)
try user?.delete(db)
}
4.まとめ
今回はiOSやMacでデータベースを利用してみました。詳しいやり方と参考にしたサイトは以下です。ぜひ見てみて下さい。
GRDB.swiftというSQLiteライブラリがイイ感じだった - Qiita
[macOS][iOS] Sqliteを使ってみる : プログラミング・メモ
Twitter: https://twitter.com/Cyber_Hacnosuke (フォローしてくださいお願いします。)
いいねもお願いします。