Reputation: 65
The following code is working perfectly fine when iCloud is deactivated. A meeting object is saved to the DB and the list on ContentView is updated properly.
But when I activate iCloud the list is not longer updated.
I tried already to wrap the meeting object with @State and loaded/updated the @Bindable property .onAppear/.onDisappear. But without any effect.
import SwiftData
import SwiftUI
@main
struct SwiftDataRelationNavigationApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.modelContainer(for: Meeting.self)
}
}
}
import SwiftData
import SwiftUI
import UniformTypeIdentifiers
@Model
class Meeting {
var id: UUID = UUID()
var name: String = ""
@Relationship(deleteRule: .cascade) var topics: [Topic] = [Topic]()
init(id: UUID = UUID(), name: String = "", topics: [Topic] = [Topic]()) {
self.id = id
self.name = name
self.topics = topics
}
}
@Model
class Topic {
var id: UUID = UUID()
var name: String = ""
init(id: UUID = UUID(), name: String = "") {
self.id = id
self.name = name
}
}
struct ContentView: View {
@Environment(\.modelContext) var modelContext
@Query var meetings: [Meeting]
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
VStack(alignment: .leading, spacing: 5) {
//BUG: the list is not updated after I created a new meeting object when iCloud is activated.
List {
ForEach(meetings) { meeting in
NavigationLink(meeting.name, value: meeting)
}
}
}
.navigationDestination(for: Meeting.self, destination: MeetingDetailView.init)
.toolbar {
Button("add", action: createMeeting)
}
}
.padding()
}
func createMeeting() {
let m = Meeting()
m.name = "New Meeting"
modelContext.insert(m)
path.append(m)
}
}
struct MeetingDetailView: View {
@Bindable var meeting: Meeting
var body: some View {
VStack(alignment: .leading, spacing: 5) {
TextField("", text: $meeting.name)
}
}
}
Upvotes: 1
Views: 35
Reputation: 65
The following code is working including iCloud synchronization and the changes I made are commented.
The App file stays unchanged.
import SwiftData
import SwiftUI
import UniformTypeIdentifiers
@Model
class Meeting {
var id: UUID = UUID()
var name: String = ""
//the relationship is opional now and an inverse target has been added.
@Relationship(deleteRule: .cascade, inverse: \Topic.meeting) var topics: [Topic]?
init(id: UUID = UUID(), name: String = "") {
self.id = id
self.name = name
}
}
@Model
class Topic {
var id: UUID = UUID()
var name: String = ""
//an optionl reference has been added for the relation with a meeting object.
var meeting: Meeting?
init(id: UUID = UUID(), name: String = "", meeting: Meeting) {
self.id = id
self.name = name
self.meeting = meeting
}
}
struct ContentView: View {
@Environment(\.modelContext) var modelContext
@Query var meetings: [Meeting]
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
VStack(alignment: .leading, spacing: 5) {
List {
ForEach(meetings) { meeting in
NavigationLink(meeting.name, value: meeting)
}
}
}
.navigationDestination(for: Meeting.self, destination: MeetingDetailView.init)
.toolbar {
Button("add", action: createMeeting)
}
}
.padding()
}
func createMeeting() {
let m = Meeting()
m.name = "New Meeting"
do {
modelContext.insert(m)
try modelContext.save()
path.append(m)
} catch {
print(error.localizedDescription)
}
}
}
struct MeetingDetailView: View {
@Bindable var meeting: Meeting
var body: some View {
VStack(alignment: .leading, spacing: 5) {
TextField("", text: $meeting.name)
}
}
}
Upvotes: 0