admin管理员组

文章数量:1336320


So, since I updated to Xcode 16.1 and iOS 18, my SwiftData project who relies on autosave doesn't work as expected.

Indeed, it works but only after a delay, around 30 seconds.

So if I add something to the database, I must wait around this delay to quit and relaunch the app, to see the changes persist.

I researched but didn't find any fix, besides using context.save() but since the method can throw errors, I cannot find exactly what errors and so, how to react to them.

If you have a solution, or just an idea, please let me know :)

Thanks a lot guys.


So, since I updated to Xcode 16.1 and iOS 18, my SwiftData project who relies on autosave doesn't work as expected.

Indeed, it works but only after a delay, around 30 seconds.

So if I add something to the database, I must wait around this delay to quit and relaunch the app, to see the changes persist.

I researched but didn't find any fix, besides using context.save() but since the method can throw errors, I cannot find exactly what errors and so, how to react to them.

If you have a solution, or just an idea, please let me know :)

Thanks a lot guys.

Share Improve this question asked Nov 20, 2024 at 12:50 JintaeJintae 537 bronze badges 7
  • 1 I see the same delay but only until I minimise the app or kill it from the device (simulator) so I see no data loss when handling it normally, only when killing the app from Xcode. I don't understand the part about not being able to call save() on the ModelContext. – Joakim Danielson Commented Nov 20, 2024 at 15:05
  • @JoakimDanielson Oh, I can call save() from the modelContext without a problem ! The thing is, the save() method throws errors and I can't find anywhere what errors exactly. So I don't know how to treat them, what to say to the user and what's the best practice to follow. For the moment, I display an error message saying the user should reboot the app, but if I knew the errors thrown by save(), I could be more precise :( – Jintae Commented Nov 21, 2024 at 10:59
  • 1 Surround by do/catch and have print(error) in the catch to start with to determine what error you get? Then you can add better error handling later on but that is another issue. That said if your call to save() throws an error then the automatic save will also generate an error or there is something wrong with how you save. But again this is another issue. – Joakim Danielson Commented Nov 21, 2024 at 11:05
  • 1 Actually I am having the same issues since iOS18 and I worked around it to call save() on all my inserting or deleting operations. I know quite some people complaining about that. It seems there is indeed a change from iOS17 to iOS 18. For me, also on closing the app (in Simulator) changes are not saved. – Armin Scheithauer Commented Nov 21, 2024 at 15:05
  • 1 @ArminScheithauer yea, I guess we should put save() everywhere for the moment, and it seems it's better that way, according to some ios devs I've talked to ;) – Jintae Commented Nov 22, 2024 at 9:54
 |  Show 2 more comments

2 Answers 2

Reset to default 1

The autosave happens every 60 seconds after the app launches, and when the app goes into the background.

You can still call modelContext.save() to do an immediate save after an update.

Re-running the app with the debugger kills the currently running app immediately, so unsaved data is lost. You can work around the loss by sending the app to the background by hand

Personally I have my own autoSave function I attach to the View

ForEach(projects) { project in
    NavigationLink(project.name, value: project)
        .autoSave(project) // <- here
}

And it looks something like this

extension View {
    func autoSave<S>(_ model: S) -> some View where S : SavableProtocol & Observable {
        modifier(AutoSaveVM(model: model))
    }
}

struct AutoSaveVM<S>: ViewModifier where S : SavableProtocol & Observable {
    let model: S
    @State private var error: Error?
    func body(content: Content) -> some View {
        content
            .task(id: model.hasChanges, {
                do {
                    try model.save()
                } catch {
                    self.error = error
                }
            })
            .alert(error: $error)
    }
}

The Observable part will call .task(id: model.hasChanges whenever there are changes.

本文标签: iosSwiftData 30 seconds delay on autosaveStack Overflow