流程- 建立一個xcodeproj ( 專案檔 )
- 撰寫一個*.m ( source code )
- 將 *.m build *.a (library)
- 撰寫一份document說明function call/back rule.
- Release *.a-library , xcodeproj(專案檔) , release document.
Build iPhone static library with Xcode
Build iPhone static library with Xcode
Question: Our project team has a new iPad/iPhone 4 project. We want to put some business logic and generic functionality into a common library but the Xcode 3.2.2 SDK does not allow us to create custom Frameworks unlike for Mac OS X. Is there a way to build a dynamic library for iPhone apps too? We have already opened our App Store account.
Answer: Welcome to the iPhone world and its static libraries! Due to the Apple’s policydynamic libraries are not allowed to be used in iPhone or iPad applications when you want to sell them on the App Store. Currently the only way to create re-usable code amongst different projects is to create static libraries. 3rd party frameworks as in Mac OS X are not supported in the iPhone SDK.
Building a library is a good idea when you have a large project or you must manage more projects. There is always a lot of code that is very generic and could be placed in their own shared libraries.
With Xcode you can build your own static library that you can share with your co-workers or clients, so that they could link it directly into their own app. You can find good tutorials over the Internet. Major steps are:
1. Create an Xcode project for your static library.
2. Create a static library target with the appropriate configurations (see Xcode documentation).
3. Pack and distribute your files. You have to add the headers and any other resources (like images) that it uses.
4. Copy the library package to a handy local folder to easily keep track of future changes. In Xcode drag the header(s), other resource files if any, and the library file from this distribution folder into your project and choose that you DO NOT want it to be copied. Xcode automatically adds the library to the target. The static library package will be included in the app bundle.
Cross-project reference
If the static library and its source code is being distributed among your collegues as an Xcode project by using a “cross-project reference”, the building of the common libraries “on-demand” can be flowless for all of you. In this case libraries are built dynamically and you are using your own app’s current build configuration. The benefit is the simple setup: it allows you to both reuse shared source code and avoid the headache of managing multiple versions of the library. The drawback is the references may not be automatically updated, so that code modifications need to be refreshed at dependent projects manually.
1. The shared code of the static library resides in its own Xcode project that, when built, results in one or more static libraries. You must create an Xcode environment variable with a path to the folder that contains the static library’s *.xcodeproj file. See Xcode -> Preferences -> “Source Tree”. Add your variable that Xcode can use to dynamically find the static library project.
2. Add the library project as a sub-project to your own Xcode project. It is a reference only. See Xcode -> Project -> Add to Project.
Your applications must now set this environment variable to cross-reference the library’s Xcode project, including any static library in that project and the related header and other resource files. See Xcode -> Click on the sub-project -> File -> Get Info -> Path Type. Change the relative path to your environment variable.
Select your main application target and hit Cmd+i (Get Info). At the General tab add the static library(ies) your project needs from the shared static library project by clicking the “+” button under “Direct Dependencies”.
Add your library’s path to the User Header Search Paths (at Build tab). You can use this syntax: $(ENVVARIABLE), where ENVVARIABLE is your environment variable of the path to the static library (see step 1). Add -ObjC and -all_load flag to the Other Linker Flags key.
Now drag and copy the static library(ies) from the cross-project reference to “Targets > {your app target} > Link Binary with Libraries.” This ensures that that the .a file(s) will be passed to the linker when you do the build.
3. Each time you build your project for a specific runtime configuration, the shared project library will also be built.
-ObjC and -all_load flags
Do not forget to add these flags to the application target’s “Other Linker Flags” build key.
Objective-C only generates one symbol per class. We must force the linker to load the members of the class too. This is what flag -ObjC does. We must also force inclusion of all our objects from our static library by adding the linker flag -all_load. If you skip these flags sooner or later you will run into the error of “unrecognized selector” or get otherexceptions.
We’ve been using this approach from the very beginning and it’s definitely saved us a lot of time.
Useful links:
Apple’s iPhone Developer Center
Visit Apple’s discussion forum for iPhone and iPad issues
Please note that iPhone SDK 4 is available for download and 3.2.2 is not the latest platform any longer.
iPhone OS Static Library Template for XCode
One of the easiest ways to overwhelm yourself when developing for iPhone OS is to try to manage all your code in one project. I’ve done it countless times but have finally come up with a nice solution to separating libraries out of the main project. To make it way easier, here’s an XCode template to automate most of the process.
Installation
- Download the iPhone OS Static Library Template from my Git Hub Projects.
- Extract it and move the contents to ~/Library/Application Support/Developer/Shared/Xcode/Project Templates/iamamused/iPhone OS Static Library/ (that would be the Library in your Mac OS X /Users home directory)
By placing the template project here you’ll be able to select it from the iamamused section in User Templates when creating new projects.
Creating a new Static Library project
- In XCode select File→New Project…
- Select the iPhone OS Static Library template from the iamamused section in User Templates (See what I did there?)
- Enter a project name such as “MyLibraryKit” for your static library.
- Yipee! You now have a library all set up and ready to import into your projects (see “Including your Library in Existing Projects” below), though it doesn’t do anything yet.
Template layout
The project template comes with a few special things.
- An include folder to store your library specific files.
- A DemoAppDelegate and DemoViewController based on an iPhone OS View Application that already includes the library. The Demo app classes and resources are not included in the static library. They are there only to give you a quick and easy way to test your library outside your main projects. Feel free to edit the Demo target any way you please as it won’t interfere with the library target.
- Targets for both the Demo as well as a target for a [YourProjectName]Mobile static library. The[YourProjectName]Mobile target produces a product called lib[YourProjectName].a which is the actual static library you’ll link to in your projects.
Adding Library Specific Classes
When you want to add new classes to include in your static library, remember these few things: * Add new class (.m
and.h
) files to the include folder in your library project. This folder will be referenced in the Header Search Paths in your other projects so if the header files are not in include then you’ll get lost of errors. * Only add new library files to theMobile target, not the Demo target. * Don’t forget to include the new header .h
files in your libraries main header file.
An Example
For example, let’s say you have created a library called MyLibraryKit and you now want to add a new subclass of UIViewcalled MLKView. Start by right-clicking on the MyLibraryKit Framework group in the Groups & Files tree in yourMyLibraryKit Xcode project window and select Add→New File…
Next, Select iPhone OS→Cocoa Touch Class→Objective-C class and select a subclass of UIView from the dropdown menu. In the New File dialog make sure you do the following:
- Set the File Name to
MLKView.m
- Check Also create “MLKView.h”
- Set the Location to the include/MyLibraryKit/ folder inside your MyLibraryKit project.
- Add to project:
MyLibraryKit
- Set your Targets to MyLibraryKitMobile. You can include it in Demo but Demo already includes the library so its unnecessary and the demo won’t properly represent the use of the library.
- Select Finish.
You’ll now have a new MLKView.m and MLKView.h file in your MyLibraryKit Framework group with the actual source files located in the include directory. Now all you have to do is #import
your new MLKView.h
in yourMyLibraryKit.h file and the view will be part of your library.
// // MyLibraryKit.h // MyLibraryKit // // Created by Jeffrey Sambells. // Copyright 2010 TropicalPixels. All rights reserved. // #import // Include your plugin related headers here... #import "MLKView.h
Testing and Developing your Library
To test your library without switching projects treat the Demo app as if it were another project–actually that’s exactly what it is. The Demo app target is already setup to include the library for you so you can start developing right away.
For example, to test the MLKView from the above example, you only need to edit the loadView
method inDemoViewController.m:
- (void)loadView { UIScreen *screen = [UIScreen mainScreen]; // Load your primary view here for the demo self.view = [[MLKView alloc] initWithFrame:[screen applicationFrame]]; }
as the static library framework has already been included at the top:
#import
If you build and run the Demo app target you’ll get a fullscreen MLKView view (which at the moment is just white since MLKView doesn’t contain any subviews or logic).
Including your Library in Existing Projects
For the purposes of these instructions I’ll assume that you’ve created a static library project called MyLibraryKit based on the iPhone OS Static Library template above.
- Open your iPhone app Xcode project.
- Drag your MyLibraryKit.xcodeproj file from the Finder and drop it into the Groups & Files tree in your app’s Xcode project window. In the confirmation dialog that appears, you can opt to copy the source into your project but depending on your setup I would highly suggest having a common place to store your libraries so you don’t end up with multiple copies everywhere. Once you’re happy with the settings click Add:
- Click and expand the disclosure triangle next to the MyLibraryKit.xcodeproj icon. You’ll see a list of all the products in your MyLibraryKit project (if they’re red it’s because you haven’t built the project yet–don’t worry).
- Click and expand the disclosure triangle next to your app’s Targets. Drag the libMyLibraryKit.a product from yourMyLibraryKit.xcodeproj to your apps Target’s Link Binary With Libraries build phase as shown here.
- Double-click your app Target (ExampleApp shown here) to edit the properties. In the General tab of the Target Info window, click the square + button below the Direct Dependencies list. In the sheet that appears, selectMyLibraryKitMobile and click Add Target.
- You will now see the MyLibraryKitMobile target appearing as a dependency under your app’s Target.
- Under the Build tab of your app’s Target Info window, edit the Header Search Paths to include the path to the include folder inside of the MyLibraryKit folder. If your path includes spaces be sure to wrap the path in “double quotes”. TIP: Make sure you edit this property for All Configurations in the dropdown, not just the active one.
- While in the same window (Build* tab of your app’s Target Info), also edit the Other Linker Flags to include the following flags: -ObjC and -all_load. This will allow the Objective-C categories in the MyLibraryKit static library to execute properly.
- Finally, build and have fun coding!
Leave your comment