CoreDataを扱ったライブラリとしてCoreStoreというライブラリがあります。
スター数も3,000を超えていたりと、比較的注目されているライブラリのようですが日本語で扱った記事がなかったので、まずは簡単な使い方について記事を書こうと思います。
CoreStoreとは
CoreDataを扱いやすくするライブラリです。
SwiftUIやCombineのサポートはもちろん、thread safeだったり.xcdatamodeld
ファイルなしで、スキーマが定義できたりします。
自分は諸事情で.xcdatamodeld
ファイルを使わずにCoreDataを扱いたかったので今回CoreStoreを触りました。
インストール方法
Swift PMで簡単にインストールできます。
CocoaPodsやCarthageも用意されているみたいですが試してません。
使い方
テーブルの定義
CoreStoreでは.xcdatamodeld
ファイルを用いて使用することも出来ますが、.swift
ファイルのみでも使えます。
class Person: CoreStoreObject {
@Field.Stored("name")
var name: String = ""
}
こんな感じで保存したいプロパティをpropertyWrapperを使って定義します。
また、上で使った以外にも、@Field.Relationship
リレーショナルな定義もできます。
コード上でテーブルの定義ができるのはいいですね。
スキーマ定義とDataStackの初期化
さてさて、テーブルを定義したので次はスキーマの定義をします。
アプリの初期化時に以下のコードを実行します。
let schema = CoreStoreSchema(
modelVersion: "V1",
entities: [
Entity<Person>("Person")
]
)
CoreStoreDefaults.dataStack = DataStack(schema)
try! CoreStoreDefaults.dataStack.addStorageAndWait(SQLiteStore())
上のコードについて簡単に説明します。
DataStack
はデータの操作をするクラスでして、それの初期化をしています。
初期化の際にはスキーマを渡す必要があり、それを渡しています。
そして、アプリの中では基本的にCoreStoreDefaults.dataStack
を用いてアクセスするのでそこにセットしています。
最後にストレージのセットアップをしています。
Read
一番シンプルなデータの読み込みは次の通りです。
let objects = try? CoreStoreDefaults.dataStack.fetchAll(From<Person>())
クエリなんかも書けます。
KeyPathでtype-safeにかけるのがいいですね
try? CoreStoreDefaults.dataStack.fetchAll(
From<Person>()
.where(\.$name == "matsuji")
)
Create / Update
DBに対する書き込みは全てperform
メソッドの中で行います。
CoreStoreDefaults.dataStack.perform(asynchronous: { transition -> Person in
let person = transition.create(Into<Person>())
person = "matsuji"
return person
}) { result in
switch result {
case .success(let person): print("success")
case .failure(let error): print("error")
}
}
特徴的なのは、perform
の中でobjectを生成して、書き込み、その結果をクロージャーで受け取っているところです。
perform
の中で生成されたオブジェクトは書き込みのためだけに生成して使われる必要があり、クロージャーの外から参照してはいけません。
perform
の中で生成したオブジェクトを他で使いたい場合、completion handlerの中のresultの中身を使う必要があります。
また、既存のデータに対して書き込みを行うときはedit()
を用いて、トランザクションのためのオブジェクトに変更する必要があります。
let person: Person
CoreStoreDefaults.dataStack.perform(asynchronous: { transition -> Person in
let person = transition.edit(person)
person = "updated name"
return person
}) { _ in }
Delete
データの削除もperform
内で行います。
let person: Person
CoreStoreDefaults.dataStack.perform(asynchronous: { transition -> Person in
transition.delete(person)
}) { _ in }
おわりに
今回はCoreStoreの簡単な導入を紹介しました。
CoreStoreは使いやすく良いライブラリですので、皆さん一度試してみてください。
今回は省略しましたが、CombineやSwiftUIに対しての機能も用意されているので興味があればそちらもみてみてください。