Hey everyone I just ran into an issue where I couldn't sync the model below fully by using CloudKit,
enum LinkMapV3_1: VersionedSchema {
static let versionIdentifier: Schema.Version = .init(3, 1, 0)
static var models: [any PersistentModel.Type] {
[AnnotationData.self, GroupData.self, Item.self, Deployment.self, History.self]
}
// MARK: - Data
@Model
class AnnotationData {
var name: String = ""
var longitude: Double = 0.0
var latitude: Double = 0.0
var order: Int = -1
var level: Int = 1
var detail: String = ""
@Relationship(deleteRule: .nullify, inverse: \GroupData.annotation)
var groups: [GroupData]?
@Relationship(deleteRule: .nullify, inverse: \AnnotationData.to)
var from: AnnotationData?
var to: AnnotationData?
var history: History?
}
// MARK: - History
@Model
class History {
var id: UUID = UUID()
var timestamp: Date = Date()
@Relationship(deleteRule: .nullify, inverse: \AnnotationData.history)
var annotations: [AnnotationData]?
@Relationship(deleteRule: .nullify, inverse: \GroupData.history)
var groups: [GroupData]?
@Relationship(deleteRule: .nullify, inverse: \Item.history)
var items: [Item]?
@Relationship(deleteRule: .nullify, inverse: \Deployment.history)
var deployment: Deployment?
var formattedDate: String {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
return formatter.string(from: timestamp)
}
var timeAgo: String {
let formatter = RelativeDateTimeFormatter()
formatter.unitsStyle = .abbreviated
return formatter.localizedString(for: timestamp, relativeTo: Date())
}
}
}
So when trying to sync with the code in documentation
let modelContainer: ModelContainer
init() {
let config = ModelConfiguration()
typealias vs = LinkMapV3_1
do {
#if DEBUG
// Use an autorelease pool to make sure Swift deallocates the persistent
// container before setting up the SwiftData stack.
try autoreleasepool {
let desc = NSPersistentStoreDescription(url: config.url)
let opts = NSPersistentCloudKitContainerOptions(containerIdentifier: "iCloud.name.Endsunset.LinkMap.SwiftData.v1")
desc.cloudKitContainerOptions = opts
// Load the store synchronously so it completes before initializing the
// CloudKit schema.
desc.shouldAddStoreAsynchronously = false
if let mom = NSManagedObjectModel.makeManagedObjectModel(for: [vs.AnnotationData.self, vs.GroupData.self, vs.Item.self, vs.Deployment.self, vs.History.self]) {
let container = NSPersistentCloudKitContainer(name: "LinkMap", managedObjectModel: mom)
container.persistentStoreDescriptions = [desc]
container.loadPersistentStores {_, err in
if let err {
fatalError(err.localizedDescription)
}
}
// Initialize the CloudKit schema after the store finishes loading.
try container.initializeCloudKitSchema()
// Remove and unload the store from the persistent container.
if let store = container.persistentStoreCoordinator.persistentStores.first {
try container.persistentStoreCoordinator.remove(store)
}
}
}
#endif
modelContainer = try ModelContainer(for:
vs.AnnotationData.self,
vs.GroupData.self,
vs.Item.self,
vs.Deployment.self,
vs.History.self,
configurations: config)
} catch {
fatalError(error.localizedDescription)
}
}
The output is
Where you can see
Optional arrays with @Relationship are missing, and the entry of record types on cloudkit database container are also missing it.
When I attempt to insert an annotation, I got
SwiftData/PersistentModel.swift:559: Fatal error: This KeyPath does not appear to relate AnnotationData to anything - \AnnotationData.groups
It gets more suspicious when restart the app and try again, the above error end with "AnnotationData.history", and if I tried again the above error end with "AnnotationData.from"... and so on.
No matter how my app stop working.