11
votes

My project has multiple build targets so I can facilitate "branded" builds that share the same code, but have unique bundle identifiers and assets per target. I've created a watch app for one of my app targets, which is working just fine. Now I'm trying to use the same watch app and extension for my other targets. I thought I could easily duplicate the watch targets (watch and extension) and simply change all the bundle id references to match the other targets but it seems like theres a hidden reference some where.

I just want to use one watch app for all my different branded targets.

Side note: the watch apps also would need to be branded correctly (asset folders).

Any ideas? Thanks.

Solution update

So, I solved it. When I duplicated my watch targets (watch and extension), and changed the bundle ids, target dependencies, everything to make it identical to the old target (but of course pointing to the new targets), for some reason the new watch target didn't point to the correct watch extension target. And there was no way to change it, anywhere. I tried to re-duplicate the targets and still had the same issue.

So what I did was to open the project.pbxproj file, search for any references to my watch extension (and bundle id) and manually update the connections. My watch target had a dependency to the wrong watch extension, and the new watch extension had a pointer to the old watch extension somehow. I later also found out I had to point the build to the correct productreference (appex reference) since this too was wrong.

So the new watch target, pointed to the wrong watch extension, and the correct watch extension pointed to the wrong appex (output file). All of this I had to change manually in the project file. It sounds extreme and hard, but it actually wasn't that difficult once you kept notes of the different UUIDs.

I hope this helps someone else who might stumble upon the same weird issue.

4
I didn't catch about the hidden reference can you please expand this moment.Dmytro Hutsuliak
Sure, even after I had duplicated the watch targets (watch and extension), changed bundle id's and which app it should target and all target dependencies etc, it still wouldnt build. But I have solved it now, ill update the questiontskulbru
I've run into the same problem. Could you post your notes of everything that has to be manually changed after duplicating the target? That would be immensely helpful. Also if you'd move your solution into an answer. :)Jordan H
Yea, sure. Don't duplicate the targets :D It will only cause trouble down the line. Simply do what @DmitryGutsulyak suggested, create new watchkit targets (dont duplicate), and add files to the target membership. After that you will need to update the storyboard target references, see my other question here: stackoverflow.com/q/35039181/215400tskulbru

4 Answers

7
votes

You definitely cannot use one Watch app for multiple targets. Because the only factor Xcode uses trying to find out whether to include a Watch companion app to the bundle or not is a bundle ID of the Watch app. So there is a one-to-one relationship.

It follows you should duplicate each WatchOS app and extension target (changing only the bundle ID) for each iOS app target. But you still can share your code (including storyboards and assets) between targets by using Target Membership and it solves a problem of branded Watch apps either. Finally you get the minimum code duplication overhead.

Update: I see you're trying to duplicate a Watch target using a right click on a target and choosing a Duplicate option. It really doesn't work for some reason.

I just tried to clone a Watch target performing the following steps:

  1. File -> New -> Target -> WatchKit App.
  2. Specified the Embed in Companion Application the needed target.
  3. Added all files to the newly created target using the Target Membership option.

After that a project has been built and ran without any problem with a new Watch target.

This way you don't have to change the bundle ID manually - everything is created automatically and smoothly by Xcode.

2
votes

You can use one target by creating Environment Variables to the projects and assigning in the plist files like images attached below.

Watch Extension ExtensionPlist

Also, you can do all the branding in the code depending on the bundle identifier by having helper like this

extension AppInfo {
    static var develop: Bool {
        return (self.CFBundleIdentifier?.contains("Dev") ?? false)
}

0
votes

faced similar problem "Error=MultipleWatchKitTwoApps ...(~/Library/Logs/CoreSimulator/CoreSimulator.log)", when I ended up duplicating the Main target & added manually watch OS kit.

Solution: Observed that the main target build Phase -> target dependencies will have reference to other watchkit app. Delete & make sure properly added the new watchOS kit app as dependency.

Similarly in Embed watch content section remove the other target watchOSapp reference.

This will resolve the problem "Error=MultipleWatchKitTwoApps ..."

0
votes

I came across this post several times and tried everything without success, and finally, I found how to fix it. I'm assuming you have an iOS app working and an Apple watch app working and you need to add more Apple watch apps without repeating code.

Step 1: File/New/Target Select the "WatchOS" tab and then select "WatchKit App" Select the app you wanna link with this new Apple Watch app Click Next

Step 2: Look at the new folders created for your new Apple Watch app and delete all the *.swift and *.storyboard

Step 3: Select the .storyboard and .swift files of your fist Apple Watch app that was working originally and you should assign them the new and the old Target Membership. In the future, all your watch app files should have those targets selected.

enter image description here