Sharing Cocoa

Learn from my mistakes.

Sharing a Project with a Customer

Recently, I have finished a project for a customer. The project enables the customer to publish a set of images as an application and can be reused for other sets (creating a different application).

Although the customer is not a programmer both him and me wanted him to keep the project and submit his application directly to the App Store. That meant that I had to share a project with the customer that he could change (the image sets at least) and he would create the app and sign it to submit it to the App Store.

Requirements

Having worked in security for some years I try to follow the need-to-know principle and always prefer to decide what to share pro-actively than sharing all and remove the unwanted things. I do trust my customers, but in this case it made no sense to share the code, because it would be more overwhelming for a non technical person and any accidental change would result in unnecessary support time.

Also, I wanted to keep track of the project history in git, but that is another thing that makes no sense to share.

Finally, I wanted to allow my customer to compile and run the app both for the simulator and the devices.

Looking for solutions

The most obvious way to share the project without the source code is using a static library. I had never done one before in Xcode, but I could easily find some good resources on the web. By far Mostly Torn's was the best explanation, but it assumed that it would share a modified version of the project with the customer and that had some implications:

  • I had to make a full copy of the project and do some cleaning afterwards, like some text files that are for my reference or the git history. This could led to undesired results if I forgot to remove any file that wasn't meant to be shared.
  • If my customer cleaned all targets, deliberately or otherwise, it would end up with an unusable project, because the libraries would be deleted and couldn't be regenerated again.

I also attempted to add the library to the project, but couldn't figure out a way to include both the arm and the i386 versions, and wasn't able to create a fat static library from within Xcode (my fault for sure) although some solutions were available from the command line.

Final implementation

So, if you want to solve this problem too and this is what you got so far, you can try this steps and see if they fulfil your needs:

  1. Once your project is ready to be shared, create a new target for all the sources that you want to share in the static library and copy them to the compile sources build phase of that target.
  2. I also needed to include my precompiled prefix header file to the target configuration (prefix header setting), because of some header dependencies that were assumed.
  3. Build the static library for both the simulator and the device. This libraries will be created under build/Debug-iphonesimulator and
    build/Release-iphoneos
  4. Create a new project with Xcode. If this is an iOS application choose the View Application template (or the one that matches your project better.) This is the project that you will be sharing.
  5. Copy the application delegate sources to the new project directory (in the Classes subdirectory.)
  6. Copy the resources (xibs, icons, launch images, plists, etc.) to the new project directory and add them to the project by right-clicking on the resources Group and selecting Add -> Existing files...
  7. Copy the headers that are required for the main ViewController to the new project and add them to it by right-clicking on the Classes Group and selecting Add -> Existing files...
  8. Create a directory on the new project that is called lib and two inside of it that are called iphoneos and iphonesimulator.
  9. Copy the arm and the i386 versions of the library to the corresponding directories.
  10. Modify the information for the project so it contains the following settings:
    • Other linker flags -ObjC -lyourLib
    • Library Search Path lib/$(PLATFORM_NAME)
  11. Compile and test the new project, first on the simulator and then on the device.

Keep in mind, that your customer will have to edit the Bundle Identifier of the Info.plist of your shared project so it matches the distribution profile.

Want to share your thoughts?