🙆
Core DataをSwiftUIと連携させる手順
下記のようなデータをCore Dataで作り、そしてSwiftUIと連携させる手順を記録します
struct Strudent {
var id: UUID
var name: String
}
XcodeでSwiftUIプロジェクトを作り、プロジェクト名と「Bookworm」にします
Data Model
まずは cmd
+ N
でファイルを新しく作ります
ファイルタイプは「Data Model」を選択、名前は「Bookworm」にします
次は「Add Entity」をクリック
左の「Entity」をダブルクリックして、「Student」へ改名します
Attributeの「+」をクリック、Attribute名は「id」、Typeは「UUID」
もう一回にAttributeを作ります。Attribute名を「id」、Typeを「String」
Swift Data Controller
新しいファイル「DataController.swift」を作ります
CoreDataをインポートします
DataController.swift
+import CoreData
import Foundation
コントローラーのクラスを定義する
DataController.swift
import CoreData
import Foundation
+class DataController: ObservableObject {
+
+}
ObservableObject
を利用して、そのデータがアプリが起動と同時にアクティブ状態に入り、そしてアプリが落ちてない限りにそのデータがずっとアクティブの状態のままです
containerを定義
DataController.swift
import CoreData
import Foundation
class DataController: ObservableObject {
+ let container = NSPersistentContainer(name: "Bookworm")
}
name
は先ほど作ったDate Modalと同じようにします
最後にロードエラーを備えて以下を書きます
DataController.swift
import CoreData
import Foundation
class DataController: ObservableObject {
let container = NSPersistentContainer(name: "Bookworm")
+ init() {
+ container.loadPersistentStores { description, error in
+ if let error = error {
+ print("Core Data failed to load: \(error.localizedDescription)")
+ }
+ }
}
}
BookwormApp.swift
を開けて、以下のコードを書きます
BookwormApp.swift
import SwiftUI
@main
struct BookwormApp: App {
+ @StateObject private var dataController = DataController()
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
environment modifierを加える
BookwormApp.swift
struct BookwormApp: App {
@StateObject private var dataController = DataController()
var body: some Scene {
WindowGroup {
ContentView()
+ .environment(\.managedObjectContext, dataController.container.viewContext)
}
}
}
ContentView.swift
@FetchRequest
を使ってCore Dataにデータをリクエストします、そしてUIにシンクロさせる
ContentView.swift
struct ContentView: View {
+ @FetchRequest(sortDescriptors: []) var students: FetchedResults<Student>
var body: some View {
Text("2")
}
}
データを表示させます
ContentView.swift
struct ContentView: View {
@FetchRequest(sortDescriptors: []) var students: FetchedResults<Student>
var body: some View {
VStack {
+ List(students) { student in
+ Text(student.name ?? "Unknown")
+ }
}
}
}
データを追加するために
まずは@Environment()
を使って、Core Dataの上層クラスにデータへのアクセスをリクエストします
ContentView.swift
struct ContentView: View {
+ @Environment(\.managedObjectContext) var moc
+ @FetchRequest(sortDescriptors: []) var students: FetchedResults<Student>
var body: some View {
VStack {
List(students) { student in
Text(student.name ?? "Unknown")
}
}
}
}
追加する情報を作って追加する
ContentView.swift
struct ContentView: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(sortDescriptors: []) var students: FetchedResults<Student>
var body: some View {
VStack {
List(students) { student in
Text(student.name ?? "Unknown")
}
+ Button("Add") {
+ let firstNames = ["Ginny", "Harry", "Hermione", "Luna", "Ron"]
+ let lastNames = ["Granger", "Lovegood", "Potter", "Weasley"]
+
+ let chosenFirstName = firstNames.randomElement()!
+ let chosenLastName = lastNames.randomElement()!
+
+ let student = Student(context: moc)
+ student.id = UUID()
+ student.name = "\(chosenFirstName) \(chosenLastName)"
+
+ try? moc.save()
+ }
}
}
}
Discussion