If you manage a number of iOS applications that have a lot of the same features you may want to consider building a framework that can be used across all of them. There are a couple ways to do this, the most common would be to build a static library.
A great solution for creating a living framework that is worked on my multiple people is to create a sub-project. This means that we’ll store all of the re-useable code in the sub-project and embed it into the projects for all of our apps. This works especially well if you are using GitHub across all of your apps. I’ll show you how to add the sub-project as a submodule in Git allowing the sub-project to be modified as often as possible, then when you have to update your project with the most recent fixes you just pull the latest code from the sub-project and your master project is automatically updated.
Create the Static Library Project
To start we need to build the sub-project that will contain all the reusable code for our Framework. Create a new project from the “Cocoa Touch Static Library” template as shown in the screenshots below.
When saving your project, ensure that the “Create local git repository for this project” is checked, we’ll need this later when we want to automatically update our parent project with the latest code from the framework project using Git submodules.
Next you’ll need to modify the copy files section within the target Build Phase so the library can be accessed by the project that includes it. Remove “${PRODUCT_NAME}” from the Subpath so only “include” remains.
We’ll need to add all of the assets within the Framework into a Resource Bundle. Normally all of your assets are stored in the projects “main bundle” but for another project to access the assets using a library the best way is to store them in their own bundle. Resource Bundles should store all your images and nibs (XIB). Add a target to the library project using the template “Bundle”. From the “Build Settings” of your library project click the “Add Target” button.
After the Resource Bundle is added we need to fix it’s architecture properties because by default Xcode adds it as a Mac OS X architecture. Navigate to the “Build Settings” of the Resource Bundle and change the “Base SDK” to the “Latest iOS” option.
Below I’m adding a new UIViewController named “AdViewController”. This is going to be added to the Framework project and later we’ll access this class within the parent project. This will show you that you can add any class / SDK you wish to your Framework allowing you to access or extend it within your parent project. First we’ll create a new Objective-C class which will be a subclass of UIViewController.
Ensure that the new class is only being added to the “MyFramework” target, not the bundle. We’ll add the nib (XIB) to the Resource Bundle separately, we don’t want our .h or .m files in the Resource Bundle since it doesn’t know how to handle them when compiled.
Navigate to the new “AdViewController.xib” file and check “MyFrameworkBundle” under the “Target Membership” on the right.
Next we want to add our objects to the nib (XIB). Drag in a UILabel and change it’s text to “Hello Ad Framework”.
Go to the “Build Phases” section and add the “AdViewController.xib” to the “Copy Bundle Resources” and in “MyFramework” add “AdViewController.h” to the Copy Files to ensure that these files will be accessible to the parent project.
Lastly commit all of the changes we’ve made to Git. Select “File > Source Control > Commit…”.
That’s it our static library Framework is complete. Next let’s look how to incorporate this framework into an everyday project.
Create the Parent Project
You may already have an existing project to add your new Framework into but we’re going to assume that you’re starting a whole new project and the first thing you are going to do is add your Framework that contains all of the reusable classes you’ll use in your new app. Start out by creating a new “Single View Application”.
Same as with the static library, ensure that the “Create local git repository for this project” is checked, we need it to be able to add the Framework as a submodule.
Let’s add the Framework as a Git submodule. Since we’re adding it as a submodule, anytime that the Framework has been updated all you’ll need to do it do a “git pull” from the submodule and your parent project and any other projects will be all be up to date without having to go into each one and cut and paste all the changes. So if you have 10 apps that all use your Framework and you fixed a bug with the Ad class or needed to update the latest third party SDK you use, make the change in your Framework, then open each of your apps, pull the latest Framework code, recompile and you’re ready to release your update to the App Store.
Navigate to the directory of your parent product using Terminal and type “git submodule add ../MyFramework” and press enter. This assumes that your Framework is stored locally. If you are using GitHub or BitBucket, point to the address of your repository.
The Framework project will be added to a sub-directory under your parent project folder. Next, drag the Framework project file (.xcodeproj) into your parent product dock, as shown below.
Edit the parent project scheme to make it build the Framework’s project targets first. Edit the scheme and under the “Build” tab click the plus at the bottom and add the library target and library resources target. Select all of the Frameworks Targets and click “OK”.
Link your Framework library file to your parent project. This is done very similar to how to include Frameworks like the “AudioToolbox.framework”. Select your parent project target, and click the + button under the “Linked Frameworks and Libraries” section, then choose the .a file associated with your Framework.
To include the Resource Bundle, expand the “Products” folder from the Framework and drag the “MyFrameworkBundle.Bundle” into the “Copy Bundle Resources” section under the parent project target. Don’t mind that the colour of the two files under the products folder are red, they will look normal once they are compiled.
Add the Framework targets into the “Target Dependencies” of the parent project so they will be compiled first before your parent product is compiled. If this isn’t done your project won’t know where to find the classes you are referencing.
Update the header search paths of the parent project. Go to “Build Settings” of the project and look for “User Header Search Paths”. Then set the target setting to “$(BUILT_PRODUCTS_DIR)” and select “Recursive”. This will be the location where your parent project will pickup the headers (.h) files of the Framework.
Using The Framework
We’ve integrated the Framework into our parent project, now we’re ready to use the classes within it. This should be very straightforward because we can leverage the classes just like you would from within your project.
First import the header at the top of your implementation file.
[syntax_prettify linenums=””]
#import “AdViewController.h”
[/syntax_prettify]
Then add the following code to leverage the Framework Resources Bundle and present the AdViewController within the app.
[syntax_prettify linenums=””]
NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:@”MyFrameworkResources” withExtension:@”bundle”]];
AdViewController *adView = [[AdViewController alloc] initWithNibName:@”AdViewController” bundle:bundle];
[self.view addSubview:adView.view];
[/syntax_prettify]
Once completed your code should look like this.
When you run the sample project, the output should show the AdViewController.
I hope this tutorial helped you to create your own Framework. Remember the advantage of embedding it as a sub-project allows you to view the code for the Framework while you’re using it and adding it as a Git submodule makes it really easy to keep your parent products up to date with the latest code for the Framework. Now go create your own Framework with all of the amazing classes you have created and want to reuse in every new app you create.
Grab the Source Code to this tutorial to help you debug any issues you had, but try to follow the tutorial yourself so you can learn all of the steps to ensure you know what each one does.