WatchKit Data Sharing: Beware of the NSFileCoordinator and NSFilePresenter

UPDATE: This issue has been resolved in iOS 8.2 and up! From Apple’s Technical Note:

“Using file coordination in an app extension to access a container shared with its containing app may result in a deadlock in iOS versions 8.1.x and earlier. This is usually the case if a process is suspended mid coordinated I/O. This can be more prevalent on iOS where most apps will be suspended after a short period of time after being moved to the background. Extensions should use alternatives to file coordination. This has since been resolved in iOS 8.2.

One of the biggest challenges of working with WatchKit is figuring out how to best share information between your iOS and WatchKit app. To challenge myself to dive deep and really understand the topic, I gave a talk on the topic at the San Francisco Swift Language User Group Meetup earlier this month. You can view the slides here and the video here.

One of the topics I covered was sharing data between your iOS and WatchKit app using the NSFileCoordinator and NSFilePresenter. The nice thing about the NSFileCoordinator is that there’s a delegate method, presentedItemDidChange, which notifies each party any time the file changes. This means that you can have real-time updates on both your iOS and WatchKit app without any type of refreshing mechanism. Sounds perfect, right?!

I’ve seen several WatchKit project examples use NSFileCoordinator and NSFilePresenter, so I didn’t do more research into it besides learning how to make it work.

Turns out, there’s a bug with NSFileCoordinator and NSFilePresenter that prevents it from being used in extensions. Thanks @stephenpoletto for pointing this out to me. According to Apple’s Technical Note TN2408:

Important: When you create a shared container for use by an app extension and its containing app in iOS 8, you are obliged to write to that container in a coordinated manner to avoid data corruption. However, you must not use file coordination APIs directly for this. If you use file coordination APIs directly to access a shared container from an extension in iOS 8.0, there are certain circumstances under which the file coordination machinery deadlocks.

You can read more on the topic from a few blog posts gathered by @mjtsai: iOS IPC via NSFileCoordinator and NSFilePresenter.

To see how to properly manage file sharing between your iOS app and your WatchKit extension, check out Apple’s use of NSFileManager in their sample Lister app.

Enjoy the article? Join over 20,000+ Swift developers and enthusiasts who get my weekly updates.