Once you’ve mastered using localized strings in Xcode 4, you can move on to performing substitutions in those strings.

The benefit of this approach is two-fold. Strings values easily calculated at runtime don’t need to be individually defined, and those same strings can still be localized.

For example, let’s say you have a UITableView, and for each cell you want to display its index in the table:

Instead of five individually defined strings, you’d have a single string in your Localizable.strings file with a placeholder for the table index:

/*
  Localizable.strings
  How to Perform String Substitutions in Xcode 4

  Created by Miscellanea on 11/24/11.
  Copyright 2011 __MyCompanyName__. All rights reserved.
*/

"CellTitle" = "Item #%s";


Then in your UITableViewController implementation you’d reference the string and perform a substitution for the table index:

– (UITableViewCell *)tableView:(UITableView *)tableView
    cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView
        dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc]
            initWithStyle:UITableViewCellStyleSubtitle
            reuseIdentifier:CellIdentifier] autorelease];
    }

    NSString *itemNumber;

    // FIXME: we'll improve this in a later post!
    switch (indexPath.row)
    {
        case (0):
            itemNumber = @"1";
        break;

        case (1):
            itemNumber = @"2";
        break;

        case (2):
            itemNumber = @"3";
        break;

        case (3):
            itemNumber = @"4";
        break;

        case (4):
            itemNumber = @"5";
        break;

        default:
        break;
    }

    [cell.textLabel setText:[NSLocalizedString(@"CellTitle", @"")
        stringByReplacingOccurrencesOfString:@"%s"
        withString:itemNumber]];

    return cell;
}


This isn’t limited to numeric substitutions; it’s especially useful for titles and labels with prefixes, or anywhere a string needs to reflect a dynamic state or view.

In a future post I’ll explain a much better way to display numbers as strings.