はじめに
以前、「コードのみでCoreDataを実装する」を書きました。
しかし、それ以来CoreDataを使ったことがありませんでした。
先日使うことがあったので使い方を記録しておきます。
サンプルアプリ
実装
xcdatamodeldを作成
① メインターゲットフォルダを右クリックします
② 「New File...」を選択します
③ Data
を検索します
④ 「Data Model」を選択します
⑤ 「Next」を選択します
⑥ 任意のファイル名を設定します
⑦ 「Create」を選択します
Entityの設定
① 先ほど作成したファイルを選択します
② 「Add Entity」を選択します
④ 「+」を選択します
⑤ Attribute名を決めます
⑥ Typeを選択します
⑦ 追加したEntityを選択します
⑧ 三本線を選択します
⑨ 「Codegen」を選択します。
⑩ 「Codegen」を「Manual/None」に変更します
拡張を追加
① 「Editor」を選択します
② 「Create NSManagedObject Subclass...」を選択します
Persistenceを作成する
① メインターゲットフォルダを右クリックします
② 「New File...」を選択します
③ 「Swift File」を選択します
④ 「Next」を選択します
⑤ Persistence
というファイル名にします(自動生成時のファイル名がこれだった)
⑥ 「Create」を選択します
作成したファイルに以下のコードをコピペします
import CoreData
struct PersistenceController {
static let shared = PersistenceController()
static var preview: PersistenceController = {
let result = PersistenceController(inMemory: true)
let viewContext = result.container.viewContext
// MARK: 下2行はEntityの設定によって違う
let newSampleModel = SampleModel(context: viewContext)
newSampleModel.title = ""
do {
try viewContext.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
return result
}()
let container: NSPersistentContainer
init(inMemory: Bool = false) {
// MARK: 下1行はEntityの設定によって違う
container = NSPersistentContainer(name: "SampleModel")
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
container.loadPersistentStores(completionHandler: { _, error in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
}
}
App.swiftの編集
import SwiftUI
@main
struct coredata_sampleApp: App {
private let persistence = PersistenceController.shared
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistence.container.viewContext)
}
}
}
サンプルアプリ
アプリを起動した時間をCoreDataに保存するアプリです。
import SwiftUI
struct ContentView: View {
// MARK: `SampleModel`は各自の設定によって違います
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \SampleModel.title, ascending: false)],
animation: .default
)
private var samples: FetchedResults<SampleModel>
// MARK: 追加/削除に必要
@Environment(\.managedObjectContext) private var context
var body: some View {
List(samples) { sample in
Text(sample.title ?? "")
}
.onAppear {
// MARK: ここが追加の処理
let newSampleModel = SampleModel(context: context)
newSampleModel.title = "\(Date.now.timeIntervalSince1970)"
try? context.save()
}
}
}
おわり
無事、CoreDataを使用することができました!