This is part 2 of a 2 part series on using and creating static iOS libraries. See part one: Using static iOS Libraries. for info on how to use static libraries in your own projects.
All of the below steps can be applied to create and package your own static libraries for distribution.
- Create a new Xcode project of the iOS > “Cocoa Touch Static Library” variety.
- Add your relevant source files to the project. (.h & .m)
- I like to add a single .h file that includes all other public headers e.g.
- Select your newly created target.
- Select “Build Phases”.
- Delete the Auto Generated “Copy Files” Phase. (Xcode defaults to adding this, however i prefer to use an actual copy headers phase, which we will add in a second.)
- Now add a new “Copy Headers” phase.
- Add your public headers to the public section & your private headers to the private section.
- Add any other dependant frameworks to the “Link Binary With Libraries” phase. (e.g. Addressbook.framework or CoreLocation.framework)
- Select “Build Settings”.
Public Headers Folder Pathand set it to
include/$(TARGET_NAME)we also want to set
Private Headers Folder Pathto
$(PUBLIC_HEADERS_FOLDER_PATH)/Private. This allows users of our library to find and include our headers. (We include the
$(TARGET_NAME)variable so that users can include our headers using the standard framework idiom
Installation Directoryand set it to
Skip Installand set it to
- Make sure
-all_load -ObjCis added to the
Other Linker Flagssection. (This makes sure everything in the static library is linked, even if not used at compile time. i.e. making it available at run time.)
Other Things To Consider
Trouble Finding Headers
Your users may have trouble finding headers in their projects even though they have added
include/ to their
Header Search Paths.They are likely running into an issue whereby the static library is being built with one configuration name and their project is building with another. (i.e. Debug vs DebugStaging)
Xcode will, on finding a matching configuration name in a sub-project use that configuration to build the sub-projects targets, however if it can’t find a matching configuration it uses the projects default config. This can lead to problems finding the matching headers. (i.e. Xcode is looking in
Build/Products/DebugStaging-iphonesimulator and your library is being built into
To work around this you can set your public / private headers folder paths to be
../../Headers/$(TARGET_NAME), i.e. in the folder above the config specific folder that Xcode creates when building projects. If you choose to do this your users will instead need to add this folder to their header search paths instead of
Headers being included in Xcode archives
If the path your static library is putting its headers into starts with a slash i.e.
/include/$(TARGET_NAME), Xcode will include the headers in archived builds (because it’s a fully rooted path). This leads to app store validation failing when trying to upload a build. The solution to this problem is to change your public headers folder path in your library to no longer include the /.
Ideally you would set
Public Headers Folder Path to
Private Headers Folder Path to
Specific Build Settings
Your Static Library Project
PUBLIC_HEADERS_FOLDER_PATH="include/$(TARGET_NAME)"; /*Public Headers Folder Path*/ PRIVATE_HEADERS_FOLDER_PATH="$(PUBLIC_HEADERS_FOLDER_PATH)/Private"; /*Private Headers Folder Path*/
HEADER_SEARCH_PATHS="include/**"; /*Header Search Paths (the ** indicates recursive)*/