Ray Yamamoto Hilton
Freelance Mobile Architect & iOS Developer in Melbourne, Australia
~

Cardola - Virtual Hotel

Cardola develop and install modern solutions to in-room concierge & room services. This iPad-based app integrates with hotel’s existing billing services, room service and shop as well as providing local weather, tourist information, news and events. The app is primarily to be deployed onto hotel-managed devices but will eventually be available as a public download.

A public version of this app has just been made available for the Mayfair Hotel and is available on the iTunes App Store

Hood

Discover the wealth of digital content floating around you that would otherwise be trapped within networks you never use. This project aims to aggregate and organise local information into a smart guide that is greater than the sum of its parts.

Screenshot 1 Screenshot 2 Screenshot 3 Screenshot 4 Screenshot 5 Screenshot 6 Screenshot 7 Screenshot 8

Chromatic

A colourful, touch-reactive toy. Just touch the screen and watch the big, bright particles light up the screen and react to your swipes. Multiple touches introduce a centre-of-gravity that causes your particles to swirl around.

This was a personal project where I brought together some knowledge of OpenGL, from my days at digital agencies in London, on to modern devices such as the iPhone 4S and the iPad 2. This app is very graphically intensive and involves plotting a large number of particles using a meta-ball technique. The main aim of this app was to show that a seemingly complex app could be designed, built and deployed in under 2 months by constraining scope and focusing on user experience.

The app has just been released and is available on the iTunes App Store

Metlink

The Public Transport Victoria iPhone app is the one-stop-shop for Victorian public transport information and is free to download from the iTunes Store.

Dial - Community Radio

Listen to Australian community radio stations based on location, genre and community and extend the experience through the included social media links. Download it from the iTunes App Store for free.

DIAL is your portable entry point to Australian community broadcasting! Australia is home to hundreds of community radio stations that all enhance the diversity of national media and contribute to an inclusive, cohesive and culturally diverse society.

Using git to deploy

I’ve recently started using Git to deploy to my servers. Anyone who has used Heroku would be familiar with this technique and it feels kinda cool to be able to think of your different environments as just git remotes. I can’t vouch for the appropriateness of this technique in the general case, but I just wanted to make a note on what I’ve found to work for me. Hopefully, others may find this useful.

So, I use GitHub as my main source code repository, but I set up a second repository on the server I want to deploy to, normally in my home directory. First create an empty Git repo:

1
$ git init --bar ~/git/my-repo.git

To trigger a deployment on a push, we define a post-receive hook in this new repository. Hooks allow the you took invoke behaviour on a variety of git events, in this case we are interested in when the repository has successfully received a push.

1
$ vi ~/git/my-repo.git/hooks/post-receive

This is just an example, but the contents of the post-receive hook might look like this for a rack/passenger based web application:

1
2
3
4
5
6
7
8
9
#!/bin/bash

cd /var/ww/my-site
unset GIT_DIR
GIT_WORK_TREE=/var/ww/my-site git pull
GIT_WORK_TREE=/var/ww/my-site git reset --hard
GIT_WORK_TREE=/var/ww/my-site git submodule update -i
bundle install
touch tmp/restart.txt

Of course, this file can contain whatever you want, just make sure you set the executable bit on the file:

1
$ chmod +x ~/git/my-repo.git/hooks/post-receive

All that remains is to push your local repository to the new git repo on your server:

1
2
$ git remote add prod ray@my-server.com:~/git/my-repo.git
$ git push prod master

This is just a simple example, but because you are executing a script on the server, you can basically perform any functionality you like. I don’t know whether this would be a good idea in a large-scale production environment, but the key here is to make the deployments as simple and easy as possible to encourage smaller and more regular changes. Backing it with git enables a basic form of rollback, but anything that is not controlled by git, i.e. database schema state, will still need to be managed separately.

PlayUp - Where Sport Gets Social

PlayUp is a Melbourne-based startup who are bringing sports and social networking together. I, along with some of the top names in development in Melbourne, were brought together to work on their iPhone app.

The app has just been released and is available on the iTunes App Store.

Home screen Add friends View a match Chat with friends View live matches

Control XCode builds from Ruby

Previously I had created an Xcode plugin for Hudson to allow you to configure and invoke builds directly. Although this worked for some cases, there are a few projects where the build process is more complex or non-standard enough to force me back to scripting things manually. Rather than update the plugin to try and cope with every esoteric use case, I decided to flip things around and simple create a ruby-wrapper for Xcode. This allows me to take what i need and create a custom Rakefile to control the build process.

The aim of this gem is to provide an object model for navigating the project structure and be able to invoke some common types of modifications. I aim to gradually add more functionality to this gem as I come across new use cases.

The source is available on github, but it is available to install from ruby forge by using the command:

$ gem install xcoder

A simple use-case would be to find the only project in a directory, update the project’s build number and then invoke a build:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Find the first project in the current directory
project = Xcode.find_projects.first

# Find the target called "TargetName"
target = project.target(:TargetName)

# Find the configuration called "Debug"
config = config.config(:Debug)

# Update the build number
config.info_plist do |info|
    info.version = ENV['BUILD_NUMBER']
    info.save
end

# Clean the build for this target's configuration 
config.clean

# Build the target using this configuration
config.build

# Create an IPA for this target's configuration signed using the provided identity and embed the provided profile
config.package :sign => 'iPhone Distribution: Developer Name, :profile => 'Provisioning/ProfileToEmbed.mobileprovision'

It’s early days yet, but I plan on adding support for OCUnit => JUnit output mapping (like the xcode-hudson-plugin) as well as loading provisioning profiles from the file system and generally manipulating the project file. Please send issues/feature requests to the Xcoder page on github

Yellow Pages for iPad wins Mobile Award

We won the “Best New Service or Application” category in the Mobile Awards 2011! Congratulations to everyone involved and I am sure we will all go on to make more award winning apps!

XCode plugin for Hudson/Jenkins CI

This project has since moved to Jenkins, please take a look at Xcode Plugin on the Jenkins Wiki for the latest information.

Feature Overview

This is a simple plugin for Hudson CI that wraps and provides limited functionality for agvtool and xcodebuild to version and build XCode-based iOS projects. The plugin is mature enough to support building, versioning, IPA packaging and basic testing view OCUnit.

Versioning

This builder can invoke agvtoool to dynamically update the CFBundleVersion with the current build number prefixed with the current marketing version (as defined by CFBundleShortVersionString) to produce a version number of the form CFBundleShortVersionString.BUILD_NUMBER (e.g. 1.0.456)

Building

The target (optional), configuration (e.g. Debug, Release) and SDK (optional) can be specified in the per-project config along with whether to perform a clean before the build phase.

Packaging

The builder can be used to package the .app into a .ipa. Since a .app is actually a directory, it can be awkward to work with and, especially, distribute. We can simplify this by packaging the .app into a single .ipa file, which is just a zip file with a well-known internal structure

Unit Testing

This plugin will listen to the xcodebuild output when running OCUnit tests and write out JUnit-format test reports that Hudson can understand. Hudson will then use these to publish test failure reports and graphs.

Gotchas & Limitations

  • Obviously, the build machine has to be an OSX machine with XCode developer tools installed
  • Certificates, Identities and Provisions must be installed on the build machine separately
  • When code-signing, a prompt may appear on the build machine asking whether to allow keychain access. This will block the build until it is dismissed. Just select ‘Always Allow’ the first time and it shouldn’t need to ask again.
  • If you connect via ssh to the OSX slave, you will need to execute ‘security unlock-keychain’ once you connect to allow the build tools access to the keychain. The alternative is to use the JNLP slave agent
  • Make sure you define the CFBundleShortVersionString in your Info.plist. This will be used as the marketing version and will be prepended to the build number when using agvtool
  • Derek Stutsman reports that “If your project has the base SDK set to iPhone simulator, the build will crash with a nullreference exception”

Usage

Building

This is a maven project that uses the hudson maven plugin. You will first need to add the following to your ~/.m2/settings.xml:

1
2
3
4
5
<settings>
  <pluginGroups>
    <pluginGroup>org.jvnet.hudson.tools</pluginGroup>
  </pluginGroups>
</settings>

To clone the repository and build the .hpi, follow these steps:

1
2
3
4
5
6
7
8
# Clone the repository
$ git clone git://github.com/rayh/xcode-hudson-plugin.git
              
# Go into the cloned repository
$ cd xcode-hudson-plugin
              
# Build the project
$ mvn install

The xcode.hpi will be in the target/ directory.

Installing

I am awaiting commit access to the hudson repository on java.net so that I can use the official hudson to build the plugin as well as hosting the plugin in the official repository. Until then, you will have to install it by manually uploading the xcode.hpi to hudson. Simply go to ‘Manage Hudson’ > ‘Manage Plugins’ > ‘Advanced’ > ‘Upload Plugin’ and select the xcode.hpi that you either built or downloaded and then select ‘Upload’.

Setting up a build step

Add the XCode build step to a free-style project and set the target (e.g. MyApp), configuration (e.g. Release) and check the build IPA and update version number options. This will give you a single, versioned .ipa file. You can also select to clean the project before a build; while this will make sure that the project is starting from a clean state, it will make large projects take a lot longer.

Setting up a unit test step

Add the XCode build step and this time specify your unit test target (e.g. MyAppTests), configuration (e.g. Debug) and the SDK (e.g. Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.1.sdk/). Leave all the checkboxes unselected. The SDK needs to be supplied here as the unit tests will only be run when building under the simulator’s SDK.

Check the “Publish JUnit test result report” option in the project config and set the value “/test-reports/.xml” under “Test report XMLs”. This will tell Hudson to pick up the JUnit-format test reports.

Source Code

The source code is hosted on GitHub and made available under the GPLv2 license.

Download

You can download the latest issue tracker.

Acknowledgements

The xcodebuild/OCUnit output parsing was inspired and based upon Christian Hedin’s ocunit2junit.rb script.