18
votes

I've created iOS Framework project using this method: https://github.com/jverkoey/iOS-Framework

Works pretty neat but I'm a little confused on how to include libraries/frameworks that are needed by my framework to work and, in particular, how to do it so that in case 3rd party client app that uses my framework can include these libs as well without conflicts.

Let's say my framework code needs these two things:

  • FacebookSDK.framework
  • libFlurry.a

The first one is an iOS Framework. When I add it to "Link Binary With Libraries" phase in my Framework and try compile the client project that uses my framework the linker complains about missing symbols - I need to add FacebookSDK to the client project which is great: there is no possibility of conflicts if client apps wants to use Facebook.

However when I do the same with Flurry static library I get duplicate symbols error when compiling client project. Which confuses me a bit, because isn't FacebookSDK.framework just a packaged static library?

ukaszs-iMac:FacebookSDK.framework lukasz$ file Versions/A/FacebookSDK 
Versions/A/FacebookSDK: Mach-O universal binary with 3 architectures
Versions/A/FacebookSDK (for architecture i386): current ar archive random library
Versions/A/FacebookSDK (for architecture armv7):    current ar archive random library
Versions/A/FacebookSDK (for architecture cputype (12) cpusubtype (11)): current ar archive random library

So my questions are:

  1. why a library embedded in framework (like Facebook) is not linked to my Framework project product, whereas library included as .a file is?
  2. how to include .a file in my framework so that it does not produce duplicate symbols error when client app using my framework also needs this particular static library?
7

7 Answers

17
votes

For the use case you are describing, you should be linking to these external libraries from your application, NOT your own framework. It can be one or the other, but it can't be both.

If you decide that these dependancies belong as the responsibility of the application, you would remove them from "Link Binary With Libraries" and any other explicit linking configuration, and just project your framework project with the path to these frameworks and libraries so it can find the symbols (but not link against them) at compile time (i.e. the path to the libraries should be included LIBRARY_SEARCH_PATHS).

4
votes
  1. Use cocoapods , it's easy (http://cocoapods.org/)

  2. Your application developers will have to include the podfile and download the dependencies.

  3. While developing your SDK use a reference application/demo app on top of the SDK to simulate this.

2
votes

You shouldn't link anything when building your framework but just create a *.a binary with your framework's objects.

Also you should not include code from other libraries in your framework as client applications may be adding the same libraries directly or requiring different versions of them, thus creating conflicts.

Off course you can reference *.h header files from other libraries in your framework in order to compile your objects.

As a result the installation steps for your framework should detail other required frameworks/libraries needed, their supported versions, how to add resource files (if any), etc. Just some of the many reasons why you may want to consider Creating a CocoaPods' podspec instead.

1
votes

You should use CocoaPods. Your dependency on Facebook can be done by linking against the CocoaPod.

If you want to include that particular version of Facebook in your pod, you can put it in your repo and use the vendored_frameworks property to refer to it.

Similarly if you wanted to vendor libFlurry.a, you could do so using s.vendored_libraries.

For system libraries, you don't need to vendor them, e.g. libZ.a.

I strongly recommend creating your CocoaPod using pod lib create YourPodName. They've recently changed the mechanism for how this works and it's really nice.

You can create an Example project that shows how to use your code in context of an app.

Then one of the other neat things I just learned about, someone can do pod try YourPodName and it will automatically download, integrate and run the Xcode project.

CocoaPods is worth the trouble.

1
votes

I am building my framework project using CocoaPods. The framework uses some 3rd libs from CocoaPods. Podfile specifies to install dependency on target of the framework. When I build the framework, it includes all libs in the binary.

If I add use_frameworks! in Podfile, when the framework is built, it will not include 3rd party libs.

0
votes

Use CocoaPods dependancy manager. Here's a good guide,

7 miniute video tutorial

-3
votes

Mostly if you install third party frameworks you can install with cocoapods (which is really nice, I would definitely do that) or they offer you to download the framework and include it in your Project. If you decide to download the library and include it there is normally a list of frameworks you need in the "Getting started" guide.

Means: Offer them to install using cocoapods and to download your library but do not include anything else, give them a list what they need.