お題
CoreDataを使わないなら、Use CoreData
にチェックを入れないでプロジェクトを新規に作成します。
でも、後から「実は使いたい」となる可能性は十分に考えられます。
そのときにどうしたらいいか?というのが今回のお題
ちなみに、私はこれまでCoreDataは使ったことがありません。CoreDataとの初めてがこのような形になるとは思いませんでした。
というわけで、
- これまでCoreDataを使ったことがない
- もともと使うつもりではなかったプロジェクトに途中からぶち込む
というあまり好ましくない状況からのスタートです。
そんな機能はAppleが用意してくれてるでしょ?
探してみましたが、そんな機能はXCodeにはありませんでした。残念。
新しく何かしらのファイルを追加することで対応できるといえばできるんですが、おニュープロジェクトのときと同じ水準に一発でお膳立てをしてもらいたいんです。
ワガママなんです私。
もしかしたら探し漏れがあるかもしれません。「あるよ。君の目は節穴かね?」という情報提供を頂けるとありがたいです。
CoreData使う使わないで何が違うのか?
ならば、おニュープロジェクトでCoreDataありとCoreDataなしでどう違うのかを比較してみましょう。
差分をマネてみれば動くんじゃね?という魂胆です。
すっぴんプロジェクトを作ってみます。
ファイルの比較
左がCoreDataあり、右がCoreDataなしです。
testWithCoreData.xcdatamodeld
が入ってますね。
これはCoreDataで使うEntityの定義などをするもののようです。
中身の比較
先頭から順に見比べてみましょう。
差異があったものは次の2ファイル。
- SceneDelegate.swift
- AppDelegate.swift
いずれもCoreDataありのほうが多いです。
で、具体的に何が違うのか?
自動生成されたコードの違いを見てみます。
SceneDelegate.swift
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
~略~
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let contentView = ContentView().environment(\.managedObjectContext, context)
~略~
}
うむ、なるほど。わからん。
func sceneDidEnterBackground(_ scene: UIScene) {
~略~
(UIApplication.shared.delegate as? AppDelegate)?.saveContext()
~略~
}
アプリがバックグラウンドに回るときに、データの変更分を保存してしまう処理のようです。
AppDelegate.swift
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "testWithCoreData")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
1つ目のは、取り扱いたいEntityが詰まっているコンテナ(でいいのかな?)を取得してるようですね。
2つ目のは、1つ目ので取得したコンテナにデータを保存する処理のようです。
何かデータを保存するときはこのメソッドを呼ぶことになるのか?
どこかで見たな……
( ゚д゚)ハッ! SceneDelegate.swiftのsceneDidEnterBackground
で呼び出されている。
ちなみに、冒頭でimport CoreData
も入りますのでご注意を。
これから
現状はなんとなくぼんやりした状態です。
データを保存する処理だけで削除したり更新したりする処理はないんですね?とか。
正直さっぱりわかりません。このままではよろしくないので、順次理解を深めていきます。
まずはデータの読み書きができることを目標に。