You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftData数据无法持久化:宏追踪应用编辑后数据不保存

SwiftData修改无法持久化问题

我正在开发一款宏追踪应用,但使用SwiftData时,编辑数据后从未成功保存。每次关闭应用后,所有对象都会恢复到初始状态,数据并未删除但修改无法持久化。打印变量显示数据已正常编辑,手动保存也没用,看过的待办应用教程帮助不大。


相关代码

应用入口代码

@main
struct Macro_TrackerApp: App {
    var sharedModelContainer: ModelContainer = {
        let schema = Schema([
            Macros.self,
        ])
        let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)

        do {
            return try ModelContainer(for: schema, configurations: [modelConfiguration])
        } catch {
            fatalError("Could not create ModelContainer: \(error)")
        }
    }()
    var body: some Scene {
        WindowGroup {
            TabBarView()
        }
        .modelContainer(sharedModelContainer)
    }
}

数据模型代码

@Model
class Macros: Identifiable {
    @Attribute(.unique) var id: String = UUID().uuidString
    var date: Date
    var fat: CGFloat
    var carbs: CGFloat
    var proteins: CGFloat
    var calories: CGFloat
    
    init(id: String = UUID().uuidString, date: Date, fat: CGFloat, carbs: CGFloat, proteins: CGFloat, calories: CGFloat = 0) {
        self.id = id
        self.date = date
        self.fat = fat
        self.carbs = carbs
        self.proteins = proteins
        self.calories = calories
    }
}

更新数据方法

func updateMacros(dailyMacros: Macros) {
        dailyMacros.fat += quickAddFat
        dailyMacros.carbs += quickAddCarbs
        dailyMacros.proteins += quickAddProteins
        dailyMacros.calories += ((quickAddFat * 9) + (quickAddCarbs * 4) + (quickAddProteins * 4))
    }

视图中的数据引用

@Environment(\.modelContext) private var modelContext
@Query var macros: [Macros]
var dailyMacros: Macros? {
    macros.first(where: { Calendar.current.isDate($0.date, equalTo: Date.now, toGranularity: .day) }) ?? nil
}

触发更新的按钮代码

HStack {
                    CustomButtonView(action: {
                        viewModel.updateMacros(dailyMacros: dailyMacros)
                        print(dailyMacros.carbs)
                        print(macros.first(where: { Calendar.current.isDate($0.date, equalTo: Date.now, toGranularity: .day) })?.carbs)
                    }, label: "Appliquer", color: Color.macroTrackerButton, width: 200, height: 50)
                }

初始化数据方法

func insert() {
        modelContext.insert(Macros(date: Date.now, fat: 0, carbs: 0, proteins: 0))
    }

问题排查与解决

1. 强制手动保存上下文

SwiftData默认自动保存,但快速修改后立即退出可能来不及触发。在更新逻辑后添加手动保存:

func updateMacros(dailyMacros: Macros, modelContext: ModelContext) {
    dailyMacros.fat += quickAddFat
    dailyMacros.carbs += quickAddCarbs
    dailyMacros.proteins += quickAddProteins
    dailyMacros.calories += ((quickAddFat * 9) + (quickAddCarbs * 4) + (quickAddProteins * 4))
    
    // 手动保存上下文
    do {
        try modelContext.save()
    } catch {
        print("保存失败:\(error)")
    }
}

注意要让ViewModel能拿到modelContext,可以在初始化ViewModel时从视图传入。

2. 修复日期匹配的精度问题

当前通过天级粒度匹配日期,但存储的Date包含时分秒,重启后可能因精度问题找不到原有数据,导致重新创建初始对象。给date属性添加转换器,只保留天级精度:

@Model
class Macros: Identifiable {
    // ...其他属性
    @Attribute(.transformable(transformer: DateDayTransformer.self))
    var date: Date
    
    // ...初始化方法
}

// 自定义日期转换器,只保留当天起始时间
class DateDayTransformer: ValueTransformer {
    override class func transformedValueClass() -> AnyClass { Date.self }
    override class func allowsReverseTransformation() -> Bool { true }
    
    override func transformedValue(_ value: Any?) -> Any? {
        guard let date = value as? Date else { return nil }
        return Calendar.current.startOfDay(for: date)
    }
    
    override func reverseTransformedValue(_ value: Any?) -> Any? {
        transformedValue(value)
    }
}

3. 明确指定数据存储路径

给ModelConfiguration指定具体的存储URL,确保数据写入正确位置:

let modelConfiguration = ModelConfiguration(
    schema: schema,
    url: FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appending(path: "MacroTracker.sqlite")
)

4. 验证数据存储状态

通过Xcode的Window > Devices and Simulators选中应用,点击Download Container查看沙盒内的MacroTracker.sqlite文件,确认修改后文件时间是否更新,验证数据是否真的写入。


内容的提问来源于stack exchange,提问作者Killianoni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 04:45:09