I found a solution which seems to resolve the issue overall. If the container fails to be initialized when iCloud is enabled, try initializing it without a CloudKit Database, then immediately reinitialize with the CloudKit Database. This prevents the app from crashing during migration and resolves the issue in my earlier solution that left CloudKit disabled on first run after migration.
public extension ModelContainer {
private enum Constants {
static var AppGroup = "group.XXXXXXXXXX"
static var CloudKitContainerName = "XXXXXXXXXX"
static var CloudContainer = "iCloud.XXXXXXXXXX"
static var SQLFile = "XXXXXXXXXX-Shared.sqlite"
}
static var DistanceTrackContainer: ModelContainer = {
let cloudConfig: ModelConfiguration = .init(
Constants.CloudKitContainerName,
groupContainer: .identifier(Constants.AppGroup),
cloudKitDatabase: .private(Constants.CloudContainer)
)
let localConfig: ModelConfiguration = .init(
Constants.CloudKitContainerName,
groupContainer: .identifier(Constants.AppGroup),
cloudKitDatabase: .none
)
do {
let container: ModelContainer
if let iCloudContainer = try? ModelContainer(
for: DistanceGoal.self,
migrationPlan: DistanceTrackMigrationPlan.self,
configurations: cloudConfig
) {
container = iCloudContainer
} else {
_ = try ModelContainer(
for: DistanceGoal.self,
migrationPlan: DistanceTrackMigrationPlan.self,
configurations: localConfig
)
container = try ModelContainer(
for: DistanceGoal.self,
migrationPlan: DistanceTrackMigrationPlan.self,
configurations: cloudConfig
)
}
return container
} catch {
fatalError("Failed to configure SwiftData container. Error: \(error)")
}
}()
}
Post
Replies
Boosts
Views
Activity
I found a workaround that prevents the app from crashing during migration, but it does disable iCloud syncing until the app is relaunched. I don't like this solution, I'd rather find something that doesn't disable iCloud syncing.
public extension ModelContainer {
private enum Constants {
static var AppGroup = "group.XXXXXXXXXX"
static var CloudKitContainerName = "XXXXXXXXXX"
static var CloudContainer = "iCloud.XXXXXXXXXX"
static var SQLFile = "XXXXXXXXXX-Shared.sqlite"
}
static var DistanceTrackContainer: ModelContainer = {
do {
let cloudConfig: ModelConfiguration = .init(
Constants.CloudKitContainerName,
groupContainer: .identifier(Constants.AppGroup),
cloudKitDatabase: .private(Constants.CloudContainer)
)
let localConfig: ModelConfiguration = .init(
Constants.CloudKitContainerName,
groupContainer: .identifier(Constants.AppGroup),
cloudKitDatabase: .none
)
let container: ModelContainer
if let iCloudContainer = try? ModelContainer(
for: DistanceGoal.self,
migrationPlan: DistanceTrackMigrationPlan.self,
configurations: cloudConfig
) {
container = iCloudContainer
} else {
container = try ModelContainer(
for: DistanceGoal.self,
migrationPlan: DistanceTrackMigrationPlan.self,
configurations: localConfig
)
}
return container
} catch {
fatalError("Failed to configure SwiftData container. Error: \(error)")
}
}()
}
Were you able to resolve this issue? I'm running into something similar.