Search code examples
iosobjective-capple-watchwatchos-2dyld

WatchOS 2 App fails to launch on device with dyld_fatal_error for my Framework Library not loaded: Image not found


I've just followed the apple transition guide to upgrade my ObjectiveC app to WatchOS 2

https://developer.apple.com/library/watchos/documentation/General/Conceptual/AppleWatch2TransitionGuide/ConfiguretheXcodeProject.html

With the section "Sharing Code Between an iOS App and a watchOS App" describing how to duplicate an existing iOS framework into a WatchOS framework target for use by WatchOS as follows.

"If you already have a watchOS 1 app that shares a framework with your iOS app, duplicate your iOS framework target and modify it to support watchOS 2.

To duplicate and configure your framework target for watchOS 2

  1. Open the project editor pane of Xcode. (The pane is normally closed.)
  2. Control-click the target to display a context menu with a Duplicate command.
  3. Change the name of the target so that you can identify it easily later.
  4. In Build settings, change the following values:
    • Change the Supported Platforms setting to watchOS.
    • Change the Base SDK setting to the latest watchOS.
    • Change the Product Name setting so that it matches the name of your iOS framework. You want both frameworks to be built with the same name.
  5. Add the framework to your WatchKit extension’s list of linked frameworks."

I've followed these steps to clone my framework which with the iOS framework was called MyFramework, and now the new WatchOS framework is called MyFrameworkWatch. But as described above the Product Name is set to MyFramework instead of MyFrameworkWatch. I presume this naming shift is so that I can include from my framework using

#import <MyFramework/SharedUtils.h>

instead of presumably having to change it to

#import <MyFrameworkWatch/SharedUtils.h>

I wouldn't mind the latter but I'll admit its nicer keeping the framework name the same.

After a bit more work beyond the initial automatic transition I managed to get my app working perfectly well on the simulator, but now switching to device i just can't get it to launch.

Launching my app on the device causes it to spin for a few seconds and then just crash. Launching the glance just causes it to spin indefinitely. Trying to run it from Xcode and running the app causes the app to eventually launch and spin, the spinning can last indefinitely sometimes, but eventually it gets through and i get the actual error reported as follows

dyld_fatal_error - dyld: Library not loaded: @rpath/MyFramework.framework/MyFramework referenced from WatchKit Extension Reason: image not found

So this is my Watch App Extension trying to link to the Watch framework, and doing so looking for the MyFramework name, not the MyFrameworkWatch name. I wonder if this name clashing has caused it to get confused?

When I try to find the frameworks referenced under the Products folder in Xcode I can see two frameworks

MyFramework
MyFramework

they're both reference the same path

/Users/jim/Library/Developer/Xcode/DerivedData/MyApp-byegspjumgwlfpahhwjgzpmfkcdx/Build/Products/Debug-iphoneos/MyFramework.framework

though you can see the target membership is separating the two frameworks, the top MyFramework is associated with the main app, today widget and framework tests project. The lower MyFramework is just associated with my Watch extension. It doesn't feel right that these are referencing the exact same path surely?

Finally when googling for this issue I've found reference of CocoaPods having similar problems though according to their site here

https://github.com/CocoaPods/CocoaPods/issues/4180

It's been fixed since September in version 0.39.0, which is the version that pod --version reports. So I presume I have their fix. I'm tempted to remove the cocoa pods from my framework to see if it helps.

Has anyone else followed the transition guide suggestions for creating a duplicate framework and then managed to get the app and framework actually installing on their watch ok?

Is there any way to analyse the build that is done to try and see if i can see problems with the built files so i don't have to wait for the watch to fail to launch the app to debug it.

Any help is really appreciated as always! Cheers!

Edit: I think I've managed to remove cocoa pods from the offending MyFrameworkWatch target by commenting out the target section in my pod file and running pod update/pod install... it didn't seem to clean up the target very well so i had to manually remove the cocoa pod steps in the post build step. Maybe i've not removed it properly, i find it a little confusing to know what is going on under the hood with cocoa pods. Regardless the same error occurred, so either i didn't remove it properly or it has no effect on this particular problem


Solution

  • Ok, this was caused by the apple documentation for transitioning being wrong, or me interpreting it wrong. It says

    Add the framework to your WatchKit extension’s list of linked frameworks.

    Where as actually the correct fix was to add the framework to the embedded binaries section (which automatically adds an entry to the linked frameworks anyways) and correctly places the framework within the watch extension under a Frameworks directory. Which the app then loads fine! So much frustration, I lost hours to this across a few days!!