Skip to content

Posts tagged ‘app’

18
Oct

Kestrel — A Choosable Path Novel for Young Adults

Just over a year ago, I wrote about the interactive fiction fantasy book app I was working on. After much work by many people, we released it just a few weeks ago. It’s free, for iPad-only (so far). Please check it out and let me know what you think.

Kestrel is a choosable path story or novel for young adults where you make choices in behalf of the main character, altering how the story unfolds.

You get to decide where Kestrel goes, who she trusts, and how she reacts to the events around her. Depending on your choices, she can end up on either side of the conflict or weave a path along the middle.

Growing up on a farm where she can see the city lights at night, Kestrel dreams of a better future. One without cows. But in a world where two forces of magic are about to collide, Kestrel is about to be caught up in something that will change her world forever. And she may be the deciding factor.

The app currently has just one chapter. Each new chapter will be published as it becomes available. You will be able to buy each new chapter, or the whole book (and all future chapters) for a great discount until the book is complete.

Version 1.2 was just released today. It fixes a few more problems, including one occasional crash bug.

▸ Fixed another issue where the app could crash when tapping the next button at the top of the app.
▸ Increased the font size a bit when the device is in portrait orientation.
▸ Added a request for ratings, but hopefully in a way that isn’t annoying. If you’re annoyed, let me know. :)

17
Oct

Automatic Build Numbers for iOS Apps Using Xcode

UPDATE Sep 2014: Added another idea from Jared Sinclair, who has example code for Git.
UPDATE Jan 2013: Now also updating the build version in the dSYM file.

There are many articles that discuss how to automate build numbers in Xcode. However, some are misleading for iOS apps. Many are quite long. I wanted to find a short, simple way to do this.

Background

On the target Summary tab your project settings, Xcode lets you set a Version and a Build. The version is what we are all familiar with, such as 5.0 and 5.1.1. The build is what often appears in parentheses after the version, as in 5.0 (134) and 5.1.1 (147).

Apple doesn’t seem to care what you use for Version (aka CFBundleShortVersionString), but Build (aka CFBundleVersion) must be a monotonically increasing string, comprised of one or more period-separated integers. Thus Apple will reject your update if you go from 1.1 (10) to 1.2 (0). The version is ignored and, alas, zero is clearly less than ten.

The part about integers is important too because Apple will also reject your update if you go from 1.01 (1.01) to 1.1 (1.1). The period is not a decimal place. Both (1.01) and (1.1) are interpreted as “the integer one followed by the integer one”. We saw this logic in action when OS X went from version 10.4.9 to 10.4.10.

Problem

If you do this wrong, you’ll see this error when you upload your app update:

This bundle is invalid. The key CFBundleVersion in the Info.plist file must contain a higher version than that of the previously uploaded version.

To get your monotonically increasing period-separated integer build number, you could just use the app version, like 5.1.1 (5.1.1). But I think it’s better to use a build number that can help identify the code from which that version of your app was built. Both Git and Mercurial include the ability to count commits, which is perfect—always increasing and helpful in identifying the code.

If you modify the Info.plist file in your project folder during the build process, you’ll probably need to commit the change to your code repository. This extra commit, while not harmful, is unnecessary. Instead, you can modify the Info.plist file in the app package after the build process is finished. The file will be in a binary format, but the PListBuddy tool can handle it.

Solution

Here is the script you need for Mercurial. This script also adds the bundle version to the dSYM file, which is necessary for correctly symbolicating your crash logs. It’s also required for several distribution mechanisms including TestFlight and HockeyApp.

ver = `/usr/local/bin/hg id -n`.strip
puts "Build number is #{ver}"
filepath = "#{ENV['BUILT_PRODUCTS_DIR']}/#{ENV['INFOPLIST_PATH']}"
puts "Updating #{filepath}"
`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion #{ver}" "#{filepath}"`
filepath = "#{ENV['DWARF_DSYM_FOLDER_PATH']}/#{ENV['DWARF_DSYM_FILE_NAME']}/Contents/Info.plist"
puts "Updating dSYM at #{filepath}"
`/usr/libexec/PlistBuddy -c "Set :CFBundleVersion #{ver}" "#{filepath}"`

The first line counts the number of commits in your local repository. It’s safe to use as long as your builds are done on the same machine. Repositories on other computers may have different commit counts. For Git, you can count your commits using a similar command.

Steps

  1. Select your project in the Project Navigator
  2. Select your target
  3. Select the Build Phases tab
  4. Choose “Add Build Phase”
  5. Select “Add Run Script”
  6. Change the Shell to “/usr/bin/ruby”
  7. Copy and paste the script

Within your app, you can grab the version and build number with this code:

NSDictionary *appInfo = [[NSBundle mainBundle] infoDictionary];
NSString *appVersion = [NSString stringWithFormat:@"%@ (%@)", appInfo[@"CFBundleShortVersionString"], appInfo[@"CFBundleVersion"]];

This will give you a string like 2.2 (134) that you can display in your app. I’m using the new object subscripting syntax in Objective-C, but it’s not too hard to switch back to using objectForKey:.

Follow Up

Jared Sinclair has a nice example of how to do this with Git. I really like the idea of using the branch name as a build suffix for Debug builds. I’m going to update my code to match.

4
Sep

My Current Project

A few months ago, two friends asked if I’d be interested in working on a book project with them. Jed is a successful artist and illustrator. Noelle is a brilliant writer and educational designer. They’ve worked together on several projects and wanted a programmer to help design a book app. I said yes before they stopped talking. :)

Here is one of Jed’s early designs:

Story app mock up

It’s an interactive fiction fantasy story app, except that the plot is cohesive and targeted at a young adult audience. In many choosable path books, the endings were often very different from each other. For example, the plot might change from bank robbers to aliens depending on which door you went through. Also you died a lot.

In our story app, you nudge the main character in the direction you want her to go even as the story unfolds around her. The book remembers the choices you make and adjusts the text and artwork as you go along. Noelle is writing the same story more than 20 times and loving it. She’s been planning this story since high school.

A website is coming soon. We’re close to finishing the programming, art and writing for chapter one. Noelle is wrapping up chapter two in a few weeks.

Jed recently completed a successful Kickstarter project for traditional hand-made Japanese woodblock prints of video game characters. It’s kinda cool, so check it out if you’re interested.