My project has dependent libraries that don't compile under the LLVM compiler, so my project is not compatible with ARC.
How can I include other third party libraries and source files that are ARC compatible in to my non-ARC project.
Thanks in advance.
You could add a complier flag to each compile source in the Build Phases. The flag you should add is -fobjc-arc
If you're not using LLVM your main project won't be able to use ARC at as it's a LLVM 3.0 feature.
If I was you I'd make your main project/target/app compile under LLVM and include your older external dependencies as static library dependencies. Once the static libraries are compiled the fact that they're ARC or non-ARC doesn't make a difference.
You'll need to move to Xcode workspaces that contain multiple Xcode projects, one for each of your third party libraries and have static library targets for each project. This setup allows independent build settings and greater flexibility. You'll find a lot of people create static libraries for third party things these days.
Checkout a blog post or two on setting up static libraries within an Xcode workspace, it's quite common these days.
Related
I'm developing a Cocoa Touch Framework which is used a couple of third-party static libraries and frameworks. For some of them I have a source code. For others I'm don't.
The issue is when someone who uses my framework wants to use the same third-party static libraries and frameworks, he will encounter with console logs like:
Class <ClassName> is implemented in both <Path to my framework> and <Path to my app>. One of the two will be used. Which one is undefined.
My framework is written on Objective-C.
How can I completely hide third-party libraries and frameworks inside my own dynamic framework so that developers who are using my framework also can use the same third-party static libraries and frameworks without any conflicts?
The error that you are seeing in the log is the result of you compiling the source files of the third-party library for both your framework's target and your app's target. You'll most likely see the source files in the Compile Sources build phase for both targets.
To fix this, remove the files from the app's Compile Sources build phase, as it is unnecessary to have them there. It is not necessary to link/compile libraries for your app that have already been linked/compiled into your framework.
I successfully compiled FFmpeg with iOS 8.2 SDK thanks to https://github.com/kewlbear/FFmpeg-iOS-build-script and last version of gas-preprocessor (https://github.com/libav/gas-preprocessor).
However, I would like to package FFmpeg libraries as a iOS 8 dynamic framework due to legal constraints. I found resources to create iOS 8 dynamic framework however I cannot find any solution for FFmpeg.
Can anyone help me to package these librairies ?
Thanks
David
As far as I know, FFmpeg-iOS repo in Github can build static libraries from FFmpeg source code. But I search throughout the network, no one show me how to compile with dynamic libraries.
But I wonder if we can create a new cocoa touch framework project, and drag all header files and libraries into this project, and do some header declaration into the base .h file, and drag the framework project into an existing iOS project as a sub project, add it as an embedded framework, and compile the whole project.
The reason why I use sub project, instead of giving out a final .framework file, is that static symbols can only be linked only if them are been using somewhere.
I will demonstrate this later. If anyone has better ideas, it will be grateful.
Edit:
After several days's researching, I found it is not easy to build dynamic framework easily, but I find a workaround to achieve the target:
Build a static libraries of FFmpeg
Create a new iOS dynamic framework project
Create a class that encapsulate the basic usage of the FFmpeg, such as encoding/decoding video
Copy static libraries into this dynamic framework project
Make sure your project build without error
Add this project as a subproject to your existing project
Add dependency in embedded binaries and Linked Frameworks and Libraries
Build and run main project
Open source this project as LGPL2.1+, the same as FFmpeg itself.
Through it is not perfect, but at least it works, and it complies with FFmpeg's LGPL license.
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:
why a library embedded in framework (like Facebook) is not linked to my Framework project product, whereas library included as .a file is?
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?
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).
Use cocoapods , it's easy (http://cocoapods.org/)
Your application developers will have to include the podfile and download the dependencies.
While developing your SDK use a reference application/demo app on top of the SDK to simulate this.
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.
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.
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.
Use CocoaPods dependancy manager. Here's a good guide,
7 miniute video tutorial
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.
I am trying to use a set of C libraries to allow custom graphs in my iOS project. My projects uses ARC, however, the custom graph libraries are based on a project that does not use ARC. The errors I am getting are related to ARC.
The documentation for the C libraries specify that when using the library to turn off ARC. However, my project is too evolved to revert to a non ARC project.
How might I still use this library in my project? The library is PowerPlot.
You can turn off ARC for the specific library, by adding the -fno-objc-arc compiler flag.
Go in your Target Settings > Build Phases > Compile Sources, and add the compiler flag to every implementation file from the library.
Further information can be found here: How can I disable ARC for a single file in a project?
I am trying to get this sorted out. I know how to get an ARC project working with files or static lib's that are not using ARC. For instance, using the compiler flags -fno-objc-arc.
But what if I have a project that is not using ARC and want to include a static library compiled with ARC? Every time I want to build the project it is telling me that it doesn't recognize things like "strong, __unsafe_unretained,...".
To add on to shw's answer. Add -fobjc-arc to compiler flags under build phases to ARC files to make them compile correctly for non-ARC projects.
More info here
It should work fine - are you sure you're using the newest Apple compiler with this non-ARC project and not the GCC one?