RSS

From commit to Testflight – Part 1

Recently I have received several requests to explain how to automate iOS builds from checkin to Testflight.  Since I have been using Jenkins to automate iOS applications for almost 2 years, I feel like it is time to share.  In this series of posts I will explain how I automate my iOS projects to perform the following steps:

  • Compile the App and build an IPA file
  • Execute Clang scan-build and fail when leaks are detected
  • Execute copy-paste detection and fail when infractions are found
  • Execute GHUnit tests with code coverage and fail when tests fail
  • Generate AppleDoc documentation
  • Upload the IPA to Testflight with a proper build number and commit history

Requirements:

  • A Mac OSX computer to serve as a Jenkins server or Jenkins slave.  Must have Xcode installed.
  • iOS App source code accessible from a common source code control system such as Git, Subversion, Perforce, etc.
  • The ability to download and install open source software.
  • A Testflight account with a team already configured.

Jenkins

For those of you who are not familiar with Jenkins, it is an open-source continuous integration server.  Jenkins is written in Java but can be used to automate almost anything.  Jenkins is backed by a vibrant community of developers who continually contribute bug fixes and new plugins. If you have never setup Jenkins on a Mac, you should begin by running the Jenkins Mac OSX installer which can be found on the Jenkins home page.  If you plan to use a Windows or Unix machine as a Jenkins master, you will have to configure your Mac as a slave machine.

Once you have Jenkins installed and running, you should use the Jenkins update center to install all of the necessary plugins.  You can access the plugin update center by clicking ‘Manage Jenkins’ and then clicking ‘Manage Plugins’.  Next, go to the ‘Available’ tab and begin checking the plugins you wish to install. I have broken the plugins down by function below in order to help you figure out which ones you need to install:

New Freestyle Job

After you have installed all of the plugins for the features you wish to implement, you’ll need to create a new freestyle job in Jenkins which will perform the automation.  If you plan to automate more than one App you would create a freestyle job for each App.  Create your job by clicking ‘New Job’ in the upper left, providing a job name, and choosing the ‘Build a free-style software project’ option.  I recommend not using spaces in your job names because they can cause some scripts to function improperly.

Once you have created a freestyle job for your App, you should configure the Job to connect to your source control system and pull the source code to the Job’s workspace.  Open your Job in Jenkins and click on the ‘Configure’ link on the left to access build settings.  You can setup your source control in the ‘Source Code Management’ section.  If you do not see an option for your source control server you’ll need to go install a suitable plugin.  The Jenkins job configuration page also has a ‘Build Triggers’ section which will allow you to configure source code polling.  I usually enter something like ‘*/5 * * * *’ in the ‘schedule’ field so that Jenkins will poll my source control server for changes every 5 minutes.

After you have configured your Job to pull your source code you should execute a build by clicking ‘Build Now’ on the left side of the screen.  Jenkins should execute successfully (blue ball instead of red) and your source code should now be visible in the Job’s workspace.  You can confirm this by clicking the ‘Workspace’ link on the left side of the Job page.  If you see your code in the workspace you are ready to move onto the next step.  If you do not see your source code, try clicking on a failed build and viewing the console output for clues.

Compile the App and build an IPA

XCode Preferences - Downloads

A note for XCode 4.3 users:  Apple recently began distributing Xcode via the Mac App Store.  When Apple made this change they also split XCode into several separately installed components.  Many of the tools detailed in this post require the ‘XCode command line tools’ download.  You can install this download by opening Xcode on your build server and going to ‘Preferences’.  Once you have opened XCode preferences, click the ‘Downloads’ tab and install the ‘Command line tools’ download.  After the ‘Command line tools’ are installed you should test them by opening Terminal on your build server and execute the ‘xcodebuild’ command.  If you get an error stating that no /Developer directory could be found, execute the following command from Terminal: sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer

The most basic Jenkins/iOS continuous integration system should at least compile the App.  This ensures that commits made by developers are not missing files which would cause headaches for the rest of the team.  There are currently two ways you can configure Jenkins to compile an iOS App.  You can either use xcodebuild directly from an ‘Execute Shell’ build step or use the SICCI for XCode plugin.  I have been using the SICCI for XCode plugin for about a year and have found that it is reliable and easy to use.  This guide will assume you are using the SICCI for XCode plugin.

The SICCI for Xcode plugin requires access to your XCode workspace/project so that it can list out the targets/schemes for your App.  Because of this, you will need to make sure that Jenkins is happily pulling your source code into the workspace before you move on with this step.  Once you have confirmed that your source code is being pulled properly, you will need to go to the job’s ‘Configure’ page.  On the Configure page locate and click the ‘Add Build Step’ button.  Once you click the ‘Add Build Step’ button you should see a popup with a list of build step types.  You should choose ‘SICCI for Xcode’.  Jenkins will add the SICCI for Xcode build step and you should see a list of the build targets in your project.  If you do not see your project folder and a list of build targets, your source code is probably not in the job’s workspace.

To have the SICCI for XCode plugin compile your App you should change the platform to ‘iOS’ and check the checkbox next to your App’s main target or scheme.  Once you check a target or scheme, the SICCI for XCode plugin will display several options.  You should check ‘clean before build’ and ‘create IPA’.  If you wish to have the SICCI for XCode plugin also zip up the App’s DSYM, you should also check ‘archive App’.

You may also wish to change the SICCI for XCode ‘Filename template’ to something more simple.  I usually use something like ‘AppName_<BUILD>’ where AppName is anything you want.  The <BUILD> token will be replaced automatically with the Jenkins build number during a build.  I also recommend that the you don’t use spaces in the ‘Filename template’.

Next, save your configuration changes by clicking the ‘Save’ button and run your Job by clicking the ‘Build Now’ link.  If your job passes, you are ready to move onto the next step.  If you job fails, you should click the failed job link on the left to view the job details page and then click the ‘Console Output’ link.  In order to see the entire console output you may need to click the ‘Raw’ link.

The job console will show the typical build output from xcodebuild and will show any compile errors that may have occurred.  If you still can’t figure out how to get your code to compile you should try running xcodebuild directly on your project from your local workspace using Terminal.

In the next part, I will explain how automate GHUnit tests in Jenkins.


 
9 Comments

Posted by on April 1, 2012 in Code, Software, Uncategorized

 

Tags: , , , , , , , , ,

Top 11 ways for developers to know that Apple is not following Steve’s vision

Here are the top 11 ways for iOS developers to know that Apple has strayed from Steve’s vision:

  1. Apple lets operators put shitty Apps on new Apple devices
  2. Apple allows third parties to create their own App stores
  3. Apple offers a system of global plugins to replace the keyboard and so on
  4. Apple does away with App submission reviews
  5. Apple starts selling Antivirus definitions for iOS devices as a monthly subscription
  6. Apple releases a new magic mouse which has 2 buttons
  7. Apple starts using hair metal for background music in their commercials
  8. iPad3 gets a PS/2 plug and a parallel port
  9. iOS 6 is built on Adobe flash
  10. Apple sells products for a loss to gain market share and hopes to make it up later
  11. Upon opening an Apple product you are presented with the following message: “Designed in China”
Thanks to Santiago Lema (@blackjack75) for coming up with half of this list during a twitter conversation.
 
Leave a comment

Posted by on August 24, 2011 in Uncategorized

 

Objective-C copy paste detection using Jenkins

I recently configured a Jenkins job to execute CPD (copy paste detector) using PMD against an iOS project. For those of you who are not familiar with CPD, it is a tool which can analyze a code base to identify large chunks of code that have been duplicated.  CPD is capable of ignoring differences in whitespace and literal values so that you can find similar code and not just identical code.  Because of this, CPD is an invaluable ally in the constant battle against bad coding practices.

CPD supports Java, JSP, C, C++, Fortran and PHP out of the box and can be extended by writing language definitions in Java.  In order to get the best results for iOS projects, I have compiled a simple Objective-C language definition based on an Objective-C JavaCC grammar which was written by a fellow named Mike Hall.

If you would like to setup CPD execution within your Jenkins iOS builds, you will need to first download CPD from this link:  http://sourceforge.net/projects/pmd/files/pmd/4.2.5/

You will also need to download my generated Objective-C CPD language definition from github: https://github.com/jkennedy1980/Objective-C-CPD-Language.  NOTE: It is best to download the entire project as a zip file because I have seen issues when downloading the individual release jars from github.

Once you have all the jars extracted from their zip files, you’ll want to copy the PMD and ObjCLanguage-0.0.7-SNAPSHOT jars to a location on your Jenkins box.  Next, go into your Jenkins build’s configuration and add a new ‘execute shell’ build step.  You’ll need to tailor the actual command to your project, but here is an example of what the command should look like:

java
-Xmx512m
-classpath pmd-4.2.5.jar:ObjCLanguage-0.0.7-SNAPSHOT.jar
net.sourceforge.pmd.cpd.CPD
--minimum-tokens 100
--files [Path to XCode project classes]
--language ObjectiveC
--encoding UTF-8
--format net.sourceforge.pmd.cpd.XMLRenderer > cpd-output.xml

Command Breakdown

  • java – CPD is executed using the java application.  Make sure you Jenkins box has a JRE installed.
  • -Xmx512m - This parameter tells the JRE to allocate 512 Mb of memory for the JVM.  If your project is large and you are getting out of memory or heap errors, you may want to bump this number up.
  • –classpath pmd-4.2.5.jar:ObjCLanguage-0.0.7-SNAPSHOT.jar – This puts the PMD jar and the Objective C language definition onto the JVMs classpath.  The paths to the 2 jars may need to be absolute paths.
  • net.sourceforge.pmd.cpd.CPD — This is the main class (CPD itself) that is executed from inside the PMD jar by the java executable.
  • –minimum-tokens 100 – Configures the minimum size for blocks considered to be duplicate
  • –files [path] – This parameter tells CPD which files should be scanned for copy paste violations.  You can provide more than one –files parameter if needed.
  • –language ObjectiveC – This tells CPD to load my custom Objective-C language definition.
  • –encoding UTF-8 – This allows you to specify which encoding you would like to use.  [optional]
  • –format net.sourceforge.pmd.cpd.XMLRenderer – This tells CPD that you would like to output the results as XML.  You will need to use XML if you want to publish the results within Jenkins using the plugins mentioned below.
  • > cpd-output.xml – This takes all the XML output by CPD and writes it into a file named cpd-output.xml.  You can name the output file whatever you want.

Jenkins Plugins

Once you have tailored the command above, you can install the Violations or the DRY plugin from the Jenkins update center.  I used the Violations plugin which allows you to configure limits that define when the build should be unstable or cloudy within each job’s configuration.  You’ll need to be sure that you setup the Violations or DRY plugin’s configuration values so that they can find the output CPD XML file.

Once you have configured everything properly, you should see a Violations section within your job that lets you browse the duplicated code blocks that were found within your code base.

I hope you find this post helpful and that CPD helps you remove all your duplication…or your co-workers’ duplication :)

Troubleshooting

If you are receiving parsing errors in your output, you can now( as of version 0.0.5) add ‘-DObjC-CPD-LoggingEnabled=YES’ after java in the CPD command to enable some additional logging.  The new logging will print out each file’s name as they are processed and show files names when parsing exceptions are generated.   If you are redirecting the output to an XML file as I have shown in this post, you will have to open the XML file to see the logging output.  Here is an example with logging enabled:

java
-DObjC-CPD-LoggingEnabled=YES
-Xmx512m
-classpath pmd-4.2.5.jar:ObjCLanguage-0.0.7-SNAPSHOT.jar
net.sourceforge.pmd.cpd.CPD
--minimum-tokens 100
--files [Path to XCode project classes]
--language ObjectiveC
--encoding UTF-8
--format net.sourceforge.pmd.cpd.XMLRenderer > cpd-output.xml

WARNING: by enabling logging the XML output will be invalid. Logging should only enabled to assist in troubleshooting.

 
47 Comments

Posted by on May 17, 2011 in Uncategorized

 

Homebrew Whiteboard

Homebrew Whiteboard

How would like to have a HUGE whiteboard so that you could sketch diagrams while working on a project?  I have always found that having a huge white board which lets me look at my writings from far away helps me focus on the problem at hand.

I looked into commercial whiteboards and I was surprised to find how expensive they can be.  You can expect to spend more than $200 for a cheap commercial whiteboard.  If you’re like me and want the whiteboard without letting go of your dough, you should know that you can build simple whiteboards for a fraction of the cost from materials which are available at your nearest home improvement store.

The most important part of this project is the whiteboard itself.  Some commercial whiteboards are made of a material called melamine.  Luckily, you can buy a 4 x 8′ sheet of low grade melamine from a home improvement store for about $12.  You’ll need to wander over to the paneling isle and locate “White panel board”.  It should be completely smooth and will typically be 1/8″ thick.  The home improvement melamine is not as smooth as expensive whiteboards but it gets the job done and the markers wipe off easily when needed.

Now 1/8″ is not very thick, so this large sheet of melamine will be very wobbly.  I decided to glue the sheet of melamine to a sheet of inexpensive 1/8″ hardboard.  A 4′ x 8′ sheet of hardboard ran me $6.75 and looks just like the sheet of melamine minus the shiny white side.

In order to glue these 2 sheets together, I used a single tube of liquid nails which ran me $2.75.  I positioned the whiteboard face down on a soft surface and spread many small beads of liquid nails in a crosshatch pattern on the back and along the edges.  Once the entire tube of liquid nails was spread out on the whiteboard, I carefully placed the hardboard onto the glue and positioned it so that the edges aligned nicely. Next, I used a scrap board to apply firm pressure to the sheets and worked my way around the entire surface.  After I was satisfied with the amount of pressure I had applied, I allowed the liquid nails to dry for 1 hour.

So far, I have spent $25 on materials and $10 on dry erase markers.

Here are some shots of the finished product:

4' x 8' is a lot of whiteboard

4' x 8' is a lot of whiteboard

Next, I’ll be working on a convenient way to hang this monster on my wall.  Check back for details soon.

 
Leave a comment

Posted by on April 27, 2011 in Design, Homebrew

 

Tags: ,

The RGB Design Model

Design can be defined as “satisfying a set of requirements, subject to constraints”.  Typically, large design projects will have many constraints which can be divided into many individual subject areas such as: Legal, Marketing, etc. As a strategy to manage complexity, many companies organize people into departments with the belief that it will increase focus and will allow their employees to become experts within a department.  When these departments are asked to work together to design software, turf wars can occur and bring design and development to a halt.

RGB Design Model

In order to help you understand this phenomenon a bit better, lets frame up an artificial scenario.  Suppose that you work on a large design team for a large company.  All of your designs must be approved by many different individuals who have unique interests in the final design.  Lets assume that these interests are controlled by separate departments such as: usability, legal, or branding.  For simplicities sake, lets assign a color to each of these departments: red, green, and blue respectively.  There is no significance to the number of departments/colors.

Now lets assume that every time a representative from the red department reviews a design, that they are viewing the design through a red filter (red sunglasses in the diagram).  A red color filter only allows red light through which renders the viewer incapable of seeing other colors.  If the color red represents legal issues, the person wearing the red glasses will see only the red(legal) issues and will ignore problems with the other colors. Likewise, when this individual describes what changes are necessary, they are constructing their idea of a perfect design according to their red filter.  Due to their bias toward red(legal) issues, their mental image of an ideal design will be primarily red and will not take into account any other colors.  For now, lets refer to this phenomenon as ‘color bias’.

Color Bias

Every person who has a color bias, also holds a mental model of an ideal design according to their bias.  For example, individuals from the legal department would likely fill every page with legal disclaimers to ensure users have no legal recourse against your company. Obviously legal issues are important, but it would be unwise to clutter the user interface with hundreds of lines of disclaimer text.  If you allowed this to happen, your users may be frightened and not use your product.

There is no such thing as an non-biased reviewer

As a designer, you need to assume that no one is capable of providing unbiased feedback.  This is due mainly to the fact that everyone designs for themselves.  You need to remember this so that you can use the same “filters” as above to filter the incoming feedback.  You need to pass any feedback from the green department through the green filter. This will allow you to view on the feedback which concerns the green department and remove all personal opinions or feedback regarding other issues.

The Designer

As a designer, it is your job to balance all of the constraints and come up with a design that makes each person reasonably happy.  Simply being aware of each persons biased ideal design gives you additional insight and allows you to find a balance between all of the constraints placed upon the design.

Presenting your design for feedback

Coming Soon!


 
2 Comments

Posted by on April 24, 2011 in Software Design

 

Tags: , ,

Myth: Consistency is everything

A myth that I seem to continually confront in software design is that applications should be consistent within their application family.  A family of applications will typically include a full-featured website, a mobile website, and one or more native applications which provide several of the same core features.  Some application designers seem to misunderstand what it means to be consistent and begin enforcing things like color palettes and verbiage.

It is much more important that user interactions are consistent across applications than look and feel.  Each of your applications should allow users to use a single login and access their data in the same way.  You should also ensure that each of your application’s navigation hierarchies are similar.  This allows users to find what they are looking for even if it is the first time they have used the application.  You do not want to force your users to adapt to every individual application.

It is also very important that you pay attention to the little details such as form inputs.  For example, you would not to accept a date on one screen using a MM/DD/YYYY pattern and then accept another date on another screen using a DD/MM/YY pattern.  Your applications should never surprise your users.  In fact, you should work hard to make it possible for users to never have to deal with date formatters.  This is easily accomplished by progressively enhancing date fields with a date pickers.

Each one of your applications needs to have its own personality.  By enforcing limits on things like color palettes and verbiage you are eliminating possibilities to improve your applications.

 
Leave a comment

Posted by on April 24, 2011 in Design, Software, Software Design

 

Tags: , ,

Troolean ~ I can haz three states

Have you ever seen a web form that has a Yes or No radio button where NOT choosing either option is valid?  I once worked on a project that was littered with these Yes or No questions which, due to legal reasons, needed to track whether or not the user actually made a selection.  In order to store these Yes, No, or No Selection answers in the database, the administrator decided to store the values in a small int with the following expected values:

  • 0 = User selected No
  • 1 = User selected Yes
  • Null = User did not make a selection

You can see that fields which are defined this way are actually storing two values: Whether or not the user made a selection and if they did make a selection, the value they chose.  This should have been the first indication that storing data like this may not be clear to others.

To make matters worse, the Java developers charged with representing this data in an Object hierarchy decided to store this same data using Boolean fields.  They were forced to use Booleans (big ‘B’) because Boolean fields can be null whereas primitive booleans can only be true or false.  The possibility of a null state is what allows Boolean fields to hold the third “No Selection” value.  The intent of the Boolean wrapper class in Java is not to give developers a nifty three-state boolean.  Rather, the Boolean class was designed to allow a primitive boolean which does not extend Object to be wrapped by an Object when an actual Object is required.

The developer of the class hierarchy mentioned above had two other options which could have been used to solve the problem of storing the additional state with the Yes or No value:

  • Use an enumeration – An enum could easily contain Yes, No, and No Selection.  This would have been much more clear to future developers.
  • Store the information in two separate fields – one field for the Yes or No selection and another field to store whether or not the user made a selection.

Unfortunately, the developer opted to introduce a Troolean or tri-state boolean into the system.  The problem with Troolean fields is that you end up having to do a null check everywhere you reference it in case the user did not make a selection.  This propagation of code reeks of incorrectness.  This incorrectness can be further confirmed by looking at the definition of null on wikipedia (link):

Null means “nothing” or without value or consequence.

Did you notice “without value” in the definition above?  Trooleans place value and meaning into a null or non-value.  This may not seem like a real issue at first but consider all the extra code and confusion that Trooleans force you to introduce into your code base.  Its only a matter of time before a new developer introduces a NullPointerException into the system because they didn’t expected null to mean something.  Also, what happens when you need a fourth state?

When designing Objects, it is super important to store that data in a way that is logical, clear, and does not cause any loss of precision.  Trooleans stink because they are illogical, introduce defects, and cause code propagation…don’t use them.

 
7 Comments

Posted by on May 19, 2010 in Code, Software, Software Design

 

Tags: , , ,

 
Follow

Get every new post delivered to your Inbox.