Core Dataを使おうと思って調べると、解説のほとんどが .xcdatamodeld
ファイルでセットアップを始める。
.xcdatamodeld
はグラフィカルに構造を表示し、便利な反面、裏側の仕組みを理解しづらい、GitHubでレビューしづらいなどのコストは無視できない。
さらに近年問題になり得るのは、Swift PlaygroundsでiOS/iPadOS/macOS向けアプリを作成する環境整備が進んでいることだ。
Macだけでなく、iPadでも手軽にアプリ開発を進めることができるようになるが、Swift Playgroundsでは .xcdatamodel
を取り扱うことができない。*1
ということで、ここでは .xcdatamodeld
ファイルで始めたプロジェクトを、プログラマブルに置き換える。
ちなみに、.xcdatamodel
を複数束ねたものが、.xcdatamodeld
。
.xcdatamodeld
で定義した状態の確認
まずは置き換え元になる .xcdatamodeld
入りプロジェクトを作る。
プロジェクト作成 with xcdatamodeld
Create a new Xcode project
からスタート
.xcdatamodeld
がProjectツリーにある
生成されるコード
初期状態だと、Item
は "Class Definition" として、コード生成されている。
ContentView
の中で参照されている item.timestamp
をクリックすると、生成されたコードを見ることができる。
import Foundation import CoreData extension Item { @nonobjc public class func fetchRequest() -> NSFetchRequest<Item> { return NSFetchRequest<Item>(entityName: "Item") } @NSManaged public var timestamp: Date? } extension Item : Identifiable { }
確認用のデータを入れる
この後の変更で振る舞いが変わっていないかを確認するために、アプリを実行して、データを入れておくとよいだろう。
Item
をプログラムとして再定義
型定義
コード生成を参考に、自分で定義する。
public class Item: NSManagedObject { @NSManaged public var timestamp: Date? } extension Item : Identifiable {}
Entity情報
Item
型のEntityとしての情報を定義する。
extension Item { static var entityDescription: NSEntityDescription { let entity = NSEntityDescription() entity.name = String(describing: Self.self) entity.managedObjectClassName = NSStringFromClass(Self.self) entity.properties = [ { $0.name = "timestamp" $0.attributeType = .dateAttributeType $0.isOptional = true return $0 }(NSAttributeDescription()), ] return entity } }
NSPersistentContainer
初期化時にNSManagedObjectModel
を指定
NSManagedObjectModel
のEntityにItem
のNSEntityDescription
を渡すことで、.xcdatamodeld
ファイルがある時と同じ状態のContainerとして初期化する。
let managedObjectModel = NSManagedObjectModel() managedObjectModel.entities = [ Item.entityDescription, ] container = NSPersistentContainer(name: "CoreDataExample", managedObjectModel: managedObjectModel)
余談だが、nameのみのイニシャライザはnameに渡した文字列で .xcdatamodeld
ファイルを探しているだけなので、ファイル名を変えるか、nemeの指定文字列を変えると初期化に失敗する。
[error] error: Failed to load model named CoreDataExamples
.xcdatamodeld
ファイルを削除
ファイルがあると (正確にはItem
定義があると) 生成されるコードと、定義したItem
が衝突するので、ファイルを削除しておく。
置き換えの確認
アプリの実行して、変更前のデータを表示できていることを確認。
データ操作もできている。
To Be Continued
IndexやRelationship、Migrationといった複雑な設定はまた今度
*1:2022/07/14現在