Add Realm to an umbrella/parent framework to use as an application target dependency.
This has been a bit of a saga, to be honest. I'll try to keep it brief and not combine any issues, but I think it's worth mentioning.
I've written an XMPP chat framework that uses Realm for persistence. Adding this framework as a linked library was initially leading to a Segmentation Fault 11:
1. While type-checking declaration 0x7fee91020500 at /Users/corey/Development/<projectName>/User.swift:200:1
2. While loading conformances for 'ChatUser' at <invalid loc>
For clarity's sake, ChatUser is a Realm Object subclass. User.swift conforms to a protocol with a method that returns a ChatUser object.
At this point I decided to step back and eliminate as many variables as possible which leads me to where I am now.
Framework is linked, Realm is found, and application compiles.
I can compile ParentFramework itself without issue. After adding the framework project as a subproject, making it an application's Target Dependency, and linking the parent framework, building fails with:
For simulator:
ld: framework not found Realm for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
For a device:
ld: framework not found Realm for architecture arm64
FWIW, file <path to Realm.framework binary> produces:
.../ParentFramework/Carthage/Build/iOS/Realm.framework/Realm (for architecture i386): Mach-O dynamically linked shared library i386
.../ParentFramework/Carthage/Build/iOS/Realm.framework/Realm (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
.../ParentFramework/Carthage/Build/iOS/Realm.framework/Realm (for architecture armv7): Mach-O dynamically linked shared library arm_v7
.../ParentFramework/Carthage/Build/iOS/Realm.framework/Realm (for architecture arm64): Mach-O 64-bit dynamically linked shared library arm64
My current workaround:
Now, if I build and link Realm.framework and RealmSwift.framework in the containing project (RealmTestExample) as well, it works fine. But surely that shouldn't be necessary?
See Linked code sample, but steps were as follows:
carthage update in the Parent Framework directory and modify the sole method in the framework to return a valid string.ParentFramework as a Target dependency.ParentFramework libraryimport ParentFramework to AppDelegateThis should be everything you need to reproduce: realm-framework-test
ProductName: Mac OS X
ProductVersion: 10.12
BuildVersion: 16A323
/Applications/Xcode.app/Contents/Developer
Xcode 8.2
Build version 8C38
/usr/local/bin/pod
1.0.0
(not in use here)
/bin/bash
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)
/usr/local/bin/carthage
0.19.1
(not in use here)
/usr/bin/git
git version 2.10.1 (Apple Git-78)
Realm version: 2.4.2
In Xcode, the framework search path build setting determines where the linker looks for frameworks at link time. Since your app target attempts to link to RealmSwift.framework (as a result of importing ParentFramework), RealmSwift.framework needs to be available on the framework search path.
It's important to note that while nested frameworks work in the iOS simulator and even locally on your device, iTunes Connect rejects app bundles that contain nested frameworks. The expected pattern is that all frameworks are embedded directly within the app.
Thanks @bdash. I suppose my "workaround" is simply the prescribed solution. Closing this.
Most helpful comment
In Xcode, the framework search path build setting determines where the linker looks for frameworks at link time. Since your app target attempts to link to RealmSwift.framework (as a result of importing ParentFramework), RealmSwift.framework needs to be available on the framework search path.
It's important to note that while nested frameworks work in the iOS simulator and even locally on your device, iTunes Connect rejects app bundles that contain nested frameworks. The expected pattern is that all frameworks are embedded directly within the app.