3

I have an app with a Today widget extension. I need the app, widget, and other instances of the app and widget on other devices to all share data, so I'm using iCloud Core Data integration. At first, I had the app and widget (within a single device) sharing the same Core Data store (sqlite) in a shared container directory. Now I've enabled iCloud syncing, and that's working between devices, but now I'm getting inconsistent data shown between the app and the widget on the same device (?!?). The problem could be with my widget GUI update cycle or Notification Center subscriptions, which I'm still troubleshooting, but while I do that:

What is the "right" solution for sharing data from Core Data between an app and a widget (or two apps I suppose) on the same device when you're using Core Data + iCloud? Should they share a single physical store, or should they each have their own store? Are there gotchas to either if both approaches are valid?

1
  • Apple's Lister demo app provides a working example. Commented Jan 2, 2015 at 3:02

1 Answer 1

3

The first question you should consider is whether you really need to share the whole Core Data store with your extension. If it is possible just to share a little data, perhaps via a plist, it will make things quite a bit simpler.

Assuming this is not an option, and you really do need the whole store, you have two options:

  1. Share a single store in the shared container
  2. Adopt a Core Data sync solution, and have separate stores for your main app and extension.

It is possible to share a single store between two separate processes, but there are some gotchas. If one process saves, any NSManagedObjectContext in the second process will not register the changes, which will mean the data will not update in the UI, and could also lead to a failed save later.

To get around this, you would have to find a way to pass the object ids of the changed objects from one process to the other, so that the receiving process can refresh objects and re-fetch the latest data.

The second option would involve two separate stores, and a means of transferring changes. If you go with iCloud + Core Data, iCloud is the transfer mechanism, which is a bit overkill given that your processes are both on the same device.

I believe Apple have even warned against using this solution on iOS, because if an iOS app goes to the background, it is possible it will be stopped while a file coordinator has a lock on a file, and that can cause deadlocks in the other process.

iCloud + Core Data is not the only sync solution. A better solution in this case may be the Ensembles framework, which I develop. The reason I say that is that it has the option to sync via local files, rather than requiring a cloud service. You could setup separate stores for your extension and main app, and have Ensembles use the shared container for transferring change sets. No cloud involvement, and no file coordination issues.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks @Drew, I'd heard of Ensembles, and I've actually read your data synchronization article on objc.io. Two clarifications: 1. Yes, I think I need to make a sufficiently large chunk of my model available to the widget, and the widget needs to write data, so I don't think a 2nd persistence layer is good idea. 2. I do indeed have a requirement to sync across devices in addition to on-device--so using a cloud or P2P sync isn't extra overhead, the investment has to be made anyway. I have been targeting Core Data + iCloud because it seemed like the KISS solution, but I'll re-look at Ensembles.
I started looking for that Apple recommendation based on file coordination locking between two processes, and I think this is what you're thinking of, but it appears that's a recommendation against using, say, .plist files or other flat files for coordination, and in fact it says "Instead, use CFPreferences, atomic safe save operations on flat files, SQLite or Core Data." That makes sense, I would imagine (hope?) that Core Data uses some kind of atomic file operation that can't be easily interrupted by an app suspend.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.