We are developing an iOS app using SwiftData. We have Bucket
and BucketItem
models where a Bucket
can have many BucketItem
, so there is a relationship between Bucket
and BucketItem
. Below is a simplified version of the models.
import Foundation
import SwiftData
@Model
class Bucket {
var name: String
var shared: Bool
@Relationship(deleteRule: .cascade, inverse: \BucketItem.bucket) var items = [BucketItem]()
init(name: String, shared: Bool) {
self.name = name
self.shared = shared
}
}
import Foundation
import SwiftData
@Model
class BucketItem {
var content: String
var bucket: Bucket
init(content: String, bucket: Bucket) {
self.content = content
self.bucket = bucket
}
}
We show a list of Bucket
with a count of how many BucketItem
it has. This is working in the app on the device and simulator, however the relationship is not working on the Preview. Below is a simplified version of this component with the Preview configuration
import SwiftUI
import SwiftData
struct BucketsData: View {
var bucket: Bucket //this is provided by a parent component that uses @Query to fetch the Buckets
var body: some View {
List {
Section(bucket.name) {
Text("Items: \(bucket.items.count)")
}
}
}
}
#Preview {
let config = ModelConfiguration(isStoredInMemoryOnly: true)
let container = try! ModelContainer(for: Bucket.self, configurations: config)
let testBucket = Bucket(name: "Test Bucket", shared: true)
container.mainContext.insert(testBucket)
let testItem = BucketItem(content: "Test Item", bucket: testBucket)
container.mainContext.insert(testItem)
return BucketsData(bucket: testBucket)
.modelContainer(container)
}
The list show the "Test Bucket" with a count of 0 items. It appears that for some reason the items
array is not getting populated with the related BucketItem
. How can we fix this?
You can fix this by making BucketItem.bucket
optional, like so:
@Model
class BucketItem {
var content: String
var bucket: Bucket?
init(content: String, bucket: Bucket? = .none) {
self.content = content
self.bucket = bucket
}
}
Why does this work? I don't know. SwiftData is weird.
Joakim Danielson already said it in the comments, but I'm posting this as an answer so people will know that this question is answered. I've tested this solution and it works.