First, you might examine if you really need to share the whole data set between your main app and extension. In the case where the shared data is not closely connected to your existing data, you might just configure an App Group container and create a new store there for the data sharing purpose. That way, your existing data is untouched; your extension accesses the new shared store only; your main app can manage both stores using a Core Data stack, which is demonstrated in Linking Data Between Two Core Data Stores.
If you do need to copy your existing store to an App Group container to share it with your extension, let's say a widget, consider the following flow:
On the main app side:
-
Check if the destination store URL exists. If yes, the copy is done, and so you continue the normal process.
-
Otherwise, copy the store using replacePersistentStore(at:destinationOptions:withPersistentStoreFrom:sourceOptions:type:).
-
Set hasCopiedToAppGroup to true in the UseDefault that is tied to your App Group container and shared between your main app and widget. For more information about shared UserDefaults, see UserDefaults.init(suiteName:).
-
Continue your normal process to load and use the store.
On the widget side:
-
Check if hasCopiedToAppGroup in the shared UserDefault is true. If yes, continue your normal process to load and use the store.
-
Otherwise, present something in the UI to ask the user to launch the main app. With this, the widget doesn't access the store before it exists.
In this flow, hasCopiedToAppGroup helps the widget avoid accessing the store while the main app is copying.
There are more details you need to handle when sharing a Core Data store between an app and its extensions, but I hope the above information gets you started.
Best,
——
Ziqiao Chen
Worldwide Developer Relations.