dyld: Library not loaded for a Framework within a Framework - ios

I am trying to embed a Framework that are using another Framework and this works just fine in the simulator, but it crashes on an iOS device:
dyld: Library not loaded: #rpath/FrameworkB.framework/FrameworkB
Referenced from: /private/var/mobile/Containers/Bundle/Application/B072CD7C-8595-4AE4-A506-26832A0F4402/FrameworkTest.app/Frameworks/FrameworkA.framework/FrameworkA
Reason: image not found
This is my structure in Xcode:
FrameworkTest.xcodeproj (the app project)
FrameworkA.xcodeproj (Cocoa Touch Framework)
FrameworkB.xcodeproj (Cocoa Touch Framework)
The app (FrameworkTest) uses a class A from FrameworkA (which is embedded in the FrameworkTest app). The class A uses the class B from FrameworkB (which is linked in FrameworkA).
This works just fine in the simulator, but it does not work on the device.
The structure may seem a bit strange, but I am developing the frameworks as I go when I develop the app, which is why I want to add the framework projects inside my app project.
I have uploaded the project on GitHub for you to see, if you need to take a closer look. (The class A is invoked in the AppDelegate.m file)
Why is this working in the iOS simulator and not on the device? And how can I make it work on the device?
EDIT:
As simonthumper suggests in the comments, I have also tried to add FrameworkB.framework to Copy Files as Frameworks destination in Build Phases for FrameworkA, but that gives me this error in the console:
dyld: Library not loaded: #rpath/FrameworkB.framework/FrameworkB
Referenced from: /private/var/mobile/Containers/Bundle/Application/2A38A2BC-9CD7-4AF6-9E50-42C16D92D6B2/FrameworkTest.app/Frameworks/FrameworkA.framework/FrameworkA
Reason: no suitable image found. Did find:
/private/var/mobile/Containers/Bundle/Application/2A38A2BC-9CD7-4AF6-9E50-42C16D92D6B2/FrameworkTest.app/Frameworks/FrameworkA.framework/Frameworks/FrameworkB.framework/FrameworkB: mmap() error 1 at address=0x10012C000, size=0x00008000 segment=__TEXT in Segment::map() mapping /private/var/mobile/Containers/Bundle/Application/2A38A2BC-9CD7-4AF6-9E50-42C16D92D6B2/FrameworkTest.app/Frameworks/FrameworkA.framework/Frameworks/FrameworkB.framework/FrameworkB

I contacted Apple with this issue and found a solution to my problem. Apple's Technical support made it clear, that I need to add the FrameworkB.xcodeproj to my application project, so my project structure is:
FrameworkTest.xcodeproj (the app project)
FrameworkA.xcodeproj (Cocoa Touch Framework)
FrameworkB.xcodeproj (Cocoa Touch Framework)
FrameworkB.xcodeproj (Cocoa Touch Framework)
When I have done this the application project can include FrameworkB.framework as an Embedded Library:
This solved my problem and made it possible to run it on an iOS device.
If the build crashes on Release:
Revoke your Enterprise Distribution certificate and create a new one to solve the problem. Once I did that it worked perfectly.

I also had similar issues with embedded frameworks and I just tried your code from GitHub.
Option 1 (not suitable for teamwork)
What made the error disappear was to add FrameworkB to Embedded Binaries in the General tab of your FrameworkTest target.
Option 2
Well, sharing project with other developers sure is important :). Did you try this approach? Add New Copy Files Phase In the FramewrokA's Build Phases and add FrameworkB into Frameworks destination.
But I'm not sure why does it work on the simulator. If anyone knows, please, feel free to comment.
cheers

Related

dyld: Library not loaded realm

i added a framework that i developed in ios to the new project. I tried to make the app universal (one framework work both in device and simulator) according to this tutorial
create an ios universal framework
. When i run my demo project using this universal framework i get this errors
dyld: Library not loaded: #rpath/Realm.framework/Realm
Referenced from: /private/var/mobile/Containers/Bundle/Application/DDF71B22-F535-43E5-B770-D3425419B108/DemoSDk2.app/Frameworks/#######.framework/#########
Reason: no suitable image found. Did find:
/private/var/mobile/Containers/Bundle/Application/DDF71B22-F535-43E5-B770-D3425419B108/DemoSDk2.app/Frameworks/########.framework/Frameworks/Realm.framework/Realm: mmap() errno=1 validating first page of '/private/var/mobile/Containers/Bundle/Application/DDF71B22-F535-43E5-B770-D3425419B108/DemoSDk2.app/Frameworks/##########.framework/Frameworks/Realm.framework/Realm'
both in device and simulator the demo app crash
Dynamic frameworks are by definition not statically linked into binaries that link them.
This means dynamic frameworks must be shipped with the binaries that link them.
The typical way to do this for iOS apps is to have a build phase to copy the framework into your app bundle after compilation.
Due to restrictions by Apple for app store deployment it is not possible to dynamically link frameworks. This is an issue that is common amongst frameworks and not specific to Realm.
The following link is from Realm's GitHub discussion and explains in further detail and offers some work arounds (though none are particularly elegant.
https://github.com/realm/realm-cocoa/issues/3051

Error manually adding framework required by another framework

I'm trying to implement this wonderful framework: https://github.com/Yalantis/Koloda
The framework requires Facebook Pop, I don't like using cocoa pod so I added Pop manually, like this:
And I linked Pop to Koloda, Koloda to main project.
I succeeded running on simulator, but When I ran on iPhone, after the app launches, the compiler says:
dyld: Library not loaded: #rpath/pop.framework/pop
Referenced from:
/private/var/containers/Bundle/Application/9FC4B4D6-35AE-4233-9873-13905A64F725/Memory
Alarm.app/Frameworks/Koloda.framework/Koloda
Reason: image not found
Xcode 7.3.1. Base SDK 9.3 . I was able to compile and run project by manually adding Kolada and Facebook pop. I am not sure if you tried adding Kolada as Embedded project. (Available since ios8). Here are steps I followed:
Right click on my project to add "Kolada".
Right click on Kolada to add Facebook Pop.
2.1. Make sure Facebook Pop is added in General -->Linked Framework and Libraries.
2.2 And in Build Phases --> Add Copy Files Phase. Make destination as Framework and Add pop.framework here.
Add Kolada as Embedded project . Select your project Target . General --> Embedded Binaries.
Following questions might be helpful to you:
Reason: no suitable image found.
dyld: Library not loaded. Reason : no suitable image found
I am attaching screenshots.
Adding Kolada to Project
Once you've added pop to Koloda, you then can add the iOS framework for pop to Koloda, it should appear at the top of the list. Does the Koloda project compile?
Big thanks to #kamal and #JingJingTao for trying so hard to help me with this problem, I solved eventually with Cocoa Pods.
There seems to be some code signing issue with Xcode 7, which is marked out in Xcode 8, unfortunately I wasn't able to use Xcode 8 to build due to the other libraries need upgrade, this problem seem to be very common:
dyld: Library not loaded: #rpath/libswift_stdlib_core.dylib
Eventually, as #JingJingTao suggested, I had to try Cocoa Pods, and it worked, guess for now, it's the only solution.
Last thoughts, Cocoa Pods has an open community, people discuss and fix almost every issue you can encounter, while with Xcode, when you are freaking out with a problem, no one will tap on your shoulder and say: "Hey this is a bug and we will fix it later. " because, they are not open source.

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
Open the project editor pane of Xcode. (The pane is normally closed.)
Control-click the target to display a context menu with a Duplicate command.
Change the name of the target so that you can identify it easily later.
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.
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
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!!

Issue with nested Framework for Watchkit Extension

My Watchkit app does not work in production (TestFlight && rejected from AppStore).
I think the issue come from a nested framework. Here the architecture :
I've made a framework "ModelLayer" (Cocoa Touch Framework) with the app's model, so it can be shared across all targets. This framework use another third party framework (UICKeyChainStore.framework).
And the apple watch extension use "ModelLayer".
When debugging everything works fine. But when I uploaded the archive on iTunes connect I had an error saying that nested frameworks where not allowed. So I removed the copy file phase that I had in the Build Phase of "ModelLayer"'s target. It did not worked well as the app has been rejected...
I found some threads on internet that says that the copy file phase should have as Destination 'Shared Frameworks' and not 'Frameworks' (as I've done before). So I tried this, I've uploaded a pre-release of my app on itunes connect and tried the app with testflight. The app is now on my Apple Watch, but impossible to load the app. The loader stay on screen.
Did I miss something ? How can I use UICKeyChainStore.framework in my 'ModelLayer' framework ??
Thanks in advance !
So I found the solution.
The third party framework in my custom framework was not the problem. But It was my custom framework in the watch kit extension. So it's not possible to embed directly a framework in an extension. The framework should be embedded by the main app. And the extension will be able to use it.
Add the framework to the main app target
In Build Phases Tab
Use the framework in extension target
In General Tab
And in Build Settings Tab -> Linking
Add #executable_path/../../Frameworks to Runpath Search Paths

dyld isuess (Library not loaded)

I have this message when I build my project:
dyld: Library not loaded:
#rpath/iPhoneSimulatorRemoteClient.framework/Versions/A/iPhoneSimulatorRemoteClient
Referenced from: /Users/dev01/mobile/ios/Test/test/testTests/FoneMonkey/bin/iphonesim
Reason: image not found
This is dynamic link error and as I understand correct this error came because image not found. is this correct?
What steps should be taken to resolve errors?
I have found this link and as I understad this error came because I use xcode 4.3. Now I have try this on 4.2 and everething work good.
But I not have any idea how to run it on XCode 4.3
Maybe you have this problem after adding new library and you linked it in actual framework path, if you drag this library in embeded framework path then problem will solve. Another variant is that in build scheme you have enabled memory managment malloc, if you turn it off problem will be solved.
Check your SDK project settings (i.e. when passing from SDK 6.x to 7.x) maybe one of library was not compiled for architecture and project target. And the paths. Clean DerivedData and delete app from simulator (if it is there).
If you still need the Sdk just copy it from Xcode 4.6.(3) both for device and simulator and see if this solve your problem.

Resources