Is it safe to use a NSPersistentCloudKitContainer on a Share Extension?

I have an app that uses NSPersistentCloudKitContainer to store all the data so it's backed by iCloud and synced between devices. Such app has a Share Extension, that can be triggered both from iOS (and iPadOS) and macOS (Catalyst).

I was wondering if it's safe to instantiate an NSPersistentCloudKitContainer from a Share Extension due to it being very short lived. At the moment, I'm sending the data straight to iCloud instead of instantiating an NSPersistentCloudKitContainer, but it feels wrong because I'm using the keys that NSPersistentCloudKitContainer created internally (CD_MyEntity, CD_myProperty, etc.) to send it to iCloud and then being correctly pulled by my clients.

The only concern that I have is that bringing up an NSPersistentCloudKitContainer that has to pull data, might delay or even loose the data that I'm saving right now because it gets killed after some amount of time since the share action has been completed.

Any insights will be much appreciated, because if it's safe to use an NSPersistentCloudKitContainer from a Share Extension, I could remove a ton of fragile code! 🙏

Replies

I have a similar question. It seems like the Share Extension times out before the data is uploaded to CloudKit. If theres no way to force an upload to CloudKit after saving to the context, it seems like we might be out of luck.

Having used this API for two of my apps, and speaking with an Apple engineer, it sounds like we can assume the following:
  • NSPersistentCloudKitContainer can be safely used in a Share Extension for storing data locally. It will complete the save operation locally.

  • Uploading to CloudKit requires a scheduled background operation on the part of the API. Because of this, by the time the Extension is terminated, the background operation is not completed, and thus the CloudKit sync does not occur.

In my testing, this leads to predictable behavior:
  • Data is never uploaded from an Extension, however,

  • Data is saved locally in your persistent container. And upon launching your app, with the container alive once more, it will sync your data to CloudKit.

It's a bit unwieldy having to launch your app after an operation in an Extension, but from my own usage, I think it's safe to say that you can safely use NSPersistentCloudKitContainer, even if it doesn't sync as you or I would like.

I truly hope this behavior is improved soon.

One possibility that i tried before is to extend the extension processing time by wrapping it with performExpiringActivity.

 let processinfo = ProcessInfo()
 processinfo.performExpiringActivity(withReason: "Allow CoreData to sync") { [weak self] (expired) in
      if (!expired) {
        self?.saveViewContext()
      }
 }

In my logs - I do see cloudkit+coredata successfully sync from a share extension