Third Party Continuous Integration for iOS

Until recently if we wanted to have continuous integration for your iOS project we needed to create your own solution, normally it involved the creation of a Jenkins instance in a MacMini. Now with  Xcode 5 and the OSX Server we also have an official Apple alternative in the form of Xcode bots, but you still need fork for your own server.

Luckily in  the last months a lot of third party services are starting to appear that provide a good service, for private repositories and with decent prices.

  • Travis-CI, a big player in the open source projects, providing automatic building for thousands of projects in Github, it now has a commercial solution for private repositories. One of the big advantages is that it’s not limited to iOS you can build almost anything on it.
  • Buildozer.IO, a bit cheaper than Travis but only with support for iOS and Android projects.
  • MacBuildServer, still in the beta phase and only for open source projects.




The fine guys from CocoaPods now provide us CocoaDocs a tool to search and view documentation for most  the libraries that are available in their pods repository.

The best thing is that if you have a library and its configured to to be a cocoapod the documentation is automatically generated for you.

The index page is base on the file in the repository and the class documentation is generated from the code comments in you classes.

You just need to follow the AppleDoc syntax.



YouTube Videos

Until recently to display YouTube videos in iOS or Android you need to use or an external player or some kind of Web view. The first approach made users leave your app and the second one normally was slow and buggy.

Recently Google finally launched an YouTube Player API for Android.

Unfortunately there isn’t a version for iOS but some nice fellows developed LBYouTubeView. This component is a MPMediaPlayerController subclass that is capable of displaying YouTube videos URL. It manages this by requesting information of the video from YouTube and then getting an URL to the media stream that can be played using a MPMediaPlayerController. Not sure if it’s 100% reliable and legal but it does the job!


The missing Xcode plugin manager

Alcatraz the missing Xcode plugin manager.


Generic sharedInstance iOS implementation

One very common pattern when implementing Objective C singleton objects is the sharedInstance method.

Because I was a bit tired of repeating this code in several of my classes I decided to implement a Xcode Code Snippet that can be reused everywhere.

+ (instancetype) sharedInstance {
    static id _sharedInstance = nil;
    static dispatch_once_t _onceToken;
    dispatch_once(&_onceToken, ^{
        _sharedInstance = [[self alloc] init];
    return _sharedInstance;

As you can see simple code that can be apply to any object.


Good Macros

Here is a good write up, from Mike Ash, about the preprocessor and the proper way of writing macros. And here is a good example of a better Assert macro.


Application Icon Template

With this fabulous photoshop templates you just need to create the icon, them let it create all the versions you ever need of it.


Link to your App

Do you ever struggle to do a proper link to your application on the Application Stores? Where do I get that brand logo? Is it the right size? What’s the link to my app?

Say hello to the link makers kindly provided by Apple and Google:

And after you have done this you can go the extra level by adding this metadata to your app website.


MOGenerator integration in XCode

MOGenerator is a command line utility that generates NSManagedObject class files based on you model files. It creates a NSManagedObject derived class for each entity of your model.
The utility can be run manually every time you change your model files (.xcdatamodeld).
This manual process can easily be forgotten, and ideally we want it to automatic regenerate the files every time you change the model.
We can use XCode Build Rules to add an extra step on the processing of model files. So every time you change them XCode itself will run MOGenerator and generate new files.
To do this follow this steps:

  • Create a folder inside your project called MOGenerator and copy the mogenerator binary file inside. I normally place it inside a folder called Libraries/MOGenerator inside the project. If you are a GIT user you can setup it as a git submodule in your project .
  • Open the Project settings view, select your target, open the Build Rules tab.
  • Add two new build rules, one for “Data model files” and another for “Data model version files” this is done be selecting the Process dropdown.
  • Change the Using dropdown to Custom Script
  • Add the following code to the script text box.  (Here is a list of all XCode environment variables).
  • For Data model files:
mogenerator --model "${INPUT_FILE_PATH}" --output-dir "${PROJECT_DIR}/XXXXX/Source/Model" --template-var  arc=true
  • For Data model version Files:
mogenerator --model "${INPUT_FILE_PATH}" --output-dir "${PROJECT_DIR}/XXXXX/Source/Model" --template-var  arc=true
  • Change the output-dir parameter to your specific generation path. This is the path where mogenerator will save the files.
  • Set the Output Files to the following values:
  • Data model Files:
  • Data Model Version Files:
  • Next step is to enter the name of the Class for your entity. Entity name and Class have to be the same
  • Build the project and check if you don’t get any failures in the build process.
  • Any entities which are new (that is, which MOGenerator has not encountered in a previous build) will need to be manually added to your project. This step only needs to be performed when you have new entities, not during updates to existing entities.
  • If you have multiple targets in your project which utilize your data model, you’ll need to add these build steps for each target to make sure the model is kept up to date for each target. If this is the case you could consider to move the script commands to an external script file and refer to it on the shell script in XCode.

XCode Build and Version numbers based on GIT

Since XCode 4.3 you can find in the Summary Tab of your targets the following fields: Version and Build.

  • Version should be used to identify the “comercial” version of your app, something like 2.0, for more details on how to proper change version numbers have a look at
  • Build should be a internal number to unique identify versions of your app.

Normally Version numbers are changed manually every time you prepare a deploy of a new app but Build numbers should change automatically every time you do a new build.
One initial idea could be using the current GIT commit hash number to fill the Build number, but there is a issue here: Apple wants that this number always increases from version to version.
So to go around this I decided to use the number of commits existing on the git repository. This is a number that always goes up while you are developing.

But how to integrate this with XCode and better yet make it automated?

Just follow these instructions:

  • In your Xcode project, create a new Bundle target called UpgradeVersionNumber.
  • Select that target and add a new Run Script phase to the Build phases.
  • Insert the following script in Run Script phase, replacing the path to your git executable if need be:
    # grabbing version number from plist.
    COMERCIAL_VERSION=`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" Info.plist`
    # grabbing number of commit in developer to create a version number
    BUILD_VERSION=`git rev-list HEAD | wc -l | tr -d ' ' | tr -d '\n'`
    # grabbing commit hash from git
    GIT_VERSION=`git show --abbrev-commit | grep '^commit' | sed 's/commit //' | tr -d '\n'`
    echo "#define GIT_VERSION $GIT_VERSION" > InfoPlist.h
    touch Info.plist
  • Make UpgradeVersionNumber a dependency of your main target.
  • Add the “InfoPlist.h” to your .gitignore file.
  • In your main target’s build settings:
  • Turn on Preprocess Info.plist File
  • Set Info.plist Preprocessor Prefix File to InfoPlist.h
  • In your main target select the summary tab and on the Version Number field write BUILD_VERSION
  • Now each time you build the main target, the version will be populated in the build’s Info.plist.
  • As an optional step you can also add a custom entry to the plist called GitVersion and set it with the value GIT_VERSION.
  • Now when the script runs you also gonna get the Git hash number for the build on the Info.plist.
  • You can then use the following code to display it inside the app
[NSBundle mainBundle] objectForInfoDictionaryKey:@"GitVersion"];