Find the API and Use It

It all started with an idea, something to scratch a personal itch. I was learning elementary French, and realized that there is an algorithmic approach to generating the numbers. Not a very elegant algorithm, but one that could easily be turned into a computer program.

The idea turned into a function, and soon enough it turned into an iPhone app, now called Les Nombres and available from the App Store (and also for Windows Phone). My function takes a nonnegative integer and turns it into a French language string, which is displayed on the screen. It could be fed into a speech synthesizer, but in Les Nombres the numbers are recordings of a native French speaker, which I think is nice. (And I couldn’t use recordings of Apple’s “Virginie” voice from OS X anyway due to its license.)

To keep things simple, Les Nombres only deals with the numbers 0 to 100, even though my function could do up to 1,000 out of the box. It involves some 90 lines of Objective-C code, including two recursive calls. It was fun to write, and I learned something in the process, but ultimately I didn’t have to write it at all.

The thing is, I only recently noticed that NSNumberFormatter in Foundation has had the NSNumberFormatterSpellOutStyle since iOS 2.0. (The style constant is an alias of kCFNumberFormatterSpellOutStyle in Core Foundation, and most likely it all boils down to ICU.) The spell-out style spells out the number, of course (doh!).

And just like that, my 90 lines of Objective-C were replaced with 10, or ten, lines of modern Objective-C, with ARC and literals. T-e-n, ten. They read like this:

- (NSString *)frenchNumber:(int)n {
    static NSNumberFormatter *formatter = nil;
    if (!formatter) {
        formatter = [[NSNumberFormatter alloc] init];
        [formatter setLocale:[[NSLocale alloc]
            initWithLocaleIdentifier:@"fr"]];
        [formatter setNumberStyle:NSNumberFormatterSpellOutStyle];
    }
    return [formatter stringFromNumber:@(n)];
}

I just set the locale of the formatter to “fr”, et voilà !

The moral of this story is that whatever you want to do under the umbrella of internationalization or comparable, then if the platform you’re working with is worth its salt, it will have the APIs to do what you want to do. Find them and then use them. Don’t write that code until you looked for the APIs.