CocoaConf

CocoaConf is a new developer-focused conference for Mac OS X and iOS being held August 12-13 in Columbus, OH. I am presenting a session on networking with Cocoa. It will cover the various APIs available to Mac OS X and iOS developers from Apple and third-parties, as well as touch on issues unique to using the network on a mobile platform.

Early registration opened today and you can get a conference pass for 50% off.

The iOS In-App Purchases Requirement

Marco Arment lays out the arguments against Apple’s new in-app purchase requirements for iOS apps:

This is partially defensible: Apple’s promotions in the App Store certainly bring a lot of people to apps, and it’s all happening on their hardware and platform. But if someone wants the Wall Street Journal app and finds it by searching for “WSJ” in the App Store and selecting it directly, who really brought that customer to the app?

Read More

Apple Isn’t Earning Their 30%

Much has been said over the last 2½ years about the App Store and places where Apple is failing third-party developers. Many things have been fixed, but unfortunately, many more have been neglected or only partially addressed. On January 22, 2011, the App Store surpassed 10 billion downloads. Let’s assume 1% of those are paid and Apple only takes the minimum 29¢ for each one. That’s still $29 million. Apple needs to do a lot more to earn their 30% cut. Read More

Christmas Lights Finder 1.0 for iOS

Our latest iOS app, Christmas Lights Finder, is now available on the App Store.

This app has been tumbling around in my head for almost a year. Our kids really like looking at the lights people put on their houses and in their yards, but they don’t always have the longest attention span, especially at night when they are tired. While it’s fine to aimlessly drive around and look at lights, I thought it would be far better, and more fun for mom and dad, if we had an idea of where to go to see really great lights. What better than an app on your phone to point the way? Read More

My First Foray into Facebook Ads

Web Roulette hasn’t lit the world on fire. Thus far I’ve been working on free options: Twitter, Facebook and LinkedIn contacts, submissions to app review sites, giving out handfuls of promo codes and asking the younger members of my extended family to give them to their friends. It hasn’t made a noticeable difference. Thus far, sales have followed the usual “app curve”: the biggest sales day is day #1, with an almost exponential decline to one or two a day, at best. Read More

Web Roulette 1.0.1 is on the App Store

Apple approved the 1.0.1 update to Web Roulette earlier this week. It fixes a potential crash when submitting links back to us and addresses a UI glitch on the “about” screen.

One interesting statistic from the first couple weeks of sales is that iPad users are the large majority of daily users. It’s hard (impossible?) to say if this is because there is less competition in the iPad part of the App Store or if people prefer to use a web-centric app like Web Roulette on an iPad.

Automatic Subversion Revision Stamping for iPhone Projects

Early during development of a new iPhone OS application, I discovered that App Store submissions must use a strict format for the CFBundleVersion key in the Info.plist file. It can only be numbers and dots. This left me a little frustrated with how to version pre-1.0 releases to testers. I didn’t want to use an open-source style “0.9” and yet it wasn’t 1.0. What I really wanted was “1.0 b1” or similar.

I stumbled on Daniel Jalkut’s post about automatically stamping the Subversion revision into Info.plist and thought that might be a good way to go. I also created a new key in Info.plist, LYSApplicationDisplayVersion, that I use as a human-friendly version string, which is where I get my preferred “1.0 b1” form. CFBundleVersion now takes the form of major.minor.revision, where major and minor are the important parts of the human-friendly version (“1.0”) and revision is the Subversion revision number that produced the binary.

I like this method because it solves one problem raised by commenters on Daniel’s post. Because the Subversion revision is the third component, it doesn’t matter that r3999 is a mature 1.2 point release and r4000 is a risky pre-2.0 alpha for testers. Those versions end up 1.2.3999 and 2.0.4000 and it’s clear that they are from two different branches of development. For iPhone Ad Hoc distribution, iTunes also parses the version properly and knows that 1.0.100 is newer than 1.0.95.

Here is the script to paste into your custom script build phase:

# Xcode auto-versioning script for Subversion
# by Axel Andersson, modified by Daniel Jalkut to add
# "--revision HEAD" to the svn info line, which allows
# the latest revision to always be used.
 
use strict;
 
die "$0: Must be run from Xcode" unless $ENV{"BUILT_PRODUCTS_DIR"};
 
# Get the current subversion revision number and use it to set the CFBundleVersion value
my $REV = `/usr/bin/svnversion -n ./`;
my $INFO = "$ENV{BUILT_PRODUCTS_DIR}/$ENV{WRAPPER_NAME}/Info.plist";
 
my $version = $REV;
 
# (Match the last group of digits and optional letter M/S/P):
 
# ugly yet functional (barely) regex by Daniel Jalkut:
#$version =~ s/([\d]*:)(\d+[M|S]*).*/$2/;
 
# better yet still functional regex via Kevin "Regex Nerd" Ballard
($version =~ m/(\d+)([MSP]*)$/) && ($version = $1);
 
die "$0: No Subversion revision found" unless $version;
die "$0: Modified, switched or partial working copy, you sure about that?" if $2 && ($ENV{"BUILD_STYLE"} eq "Ad Hoc" || $ENV{"BUILD_STYLE"} eq "App Store");
 
open(FH, "plutil -convert xml1 \"$INFO\" -o - |") or die "$0: $INFO: $!";
my $info = join("", <FH>);
close(FH);
 
$info =~ s/([\t ]+<key>CFBundleVersion<\/key>\n[\t ]+<string>\d+\.\d+).*?(<\/string>)/$1.$version$2/;
 
open(FH, "| plutil -convert binary1 - -o \"$INFO\"") or die "$0: $INFO: $!";
print FH $info;
close(FH);

There are a couple of other changes to this script for Subversion 1.5 and later, and for iPhone OS targets.

The first is that the regular expression allows for a trailing P in the Subversion revision. This signals a working copy from a sparse checkout, which I never use and therefore may be a problem. I have the script fail if any letter is appended to the revision when the BUILD_STYLE is “Ad Hoc” or “App Store”, which are two new configurations, cloned from Release, that I use for Ad Hoc and App Store distribution, respectively. Especially for modified working copies: I never want to accidentally hand out a build made from a modified working copy. Should the day come that I really do, I can comment this line out, make the build, and uncomment it again.

The second is that iPhone projects convert Info.plist to the binary plist format in the application bundle. In order to extract the existing CFBundleVersion key, it must be converted back to XML. When writing the plist back out, it is again converted to binary. Both of these steps use plutil, which is part of the Developer Tools.

Remember HTTP Password in Mobile Safari

In iPhone OS 3.0, Apple allowed Mobile Safari to save usernames and passwords in web forms. Unfortunately, Safari does not offer to do the same thing for HTTP Basic and Digest authentication. I’ve become fond of using HTTP authentication because it is very easy to set up, either in your Apache virtual host configuration or within a Rails application. There are many times that a full-fledged user database is unnecessary for a simple administration back-end.

There is a work-around, though it does mean storing your user and password in plaintext in your device’s bookmarks. HTTP allows you to supply authentication credentials as part of the URL, in the form http://username:password@example.com/.