Localizing your app with Linguan

The best time to get localize your app is either just before your 1.0 release is submitted to the App Store, or just after the 1.0 release. Earlier and you run the risk of needlessly localizing things that are going to change anyway; later and you're missing out on sales.

Enable Base Internationalization of Resource Files

Base Internationalization is a feature of iOS and OS X which means the you don't have to maintain separate .xib or .storyboard files for each language. Instead, the base resource file controls the layout and a separate .strings file provides the localized text for each new language.

For each .xib or .storyboard file, in the file inspector, ensure that localisation is enabled:


Select the project and ensure that the 'Use Base Internationalization' checkbox is set.


Ensure any English strings in code use NSLocalizedString()

Search through your entire project (Cmd-Shift-F) for @" and replace any raw strings with NSLocalizedString(string, comment). If the string...

Using @dynamic properties to access NSUserDefaults

Objective-C as a dynamic language

With the 'C' in its name, it's easy to forget that Objective-C is actually a dynamic language. This means that when a method is invoked, the calling code is not 'hard-wired' to the callee by the compiler & linker. Instead, the Objective-C Runtime examines the invocation and decides how it should proceed.

The most common use of this capability in regular Cocoa is in Core Data. You can create a class which is a subclass of NSManagedObject and represents one of the entities in your data model. Individual attributes are represented as properties with a @dynamic like this:

@interface Person : NSManagedObject
@property (nonatomic, strong) NSDate *born;

@implementation Person
@dynamic born;

The Core Data framework is able to manage the mapping of these properties onto a persistent store while the user code can use the entities as if they were simple objects.

The @dynamic keyword is simply a hint to the compiler that it should not raise any warnings...

Hostage to Fortune

“an undertaking or remark seen as unwise because it invites trouble or could prove difficult to live up to”.

Sometimes, it's fun to plan great changes for the future. I'm going to get fitter, travel more, eat better… and since no time traveller comes back to tell you whether you succeeded or not, there's no immediate risk to being wrong.

People rarely seem to start the new year saying what goals they missed in the previous year. In a way, that makes sense - it's better to focus on the things you want to happen rather than the past that can't be changed. However, part of what brings change is giving attention to that change. So, to increase the chances that I'll achieve my goals for 2014, I'm going to publish them here.

  1. Release 3 new products
  2. Do 9 updates to existing products
  3. Contribute 3 open source projects
  4. Write 1 blog post per month

I'm planning on reviewing these at the end of the year to see whether the added pressure helps deliver the goals.

Aside: My original goal was...

Placeholder views for iOS

When you're working on a new app, sometimes it's easier to start with dummy views and slowly replace them as you implement their functionality. Rather than use a simple UIView for this, PAPlaceholder gives you a better looking placeholder view that shows its dimensions and an optional title.

It also provides a dummy view controller which automatically creates the placeholder view. This is useful when you're using a view controller container such as a UITabBarController or a UISplitViewController.


Using this at the early stages of a project are particularly useful on iOS 7, where many of the system views (like the navigation bar or tab bar) are actually transparent and the content views extend behind them. The arrows on the PAPlaceholderView show the edges of the view so you can tell if the edges are where you expect them to be.

The source of PAPlaceholder is on github at https://github.com/dhennessy/PAPlaceholder

Adding PAPlaceholder to your project

The simplest way to add PAPlaceholder...

Downloading Device UDIDs from Apple Developer Portal

Apple allows an iOS developer to associate up to 100 devices with a developer account, and use those devices for testing Ad-Hoc builds. Although there's an option to remove devices, they continue to count towards the 100 device limit. That is, until you renew your developer account - then you get a message that you can delete devices and have them no longer apply against the limit. In past years, I've tried to carefully prune the list, but inevitably I've overlooked a bunch of devices and once you start adding new devices, you can no longer delete old ones.

This year, I have a new plan. I'm going to delete all devices, except for my own, and then gradually re-add client devices as they're needed. The developer portal has a useful option to upload a text file containing a list of devices but unfortunately doesn't have an option to download the existing devices. Using the excellent mechanize gem, I wrote a short script to scrape the UDIDs from the developer portal and export them to...

Installing PostgreSQL on Lion

OSX Lion ships with the PostgreSQL client tools, as well as a _postgres daemon user. I wanted to add a full PostgreSQL server in a way that was compatible with these tools and without creating an extra user account.

This recipe uses HomeBrew to do the heavy lifting. If you haven't already got it, head over to http://mxcl.github.com/homebrew and install it.

First, make sure brew is up to date:

$ brew update

Start the install process:

$ brew install postgresql

This will take a few minutes to download and eventually end with something like this:

==> Summary
/usr/local/Cellar/postgresql/9.0.4: 2577 files, 34M, built in 77 seconds

Next, initialize the database storage with this command:

$ initdb /usr/local/var/postgres

The built-in psql command (and many apps) expect to connect to a local PostgreSQL database using a unix domain socket in /var/pgsql_socket. This is currently owned by the _postgres user so we need to fix that:

$ sudo chown $USER /var/pgsql_socket/

Now create...

Creating Alpha Transparent Favicons on a Mac

Normally I use a very old Mac program called IcoMaker to create favicons. The problem with IcoMaker is it can’t generate alpha transparent ico files. I recently had to design a favicon for StatusHub which was round, so the standard gif level of transparency wasn’t going to cut it. Time to roll up my sleeves and find some new, hopefully free, software…

Given that favicons are based on the Windows ico format there aren’t a huge number of options available to create them on the humble Mac. Most programs claiming to support the ico format don’t support alpha transparency. For completeness, here are the set of options which don’t work:

I also tried several online tools like Dynamic Drives Generator and the...

© Copyright 2009-2014 Peer Assembly Ltd.