I've spent a few months writing an app that uses SwiftData with inheritance. Everything worked well until I tried adding CloudKit support. To do so, I had to make all relationships optional, which exposed what appears to be a bug. Note that this isn't a CloudKit issue -- it happens even when CloudKit is disabled -- but it's due to the requirement for optional relationships.
In the code below, I get the following error on the second call to modelContext.save() when the button is clicked:
Could not cast value of type 'SwiftData.PersistentIdentifier' (0x1ef510b68) to 'SimplePersistenceIdentifierTest.Computer' (0x1025884e0).
I was surprised to find zero hit when Googling "Could not cast value of type 'SwiftData.PersistentIdentifier'".
Some things to note:
- Calling
teacher.computers?.append(computer)instead ofcomputer.teacher = teacherresults in the same error. - It only happens when
TeacherinheritsPerson. - It only happens if
modelContext.save()is called both times. - It works if the first
modelContext.save()is commented out. - If the second
modelContext.save()is commented out, the error occurs the second time the model context is saved (whether explicitly or implicitly).
Keep in mind this is a super simple repro written to generate on demand the error I'm seeing in a normal app. In my app, modelContext.save() must be called in some places to update the UI immediately, sometimes resulting in the error seconds later when the model context is saved automatically. Not calling modelContext.save() doesn't appear to be an option.
To be sure, I'm new to this ecosystem so I'd be thrilled if I've missed something obvious! Any thoughts are appreciated.
import Foundation
import SwiftData
import SwiftUI
struct ContentView: View {
@Environment(\.modelContext) var modelContext
var body: some View {
VStack {
Button("Do it") {
let teacher = Teacher()
let computer = Computer()
modelContext.insert(teacher)
modelContext.insert(computer)
try! modelContext.save()
computer.teacher = teacher
try! modelContext.save()
}
}
}
}
@Model
class Computer {
@Relationship(deleteRule: .nullify)
var teacher: Teacher?
init() {}
}
@Model
class Person {
init() {}
}
@available(iOS 26.0, macOS 26.0, *)
@Model
class Teacher: Person {
@Relationship(deleteRule: .nullify, inverse: \Computer.teacher)
public var computers: [Computer]? = []
override init() {
super.init()
}
}