To save people some headaches in the future when they have to work on watchOS 2 projects, here's exactly how you need to configure watch targets to avoid the dreaded LaunchServicesError error 0.
You'll need to create a new App Group so that your watch extension can communicate with the base app. You can name this group whatever you want, but the ID should be your base app's bundle ID prefixed with
.group. So for an app with the bundle ID of
com.company.app the group ID should be group.com.company.app.
This is the part that caused me the most headaches. The ID of an embedded bundle on iOS must be prefixed with the bundle ID of their parent bundle. What makes this confusing in watchOS 2 is the way the directory structure of the bundle has changed. In watchOS 1, both your watch app and watch extension bundles would be embedded directly into the main app bundle. However in watchOS 2, the watch extension is now embedded inside the watch app, which in turn is embedded in the main app bundle.
So following Apple's rules around embedded bundles' IDs, that means our watch app's bundle ID should be prefixed with the main app's bundle ID, and the watch extension's bundle ID should be prefixed with the watch app's bundle ID. What this looks like in practice is as follows:
- Main App —
- Watch App —
- Watch Extension —
All of these app IDs must have the App Groups capability enabled, with the group configured to be the one we set up earlier.
These are pretty easy, just create provisioning profiles for each of the 3 app IDs we've created. To run your app on a real watch, you'll need to include both the watch itself and the paired iPhone in all three of these provisioning profiles.
The watch extension and watch app should be built with the profiles and app IDs we set up for them. On top of that, there's a whole bunch of things that can go wrong in your target configuration that'll generate unhelpful errors. Here's some things to check if that happens:
- The version numbers and build numbers of the main app, watch app, and watch extension must all be identical.
- In the watch extension's Info.plist file, the value of
WKAppBundleIdentifiermust match the
CFBundleIdentifierof the watch app.
- In the watch app's Info.plist the value of
WKCompanionAppBundleIdentifiermust match your main app's