Adding frameworks to Xcode project - ios

I have added a framework to xcode project. Under Build phases->Link Binary With Libraries.
The framework consists of a library file (.a file) and a folder "Headers" which includes all the necessary header files for that framework.
Now I am trying to import a header file in the framework to one of my classes.
#import <MySDK/MyHeaderFile.h>
But an error occurs "Symbol not found" while building.
My understanding was that, if we are using framework instead of library file there is no need to add the header files path in "Header Search Path".
But still, I have specified the path to my framework in header search path.
Also I have specified the framework path in Framework search and Library Search path options.
This is first time I am working with frameworks. For libraries I just added the .a files and specified full path to header files in header search path.
What configuration am I missing for adding frameworks?

If it's a static library file and a bunch of headers, it's not a framework. A framework is a specific method of packaging files. On MacOS X static and dynamic frameworks have one structure, while static frameworks on iOS have a different structure.
For a static framework using Xcode 5, your file structure would look like this:
MySDK.framework/
en.lproj/
Headers/
MyHeaderFile.h
Info.plist
MySDK
Where MySDK is the binary archive file (it should not be MySDK.a). If you have a file ending in .a , you have a static library rather than a framework. Building a static framework using Xcode 5 isn't easy but it is also not impossible. Building a static library is much, much easier and trouble free however. It sounds like you already have a static library, so you just have to tell Xcode where to find the library archive and header files using the appropriate search path settings for your project or target.
If/when you DO have a framework, adding it to "Link libraries and frameworks" OR setting "Other linker flags" to "-framework path/to/MySDK.framework" will work fine.
Newer versions of Xcode may support different functionality for building or using frameworks, however linking against them should be largely the same.

MySDK/MyHeaderFile.h : This explains that your library is inside MySDK folder. Check if it exists in same path. Otherwise you'll get "Symbol Not Found" error.

Related

Convert a static library target into a framework target in an Xcode project

I have a an Xcode project which produces a static library. My team plans all new development in Swift. It is not possible to add Swift files to the static library project. We are dropping support for iOS 7, so it is now possible to include frameworks in our iOS app. Therefore, I intend to convert my static library project to a framework project.
I have looked but I cannot find any tools or advice for how to perform this conversion. The static library is large (more than 100 .m files).
I'm hoping for a better answer than create a new parallel framework target. I've attempted this twice. The first time as a swift target, but I wasn't able to easily import all the Objective C files. Next, as an Objective C target, but there is no .pch anymore.
To convert the static/dynamic linked framework from static linked library,
Add a new cocoa touch framework as a TARGET in your existing static linked library project.
In the Build Phases, adding all the .m, .mm, .c, .cpp, .metal, etc. into "\Build Phases\Compile Sources" phase of your static linked framework target.
Put the headers that you want to exposed in to "\Build Phases\Headers".
For dynamic linked framework, remember to check the Mach-O Type setting in your Build Settings. If you are going to use swift, you need to make sure the Mach-O type is set as dynamic library so that it will become a dynamic linked framework. For static linked framework, you'll need to set the Mach-O type as static library, but you cannot use swift in the converted static linked framework (only objective-c, objective-c++, C++, C, etc. are allowed).
Then for the app that wants to use this framework just need to include the headers as #import and add the framework into "Build Phases\Link Binary With Libraries" of your App Target. If the converted framework is dynamic linked framework, you will need to put it into "Embedded Binaries".
I saw that someone created the framework manually, creating a module.framework file and copying all the header files in a module.framework/Headers folder. This solution seems to work, the project can import correctly the files and see them as a framework correctly.
I'm not sure this is the best way to do it tough, I'm trying it on a big project that ATM is importing the static library through cocoapods, but it seems like I have some problem with the visibility of some of the classes using the framework.

Deploying static library in Xcode 6

I want to deploy a static library that I've been writing in Xcode 6. I've already managed to compile the library into a .a file. Now I want to use it in another project. Also, note that including the library project is not an option, as this library is supposed to be distributed in binary.
I also managed to import the .a file into a new project, but I'm not sure what the best way to find the header files is. Should I copy them to a system folder? Should I just link to the framework's (downloaded) folder? Should I import the headers directly in the project? As the framework is meant for distribution, I think that ideally I would copy them to a system folder.
Finally, I've read that I need to build two different versions if I want the framework to be compatible with both iOS and the simulator. Is this true? Can it not be distributed in the same binary?
I distribute such a library for my company. I essentially put the .a file (built up with lipo) into a folder along with the headers. The client then needs to add the .a file to their project in the Build phases, Link Binary With Libraries. Then, they should add the path to the header files using a project relative path to the "User Header Search Paths". From my readme:
Process to Add the SDK to Your Project
1) Copy the xxx folder to the app folder, which contains the
".xcodeproj" project file, then add the directory to your project,
but don't add it to any targets (unselect the checkbox).
2) Add the appropriate library (iOS 6.0 or 7.0) folder, by going to your target's Build Phase tab, Link Binary with Libraries, tap
on "+", then navigate to the appropriate folder and select
libXXX.a
3) Add the following to the Project's Build Settings:
Search Paths -> Library Search Paths:
$PROJECT_DIR/xxx/ios // I have multiple folders each with a lib
Search Paths -> User Header Search Paths: $PROJECT_DIR/xxx
Linking -> Other Link Flags: -ObjC NOTE: If you fail to do this, your app will crash on launch (if it uses categories)
I use lipo to add both the Simulator .a files too - even thought this is not officially sanctioned. As others have said, Apple frowns on this yet offers no easy way for users of your library to use different .a files - the "official" solution would be for you to write a custom build script.

How to add a static library to a project that uses cocoapods (iOS)

I have a project that uses cocoapods for some time. Recently, I bought an external library from a vendor. This library was sent to me as a static library (.a) and two headers files (.h).
I imported both files and added the static libraries Build Phases -> Link Binary With Librareis. However, my project can not find the static library.
The same library works fine on a project that does not use cocoapods (and workspace). So I think this is a compatibility problem with the configuration made by cocoapods. I've tried to add the static library path to Header Search Path and Library Search Path. No success.
Any suggestions?
The standard procedure of adding library is
add to OTHER LINKER FLAGS -l${name_of_library_without_LIB_prefix_and_.a_suffix}, for example libz.a will look like -lz
add your library to the library search path. There are useful global vars
$(PROJECT_DIR)
$(SRCROOT)
You can reference it while defining path to your library
add to the HEADER SEARCH PATH path to library headers. You can also use $(PROJECT_DIR) and $(SRCROOT) as a part of the path.
As for using external libraries with CocoaPods - there should be no difference apart from having $(inherited) as a first line of all this settings - library search path, header search path and other linker flags.

Header search path in XCode

I am refactoring the code I produced in XCode in order to have a certain number of static libraries that I can distribute to my partners.
I have no problem in using the static libraries as suggested in the Apple tutorial where they show how to use the static library as a subproject of the project using the library.
However, I have problems in using the produced object file (.a) and corresponding header files (.h) in a new project.
Let's say I have a library lib.a with header f1.h. What I do is create a new folder F inside the new project and copying into F the lib.a file and a folder include containing f1.h:
-- PROJECT
storyboard.storyboard
/project
/images.xcassets
/Supporfing Files
...
/libs
lib.a
/include
/lib
f1.h
I have these problems:
the headers files are found with #import f1.h and not with #import lib/f1.h
if I use a view controller implemented in the static library directly in a storyboard, the app fails, however if I create a new ViewController extending the one in the lib and use the latter one in the storyboard, everything works fine.
Using a static library in an app should not be this difficult so I am clearly doing something wrong. Do you have any workflow and settings to suggest?
Thank you.
When you don't have the corresponding Xcode static library projects and sources, you can use headers and a binary static archive as follows:
Your folder structure should be like this:
$(LIBRARIES)/release-iphoneos
libA.a
libF.a
/include
/A
a1.h
/F
f1.h
Your header search path for Release Configuration (or all others) should contain this path:
$(LIBRARIES)/release-iphoneos/include
Your library search path for iOS (not Simulator) should contain
$(LIBRARIES)/release-iphoneos
where libA.a and libF.a are universal binaries containing armv7, armv7s and arm64.
You can also set a library for the Simulator: just get the binaries for Simulator (i386 or possibly a universal i386 + x86_64) and setup the library and header search paths accordingly. (Note you can set header and library search path for each configuration and architecture explicitly in the Build Settings editor).
You can import the headers as follows:
#import <F/f1.h>
Otherwise
if you have the Xcode static library projects (and the sources), simply follow the instructions in the official documentation to use and build a static library.

How to make XCode add the linked project headers and implementaion files to the static library and framework

I have a static library project and in that project I linked a .xcodeproj to the source code so I can update easily actually and to not copy and paste files in the static library project for easy update.
The purpose thought it's to embed this .xcodeproj with my code into the result static library or .framework that I will build using a script.
Although I can see that there is nothing added in the compile sources or the copy header files which I added. If I try to add with drag and drop files from the linked project to my static library build phases copy header section it copies the file to my project again, but I don't want this.
And if I add a header file #import to one of my public headers and try to use the static library to the client project it complains that the header is not found!
So, in the end, what I want is the whole linked project files to be copied in the resulting static library or .framework with the scripts and target I have.
Is this possible to achieve, I think I miss some project setting that I'm not aware about that will see and copy all header and implementation files to my result static library or .framework?
Is my approach overall correct? I don't think that there is no option to use a linked project in a static library and embed it when the build is happening since I am using it in my project!
I could add the .framework of the third party component too and merge to my static library. I have created this question earlier today. Is it possible to include a .framework in a .framework and how?
Regards.
Not sure if your #import-not-found issue is a linker issue, but...
Make sure to use the -ObjC flag in "Other Linker Flags" in the library's Build Settings. This gets the linker to build everything in the library.
Mentioned here:
https://developer.apple.com/library/ios/technotes/iOSStaticLibraries/Articles/configuration.html
And also make sure you link in the library in the build settings for the project that needs it.

Resources