My Swiftdata App (using Apples WWDC23 SampleTrips App PreviewSampleData for generating #Previews) keeps crashing its canvas previews after enabling CloudKit. The crash always happens when trying to initialise the in-memory ModelContainer:
actor PreviewSampleData {
@MainActor
static var container: ModelContainer = {
return try! inMemoryContainer()
}()
static var inMemoryContainer: () throws -> ModelContainer = {
let schema = Schema([Trip.self, BucketListItem.self, LivingAccommodation.self])
let configuration = ModelConfiguration(isStoredInMemoryOnly: true)
let container = try! ModelContainer(for: schema, configurations: [configuration]) <—- crash continues to happen here
let sampleData: [any PersistentModel] = [
Trip.preview, BucketListItem.preview, LivingAccommodation.preview
]
Task { @MainActor in
sampleData.forEach {
container.mainContext.insert($0)
}
}
return container
}
}
I thought I’d share here the solution I’ve found after being confused by the error messages I received (failed to load stores) and lots of trial and errors.
After enabling CloudKit in Capabilities I let Xcode create a NEW CloudKit container. Then, the App had to run on a Simulator SIGNED IN to an Apple developer account. This synced the Swiftdata Schema of the App with the CloudKit container Schema.
After this, the canvas previews stopped crashing.
Important to also mind current CloudKit limitations concerning @Model objects as they can cause errors that are hard to track down. In your @Model…
- don’t use @Attribute(.unique)
- Don’t use @Relationship(.deny)
- All attributes need to be either optionals or have a default value.
As per https://forums.developer.apple.com/forums/thread/731401 also make sure that @Relationship's are optional and initiated eg. As
@Model final public class MainItem { var title: String?
@Relationship(deleteRule: .cascade)
var childs: [ChildItem]?
init(title: String? = nil, childs: [ChildItem]? = []) {
self.title = title
self.childs = childs
}
}
@Model final public class ChildItem { var timestamp: Date?
// Add inverse as a simple variable
var item: MainItem?
init(timestamp: Date? = nil, item: MainItem? = nil) {
self.timestamp = timestamp
self.item = item
}
}
The crucial part that stopped preview crashes with the ‘Backingdata.swift Unknown Type … ‘ error is childs: [ChildItem]? = [] NOT childs: [ChildItem]? = nil