Posts Tagged ‘iphone’

iPhone Development and Code Reuse

Saturday, January 9th, 2010

Software development is a passion of mine. My honours thesis was on Software Reuse, something that all software developers should strive to do. During me research I was led down the path of many different technologies to do with software reuse. One of those particular technologies was Software Libraries.

My pain today has been trying to work out a software reuse procedure for iPhone development. In some ways I have been very unsuccessful, but un the end I believe I have worked out a reasonable way to do it. Note that I have googled many different searches and have usually come up with no help. There were a few good tutorials which have been useful, and I have derived my procedure based on these posts…

Library

Step One: Create the library project

For simplicity I will keep out the SVN related stuff. I am in the process of creating my post on Subversion integration with my projects, stay tuned.

Jump into xcode and create a new window based application, call it MyLibrary for example. This is actually useful as we can use the project to test our library code as well.

Step Two: Create the static library target

Right click on the “Targets” node in the xcode project list. Select “add -> New Target…”.

Choose the “Cocoa Touch” option on the right, and the “Static Library” icon in the left pane. Call it “libMyLibrary”. When the information screen comes up, change the “Product Name” to “MyLibrary”. (note this can be changed later by right clicking the target and choosing “get info”.)

Step Three: Create some classes

To test the library lets create a new class (in the Classes directory). Select the NSObject as the super class, call it “MyClass.m”, and add it to the new target (by clicking the check box next to the “libMyLibrary” target).

Add some simple code, first the header…

#import <Foundation/Foundation.h>
@interface MyClass : NSObject
{
}
+(void)hello;
@end
And of course the implementation...
#import "MyClass.h"
@implementation MyClass
+(void)hello
{
	NSLog(@"Hello");
}
@end

Save the files.

Step Four: export the header as public

In the “Targets” node in the right hand list, click the “libMyLibrary” node. The filelist will now have your MyClass.h and MyClass.m files. You need to change the “project” role next to the MyClass.h file to say “public”.

Step Five: done with the library

For the moment…

Client

Step One: Create the project

Call it “MyApp”. Any more need to be said?

Step Two: Create a reference in the application to your library

This is a slightly tricky step. Basically all you need to do is in your library project there is a list on the right hand side showing up the top your library (MyLibrary) and nodes beneth it with classes, resources etc. Click and drag the “MyLibrary” icon (right up the top) over to your new project, drop it at the same place (where it says MyApp). Make sure the “copy” checkbox is not checked (you do not want to copy it, you just want it referenced). Click Add.

You may notice that underneath the reference you just created there are two items, MyLibrary.app and libMyLibrary.a.

  • MyLibrary.app is your actual app. You can safely ignore this for the imported project
  • libMyLibrary.a is the static library.

You will notice these correspond to the targets in the MyLibrary app.

Step Three: Tell your code where the header files are (this is for code completion to work)

  • Right click the “MyApp” icon at the top of that right hand list, go down to “Get Info”.
  • Click the “Build” section. This will show all the build settings defined for your project. The list is very long, so we’ll use the search box to narrow down what we see. Type in “header search” in the search box.
  • The field we are looking to change is the “User Header Search Paths” option. Double click the blank area next to it (which will enable you to edit the paths).
  • Click the [+] button to add another path
  • Double click the new path blank area to type in the path you want

This is where you need to reference the actual path of your “MyLibrary” project. In my case I have used the same directory for both the MyApp and MyLibrary projects, so I can simply type into this field…

../MyLibrary/

Out of interest I also select the Recursive checkbox as well.

  • Close that window

Step Four: Start Coding

Open up the “MyAppAppDelgate.m” file. If you have added the header include path correctly you should be able to add the following at the top of the file (just under the #import “MyAppAppDelegate.h” statement)…

#import “MyC

… and you should now see the auto completion kick in and see the remainder of the line…

#import “MyClass.h

… Of course you should now complete the line (#import “MyClass.h”)

Next you can add the following line of code in the applicationDidFinishLoading function (which is created for you). Modify it to say this…

- (void)applicationDidFinishLaunching:(UIApplication *)application 
{    
    [MyClass hello];
    // Override point for customization after application launch
    [window makeKeyAndVisible];
}

Build and run. You should see “hello” on the console. That was from our original library code.

Step Five: Add a linker reference and build dependancy on the library

For those that are following step by step and are a little savy may notice that…

a) the items under the MyLibrary.xcodeproj (which are the targets for the MyLibrary project) are both red. And…

b) we haven’t built the library yet.

This was done on purpose as we want the library to be built as a dependency on the current project. Of course you may not want this as part of your build process, but I like to keep my code sane, so rebuilding often means I need to check and fix bugs often. Not a bad thing. But before we add this dependancy lets tell the linker to link against our static library, then we can add the build dependency.

  • open up the “Targets” node in the list in xcode
  • You will see the Link Binary with Libraries node.
  • Drag the “libMyLibrary.a” from our imported project into this node.

Now we are ready to add the build dependency.

  • Right-click the “Targets -> My App” node and go down to “Get Info”
  • Click on the General button, up the top of that screen you should see the option “Direct Dependencies” box.
  • Click the [+] button
  • Click the libMyLibrary target
  • Click the “Add Target” button
  • Close the window.

Step Six: Build and run the project

Try building the project now.

The simulator should run, and the words “Hello” should be written in the debug console. Success :)

You will also notice the “libMyLibrary.a” target in our imported project is now black – hence its been built.

Changes to the Library

You can now add another method to your MyClass, get it to do something else. Save it.

Head back to your client project, use the new method, build and run. The library should now be rebuilt and the new method available immediately for use.

Conclusion

This is about the easiest method I have found through my research today to create a library of reusable code for the iPhone. Why I am unable to create a framework to be used in an iPhone app is a bit of a loss to me (thank you Apple for making this so hard). In my opinion, to foster reuse of code, the ability to create a framework and add it to a project far outweighs the eleven steps outlined above. C’mon Apple.