Hello everyone, I am experiencing a very weird issue.
I have a simple relationship between 2 models, that occasionally starts crashing the app, with the following error:
error: <NSPersistentStoreCoordinator: 0x28007f6b0>: Attempting recovery from error encountered during addPersistentStore: 0x282523c60 Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={sourceURL=file:///private/var/mobile/Containers/Shared/AppGroup/F8286D67-AC8C-4441-A151-13B5AAA509F3/Library/Application%20Support/default.store, reason=Cannot migrate store in-place: I/O error for database at /private/var/mobile/Containers/Shared/AppGroup/F8286D67-AC8C-4441-A151-13B5AAA509F3/Library/Application Support/default.store. SQLite error code:1, 'duplicate column name: Z1POSITIONS', destinationURL=file:///private/var/mobile/Containers/Shared/AppGroup/F8286D67-AC8C-4441-A151-13B5AAA509F3/Library/Application%20Support/default.store, NSUnderlyingError=0x2825c6700 {Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={NSSQLiteErrorDomain=1, NSFilePath=/private/var/mobile/Containers/Shared/AppGroup/F8286D67-AC8C-4441-A151-13B5AAA509F3/Library/Application Support/default.store, NSUnderlyingException=I/O error for database at /private/var/mobile/Containers/Shared/AppGroup/F8286D67-AC8C-4441-A151-13B5AAA509F3/Library/Application Support/default.store. SQLite error code:1, 'duplicate column name: Z1POSITIONS', reason=I/O error for database at /private/var/mobile/Containers/Shared/AppGroup/F8286D67-AC8C-4441-A151-13B5AAA509F3/Library/Application Support/default.store. SQLite error code:1, 'duplicate column name: Z1POSITIONS'}}}
This is particularly weird because the app runs a few times without any code changes, or any CRUD operations in the database, and then suddenly starts throwing exceptions.
These are my models:
@Model
final class Desk
{
@Attribute(.unique) let id: UUID
let name: String?
@Relationship(deleteRule: .cascade) var positions: [DeskPosition] = []
init(id: UUID, name: String?) {
self.id = id
self.name = name
}
}
@Model
final class DeskPosition {
let id: UUID
var title: String
private var heightInCm: Double
@Transient
var height: DeskHeight {
get {
DeskHeight(value: heightInCm, unit: .centimeters).localized
}
set {
heightInCm = newValue.converted(to: .centimeters).value
}
}
init(id: UUID, height: DeskHeight, title: String) {
self.id = id
self.heightInCm = height.converted(to: .centimeters).value
self.title = title
self.height = height
}
}
And this is my schema and model container (I tried adding both models to the schema, or just adding the parent model, and does not seem to make a difference):
private var sharedModelContainer: ModelContainer = {
let schema = Schema([Desk.self, DeskPosition.self])
let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)
do {
return try ModelContainer(for: schema, configurations: [modelConfiguration])
} catch {
fatalError("Could not create ModelContainer: \(error)")
}
}()
I couldn't find anyone else having this same issue. There must be something obviously simple that I am not looking at. Can anyone help? Thank you!
I had the exact same problem. On the first startup everything is ok, then on the second one it crashes. It seems SwiftData doesn't see the already existing column for one-to-many relationship. This, in turn, crashes the application because of the duplicated column.
The solution that I found is to explicitly create the inverse relationship in the second model. So, in your case, changing your DeskPosition model to this:
@Model
final class DeskPosition {
let id: UUID
var title: String
var desk: Desk?
private var heightInCm: Double
@Transient
var height: DeskHeight {
get {
DeskHeight(value: heightInCm, unit: .centimeters).localized
}
set {
heightInCm = newValue.converted(to: .centimeters).value
}
}
init(id: UUID, height: DeskHeight, title: String) {
self.id = id
self.heightInCm = height.converted(to: .centimeters).value
self.title = title
self.height = height
}
}