Fix SwiftData migration crash on schema upgrades

Add = false/true defaults to all non-optional Bool properties so
SwiftData's lightweight migration knows what value to assign existing
rows. Replace try! ModelContainer with crash-safe do-catch that resets
the store on migration failure instead of crashing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
alexandrev-tibco
2026-04-30 11:24:56 +02:00
parent 4ac81d6223
commit 7da7995538
5 changed files with 24 additions and 11 deletions
+14 -1
View File
@@ -17,7 +17,20 @@ struct MealMoodApp: App {
MealSlot.self MealSlot.self
]) ])
let configuration = ModelConfiguration(cloudKitDatabase: .none) let configuration = ModelConfiguration(cloudKitDatabase: .none)
return try! ModelContainer(for: schema, configurations: [configuration]) do {
return try ModelContainer(for: schema, configurations: [configuration])
} catch {
// Migration failed reset the store to avoid a crash loop
let storeURL = configuration.url
for ext in ["", "-shm", "-wal"] {
try? FileManager.default.removeItem(at: URL(fileURLWithPath: storeURL.path + ext))
}
do {
return try ModelContainer(for: schema, configurations: [configuration])
} catch {
fatalError("Cannot create ModelContainer after reset: \(error)")
}
}
}() }()
init() { init() {
+4 -4
View File
@@ -4,11 +4,11 @@ import SwiftData
@Model @Model
final class AppSettings { final class AppSettings {
var mealWindows: String // "dinnerOnly", "lunchOnly", "both" var mealWindows: String // "dinnerOnly", "lunchOnly", "both"
var includeWeekends: Bool var includeWeekends: Bool = true
var language: String // "spanish", "english" var language: String // "spanish", "english"
var calendarId: String? var calendarId: String?
var syncEnabled: Bool var syncEnabled: Bool = false
var syncMode: String? // "weekComplete", "manual" var syncMode: String? // "weekComplete", "manual"
var lunchTime: Date var lunchTime: Date
var dinnerTime: Date var dinnerTime: Date
@@ -18,8 +18,8 @@ final class AppSettings {
var iCloudSyncEnabled: Bool? var iCloudSyncEnabled: Bool?
var weekExportStyle: String? var weekExportStyle: String?
var isPremium: Bool var isPremium: Bool = false
var onboardingCompleted: Bool var onboardingCompleted: Bool = false
init() { init() {
self.mealWindows = "dinnerOnly" self.mealWindows = "dinnerOnly"
+1 -1
View File
@@ -8,7 +8,7 @@ final class Dish {
var descriptionText: String? var descriptionText: String?
var tagIds: [UUID] var tagIds: [UUID]
var createdAt: Date var createdAt: Date
var isPriority: Bool var isPriority: Bool = false
init( init(
id: UUID = UUID(), id: UUID = UUID(),
+2 -2
View File
@@ -8,8 +8,8 @@ final class MealSlot {
var mealType: String // "lunch", "dinner" var mealType: String // "lunch", "dinner"
var dishId: UUID? var dishId: UUID?
var calendarEventId: String? var calendarEventId: String?
var isRuleOverridden: Bool var isRuleOverridden: Bool = false
var isEatingOut: Bool var isEatingOut: Bool = false
var weekPlan: WeekPlan? var weekPlan: WeekPlan?
+3 -3
View File
@@ -8,11 +8,11 @@ final class Tag {
var nameEN: String var nameEN: String
var color: String var color: String
var maxPerWeek: Int? var maxPerWeek: Int?
var noConsecutive: Bool var noConsecutive: Bool = false
var noDuplicateInDay: Bool var noDuplicateInDay: Bool = false
var mealTypeRestriction: String? // "lunch", "dinner", nil var mealTypeRestriction: String? // "lunch", "dinner", nil
var dayRestriction: String? // nil = any day, "weekdays" = Mon-Fri, "weekend" = Sat-Sun var dayRestriction: String? // nil = any day, "weekdays" = Mon-Fri, "weekend" = Sat-Sun
var isDefault: Bool var isDefault: Bool = true
var sortOrder: Int var sortOrder: Int
init( init(