Having problems with Xcode not launching your iOS application on your device? Getting the entirely useless error message error: failed to launch 'PATH' -- Security that essentially just says “Security”? It’s possible your signing certificates and provisioning profiles are out of date or otherwise invalid. Revoke them from the web portal, and use Xcode to regenerate them (which can be done from Preferences -> Accounts -> View details). Then rebuild, signing your application with the new certificates.
Are you getting multiple, apparently duplicated calls to observeValueForKeyPath for the same key in your key-value observing code? A tip I just learned the hard way: make sure you’re not registering the same observer more than once!
I’ve wanted a concise way of visualising how much work goes into a PhD thesis for a while now. It took me nearly a year to write mine (though that did include some breaks for other projects), and my git repository has nearly 450 master branch commits and merges. I thought it might be fun to turn these into a video, showing the state of the document at each point. The result is:
It was trickier to create than I imagined, due to a few periods in the repositories history when it doesn’t actually build (the perils of a single-person project with no CI server). It took over 12 hours to render, using my `git-replay` script, and a proof sheet generator I wrote, imaginatively called PDF Proof Sheet.
I recently had a need to run a script on every revision along the master branch of a git repository. Not finding any simple way of achiveving this with the builtin git tools, I knocked up the following script, which I call “git-replay”. The gist, which will be updated as I find problems/add features, is at
# Takes a repository and script from the command line
# and executes the script for each git log entry in reverse chronological order
# Use temporary files of the following format
# Validate command line parameters
if [ -z $1 -o -z $2 ]; then
echo "Usage: gitReplay.sh REPOSITORY SCRIPT"
if [ ! -x $2 ]; then
echo "'$2' does not exist as an executable file"
# Generate and move to a temporary folder
tmp_loc=`mktemp -d $TMP_TEMPLATE`
pushd $tmp_loc > /dev/null
# Checkout the repository, and bail out if it fails
git clone $REPOSITORY . 2>&1
if [ $? -ne 0 ]; then
echo "Could not checkout repository"
popd > /dev/null
# Determine all the hashes of the repository history
hashes=`git log --reverse --pretty=format:%H`
# For every hash, move to that revision and pass it to the repository
for hash in $hashes; do
git checkout $hash
bash $SCRIPT $hash $index $tmp_loc
if [ $? -ne 0 ]; then
echo "Early terminating based on script return code"
This is part two of my series on writing Six to Eight, an iOS Stack Exchange client. If you haven’t read part one, I urge you to head to it now. In this part, I’ll discuss creating the first part of the “Core functionality” that users of Six to Eight will see. We’ll look at why I made it the way it is, and how it uses the StackExchange API.
Six to Eight supports all the Stack Exchange sites in the network. You “subscribe” to the sites you’re interested in, optionally focusing your attention on one person by “tracking” them. As such, the first view seen by new users of Six to Eight will be one requiring them to setup an initial subscription. You might think this should be easy, and perhaps it should be. However, for me, it turned into one of the most complex pieces of design and development in the app.
This “Subscription creation” view, which also allows them to edit existing subscriptions, has to accomplish three things:
Let users pick a Stack Exchange site
Let users decide if they want to track somebody, and allow them to pick that person
Just get out of the way as quickly as possible for users who just want to play with the app
Users have also got to be able to experiment with this setup a bit. If they’re tracking a user on one SE site, and want to switch to another, it’d be annoying if they had to re-select that user (assuming that the user is also using the newly selected site).
The UI uses a normal iPhone table view to present the site list, and user tracking toggle. This will, hopefully, present a large number of sites in an familiar fashion. The user selector allows people to easily find their own user within the selected site, and the re-association function saves them from having to repeat this task when they experiment. The UI is nearly all non-modal, so users can change their minds and toggle options without needing to wait for data. Importantly, if they just want to close the UI and start playing, they need only wait for the sites list to load, then tap “Save”.
So, to the implementation. For what looks like it should be a reasonably simple presentation of data, the code that runs this view is the most complex in the entire app. This is mostly to do with the number of possible states the UI can be in, coupled with the desire to keep things happening in an asynchronous fashion – lots of background work is occurring to update the data and verify it whilst the user selects their options.
Initially, the view turns up in a “Loading” state – there are no sites known, no user selected. We can’t do anything until we know what sites exist in the StackExchange network. This information comes from the StackAuth API endpoint at http://stackauth.com/1.0/sites, and Six to Eight fetchs it via my CoreStackCSAuth class. We request the data, and place the UI into a “Loading” state whilst we wait for it to arrive. Once our delegate is called to indicate that the CoreStack background loader has the data, we can update the UI with it, and transition into a “Select a site” state, where we default to the first available site and to tracking no user.
The entire UI is stitched together from this type of state transition, so we might as well represent it as a finite state transition diagram. In this…
Grey indicates the UI is fully operational to the user
Red indicates an error state, with suitable modal error message
Blue indicates a modal state, where the UI is displaying a “Working” dialog (like the “Look for John Doe on SESite”).
Green indicate “complete” states, where you can return having created a new subscription
Purple indicate other view controllers
Solid arrows are state transitions activated by the user
Dashed arrows are state transitions activated by the controller
The goal is to start in the left hand purple state (where site subscriptions are listed), and get back there via one of the green states. For clarity, I’ve omitted all the “Cancel” links back to the Site selector state – all grey and green states can get there.
Moreover, these are not all the possible states of the view controller, only the UI. Internally, the view controller can be both not waiting for or waiting for data from the Stack Exchange API, including the sites list, user check data, and site icons. This isn’t even all the UI – this is just the core view (and even then, excluding each “Waiting for icon” state). The slide down user selector has it’s own internal UI state, and is activated from the two grey states in the centre of the diagram.
In all states other than blue, the UI is responsive to user interaction. Ideally, there would be no blue states, however in v1.0, I had no time to expand the state management to feasibly handle the feedback and changes needed to make user checking and re-association non-modal.
From the perspective of the API, re-association is easy. Whenever we start to track a user, the user selector dialog returns a structure obtained from the API endpoint api.sesite.example.com/1.0/users/filter?SEARCH, (CSUserDescription from CoreStack) that indicates the user name, their identifier and an association GUID. This association identifier is unique across all accounts tied together in the Stack Exchange network. When the user toggles the selected site, if we have such an association GUID, we display a modal dialog whilst we use the stackauth.com/1.0/users/GUID/associated method to find all the sites this user has associated themselves with. We search this list for the newly selected site, and either fail to find it (and so disable user tracking and display an error), or we find it and update the tracking data. The modal display is then hidden.
So, how did I do with respect to the 3 point goals initially set above, and the more general goals set out in part one?
As shown by the lack of solid arrows in the diagram between the two states and the first green state, the user can get a site up and running by just waiting a few seconds then pressing “Save”. This will setup the first reporting Stack Exchange site from the StackAuth API, without tracking a user. Similarly, the user is in control of the UI in all non-blue states, which represent the vast majority of interaction time with the UI. They can can cancel the setup, or change their settings. I think this “super fast initial setup” and responsive UI are key points in creating a good app.
The re-association feature is another subtle but important consideration for a touch based UI. We could leave it out, and whenever a user who’s tracking someone changes site, they could just re-search for their user. However, this requires more fiddly typing and network access – both best avoided on the iPhone. The StackAuth re-association API lets us save them the effort. Despite the fact that this feature is, in truth, rarely going to be used, I think the extra effort was well worth it. The fact that the Stack Exchange API allowed it with reasonable ease is testament to the quality of the feedback/design process used by the Valued Associated over at Stack Overflow Inc.
Now, if you’ll excuse me, I’m going to re-associate with an ale.