iOS Simulator crashes, device doesn't (dyld: Symbol not found) - ios

it took me some time to solve this so I thought if someone ever searches for it also they might find the solution here.
The problem occurred when I had a framework called CoreUI. This worked fine on my iPhone and iPad but it crashes on the simulator with the following error to the terminal
dyld: Symbol not found: _OBJC_CLASS_$_CUICatalog
Referenced from: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/UIKit.framework/UIKit
Expected in: /Users/sareninden/Library/Developer/Xcode/DerivedData/Treinplanner-bcfwuvntuwetsmavibxtvaiczpfg/Build/Products/Debug-iphonesimulator/CoreUI.framework/CoreUI
in /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/UIKit.framework/UIKit
After looking through all the build settings and finding nothing I tried making an empty project with a framework called CoreUI. Without any logic added in it, it crashed with the same error.
It appeared that in the simulator CoreUI is also a framework name used by Apple. Even though it was a swift only framework this still causes conflicts.

This is how DYLD_FRAMEWORK_PATH works. Because you have your own CoreUI.framework in your DYLD_FRAMEWORK_PATH, that one is used instead of the system one to satisfy the linkage from UIKit.framework.
Don't pick framework names that are used by system frameworks, ie:
ls $(xcrun --sdk iphonesimulator --show-sdk-path)/System/Library/*Frameworks

The solution is to not use module names (for your app or framework) that Apple uses. I found a list of frameworks here (https://github.com/jonathanpenn/ui-auto-monkey/issues/8). I do not know if it is complete but it is a good start.

Related

How to get CocoaPods-based project to work in the simulator?

I'm trying CocoaPods for the first time, because I've inherited a project that relies on it for several libraries. Articles like this one make it sound like it should all Just Work, even in the simulator.
But it's not working for me — I get an "Undefined symbols for architecture i386" for every class defined in a pod library. Moreover,there are a bunch of ld warnings along the lines of "ld: warning: ignoring file blah/blah/Build/Products/Debug-iphonesimulator/SocketRocket/libSocketRocket.a, file was built for archive which is not the architecture being linked (i386)". I get one of these for each CocoaPods library.
How do I get Xcode to build the pod libraries for the simulator (or link the correct ones, if they're being built)?
OK, I've managed to make it work, though I don't know if it requires both of these steps:
Deleted the derived data, as suggested here
In the Pods project, changed "Build Active Architectures Only" to "No" for Debug as well (it was already set to No for Ad Hoc and Release), as suggested by some of the comments here.
I know that step 1 alone didn't do it... but I don't know whether step 2 by itself would have sufficed. Certainly both of them together did the trick for me.
Adding this answer in case it's helpful to anyone.
To my surprise, it was the simulator version that I was using; iPhone 5 wasn't supported. Xcode gave me no sign of this until I switched to an iPhone 6 simulator, which worked. When switching back to iPhone 5, Xcode then complained that "MyApp does not have an architecture that iPhone 5 can execute."
This is all true and I knew that, but I didn't think of it as the previous error Xcode was giving me was that -lPods-MyApp was missing.

Linking only embedded framework with other dynamic framework fails when build & run on device

tl;dr
Linking your embedded framework with other framework and don't link other framework with your app cause required code signature missing when Build & Run on device.
description:
Setup:
My setup is pretty simple (Swift 2.3 & Xcode Xcode 8.0; Build version 8S162m):
Using Carthage (0.17.2) I have build Other.framework with xcodebuild 8.0 and TOOLCHAINS=com.apple.dt.toolchain.Swift_2_3 carthage build --platform iOS
MyApp has embeded My.framework.
The app and the framework projects are under one Xcode workspace.
I hade linked Other.framework to My.framework ONLY (that means, MyApp is not linked to Other.framework at all). The point here is that, MyApp does not need to use Other.framework API.
Problem:
Everything seems to work fine, until I Build & Run the app on the device. The app launched and than the process is aborted with the following Xcode error:
dyld: Library not loaded: #rpath/Other.framework/Other
Referenced from: /private/var/containers/Bundle/Application/DCF0331F-FF23-43CF-AE79-B3857D5A6EE3/MyApp.app/Frameworks/My.framework/My
Reason: no suitable image found. Did find:
/private/var/containers/Bundle/Application/DCF0331F-FF23-43CF-AE79-B3857D5A6EE3/MyApp.app/Frameworks/My.framework/Frameworks/Other.framework/Other: required code signature missing for '/private/var/containers/Bundle/Application/DCF0331F-FF23-43CF-AE79-B3857D5A6EE3/MyApp.app/Frameworks/My.framework/Frameworks/Other.framework/Other'
I have checked the signature of Other.framework and it looked OK to me. Moreover,
Solution (workaround)
Link MyApp with Other.framework. Horrible... This feels broken.
Linking the very same binary Other.framework to MyApp and solving the issue this way, points out, the Other.framework is built OK and able to be re-signed correctly. Possibly, nothing to do with Carthage.
NOTE:
There is a similar problem iOS 8+ framework with nested embedded framework, however, mine has slightly other reason.
The issue has nothing to dow with nested frameworks. It is entirely about codesignature validation. dyld is reporting that Other.framework is missing a codesignature. You need to sign the framework. This should be done for you by Xcode, so I'm curious how Other.framework is getting built.
You can probably work around this yourself by just signing it.
codesign --force --deep --preserve-metadata=identifier,entitlements,resource-rules,requirements,flags,team-identifier --sign - /path/to/Other.framework
or to just deeply resign your app:
codesign --force --deep --preserve-metadata=identifier,entitlements,resource-rules,requirements,flags,team-identifier --sign - /path/to/My.app
I fixed my exact problem by following this guidance
You don't need to link your 'Other.framework' to your MyApp. Just add run script to sign the whatever embed framework that required code signature missing
Discussing this issue on the Carthage github page, it's become clear that the workaround mentioned in the question, is actually an expected behaviour:
Carthage doesn't support nested frameworks.
Nesting frameworks doesn't let you reuse those frameworks. For instance, if A.framework and B.framework both depend on Other.framework, then neither of them can nest Other.framework—otherwise you might end up with 2 different versions, and the correct one might not be chosen at runtime.
The correct way to do this is to list it as a dependency, but link it into the app target.
Full discussion: Linking only embedded framework with other dynamic framework fails when build & run on device: "required code signature missing"
This was unclear from the README, so I raised another issue, requesting to update the documentation:
Update to README: Linking dynamic frameworks to embedded frameworks requires as well linking them to the app target #1427
This is resolved and closed in the scope of the PR:
#1427 README upd: link dependencies from embedded frameworks to the app target

Linking to iOS simulator binaries on OSX

I was curious what would happen if I linked to an iOS simulator framework in a Mac app. So I copied UIKit to it's own folder (so the Framework search path wouldn't include all the iOS simulator framework, as like CoreFoundation is both on Mac and iOS but has different headers), and dragged it into the link section in Xcode. The error Xcode gave me was:
building for MacOSX, but linking against dylib built for iOS Simulator
file '/Users/jonathan/Desktop/macuikit/UIKit.framework/UIKit' for
architecture x86_64
Both architectures are x86_64, so how can it tell the framework is specifically for the iOS simulator, I removed all references to iOS in things like Info.plist, even tried deleted everything but the UIKit binary, but the same error came up. Is there something in the binary it self that tells the linker which platform it can run on, rather than just the architecture? I looked at the Mach-O header but there is only fields for CPU type and subtype, and neither has a value for the simulator as expected.
After a little bit of digging, it turns out that the platform on which the library can run on is indeed specified in the binary. In fact, you can edit the binary in your favorite Hex editor and make the linker skip this check entirely.
This information is not specified in the Mach-O header (as you have already realized). Instead, it is specified as a load command type. You can see the available types by digging through the LLVM sources. Specifically, the enum values LC_VERSION_MIN_MACOSX and LC_VERSION_MIN_IPHONEOS look interesting.
Now, find the offset for this in our binary. Open the same in MachOView (or any other editor/viewer or your choice) and note the offset:
Once the offset is noted, jump to the same in a Hex editor and update it. I modified LC_VERSION_MIN_IPHONEOS (25) to LC_VERSION_MIN_MACOSX (24)
Save the updates and try linking again. The error should go away. Of course, you will hit other issues when you try to actually run your example. Have fun with LLDB then :)

iOS: adding Admob ads into app giving an error

My app was successfully running on both simulator and physical device. After adding AdMob into my app by following the instruction in this video , however, the app gives an error when building. I have tried several hours to look for the solution to this error, but could not find it. Do you have any suggestion for this? Thank you
ld: duplicate symbol _OBJC_CLASS_$_AppDelegate in /Users/joe/Library/Developer/Xcode/DerivedData/playSound-dxljeytitbiylehchltjsxksklbh/Build/Intermediates/playSound.build/Debug-iphoneos/playSound.build/Objects-normal/armv7/AppDelegate-B7F42A95B6FCD25F.o and /Users/joe/Library/Developer/Xcode/DerivedData/playSound-dxljeytitbiylehchltjsxksklbh/Build/Intermediates/playSound.build/Debug-iphoneos/playSound.build/Objects-normal/armv7/AppDelegate-B9769CE7F9C30755.o for architecture armv7
Command /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang failed with exit code 1
Update:
Even I have not modified any code in my app, just add all the folder of 'GoogleAdMobAdsSdkiOS-6.1.4' in my project explorer as in the video, it then produces the error immediately. I am using xCode 4.2
This may be because 6.1.4 also comes packaged with a Google Analytics xcode project. Try making sure that you remove everything under the 'Add-ons' folder from being referenced in your project (unless you are using it).
You have multiple entries AppDelegate under Targets-Compiled Sources. Check it and ensure there is only one in Compiled Sources.

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