Syncing changes between main app and extension

I have an app that starts a Live Activity on a certain user action. This Live Activity contains a button that the user can tap, which updates a SwiftData model instance. However, when you return to the main app after tapping the button on the Live Activity, the views do not update to reflect the changes, even though the changes were written to the database.

The underlying issue here is that the ModelContainer/ModelContext used by the AppIntent (performed from the LiveActivity when the button is tapped), are different from the instances in the main app. Meaning that while the changes are written to the underlying storage, the in-memory instances of ModelContext/ModelContainer in the main app don't get the changes from the extension, so SwiftUI doesn't update either.

What is the recommended way to handle this scenario? Or is there one? :) Shared access to a SwiftData container is clearly supported through App Groups, so is there not a mechanism to ensure changes made by an extension are updated in real-time for the main app?

Otherwise, it seems I would have to go through and manually rerun queries that views depend on to make sure they are showing the most recent data. This is cumbersome and error-prone.

Perhaps I'm missing something? Any suggestions would be greatly appreciated.

Answered by DTS Engineer in 805174022

The SwiftData version of the following Apple sample demonstrates how a main app detects changes from its interactive widget by consuming the SwiftData history. The use case is very similar to yours, and so you might give it a try and share if the sample helps.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Accepted Answer

The SwiftData version of the following Apple sample demonstrates how a main app detects changes from its interactive widget by consuming the SwiftData history. The use case is very similar to yours, and so you might give it a try and share if the sample helps.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

@DTS Engineer Update: This does work in iOS 18, but not quite in iOS 17. The steps I'm doing are pretty straightforward, and very similar to the sample app.

  1. Start Live Activity on some user action in the app
  2. Background the app, and expand Live Activity to show button
  3. Tap button, activating an AppIntent, which updates a SwiftData model and writes its persistent ID to shared UserDefaults
  4. Bring app back to foreground, which observes changes to scenePhase, and when .active, sync changes by calling ModelContext.fetch.

On iOS 18, this works, and the model returned from the fetch call has the latest change written by the AppIntent executed by the Live Activity. On iOS 17 however, the fetched model still contains old data. If I relaunch the app, then I get the updated data in the model, so the change is written, but is not seen when first calling fetch on it.

This seems like a bug, and something that was fixed in iOS 18. Is that a correct assumption?

Yeah, I believe your assumption is right. I vaguely remember that I saw the issue as well when working on the sample (before iOS 18).

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Syncing changes between main app and extension
 
 
Q