Maxim Shoustin
Maxim Shoustin

Reputation: 77904

How to build dynamic Framework for iOS with no Embedded Binaries?

I try to generate framework named AfTestFramework for ios. I created through Xcode Cocoa Touch Framework with some basic code, ran it and got:

enter image description here

So far so good.

I created new Test Application and drag @ dropped AfTestFramework.framework into the project, like crashlytics does (see below)

After building project and running I got Library not loaded ... Reason: image not found:

dyld: Library not loaded: @rpath/AfTestFramework.framework/AfTestFramework Referenced from: /var/containers/Bundle/Application/9B12D0AD-94AA-4119-A5DE-6BCAA806FA9F/TestAvoidEmbedded1.app/TestAvoidEmbedded1 Reason: image not found

I know the solution is to attach this framework to Embedded Binaries but I look for the way to avoid this approach.

Further, It demands to create 2 Frameworks: for Simulator and for Release otherwise I cannot release application with my framework, that looks a bit messy and weird.

I found that following frameworks work without Embedded Binaries:

ans so on.

So far I didn't find any description, I know also that its something new.

I started to play with xcodebuild like:

 xcodebuild -sdk "iphoneos10.1" "ARCHS=arm64 armv7 armv7s" "VALID_ARCHS=arm64 armv7 armv7s" "ONLY_ACTIVE_ARCH=NO" -target AfTestFramework  -configuration "Release"  clean build

but no success.

Can somebody spread the light on this problem?

Upvotes: 3

Views: 3547

Answers (3)

Alej priv
Alej priv

Reputation: 101

this is old but if its useful for future reference: you can do

$lipo -create <path to simulator framework> <path to device framework> -output <path to the output framework>

Upvotes: 1

clemens
clemens

Reputation: 17721

If you add a dynamic Framework to your iOS project, you must add it to the Embedded Binaries. In opposite to static libraries are dynamic libraries loaded at runtime. Thus the dynamic linker must access them on the device.

The only possible way to add the code inside of the framework without embedding the framework is to bind it statically to your app. For that you should create a static library from the framework. (Probably, libtool(1) may help you with that.) But anyway you may run into other problems, if the framework needs its bundle structure for loading resources etc.

Upvotes: 3

drekka
drekka

Reputation: 21883

I'm not quite sure what you are trying to achieve but it sounds like you are trying to create a framework which has a dependency on another framework.

So when used, it would be something like app -> your-framework -> some-other-framework.

I would strongly recommend looking at carthage as a solution to our problem. Carthage is an OS X native dependency manager that is designed to manage dependencies for you.

Firstly you need to check that the framework your framework uses is Carthage friendly. For now I'll assume so.

In your frameworks project you would add a Cartfile where you declare your dependency on the other framework, then use Carthage to download and build the other framework. You then add the built framework to your project as you would with any Apple supplied framework. You DO NOT need to embed the framework and generally speaking it's not recommended to do so. Carthage will handle this issue.

In the app project you would then also add a Cartfile, but you only need to specify your project in it. When Carthage builds the framework, it will automatically locate the other framework, download and build it as well. Then in the apps build phases you simple specify linking agains both frameworks and add a carthage-copy script phase to include them in the Frameworks directory of the finished app.

With regard to building for simulator and release. You don't need to build multiple targets. For a start, using Carthage means that the frameworks are only built when you need them, so this removes any requirement for you to supply binaries.

When telling Carthage to build the dependencies, by default it builds Release binaries. Building Debug frameworks for testing is just a matter of add --configuration Debug to Carthage's command line arguments.

Finally - to be fair, there are also two other package managers out there: Ruby based CocoaPods which is an older manager and for Swift, the Swift Package Manager. Personally I prefer Carthage for reasons I explain in a blog post here.

Upvotes: 0

Related Questions