How to create a formatted localized string?

I have a localized string that requires several variables. However, when localizing, it is important that the order of the variables can change from language to language.

So this is not a good idea:

NSString *text = NSLocalizedString(@"My birthday is at %@ %@ in %@", nil); 

In some languages, some words come before others, and in others, vice versa. At the moment, I do not have a good example.

How can I provide NAMED variables in a formatted string? Is there any way to do this without any heavy homemade replacements? Even some numbered variables like {% @ 1}, {% @ 2}, etc. It would be enough ... is there a solution?

+7
iphone string-formatting
source share
3 answers

This is why NSLocalizedString accepts two parameters. Use the second parameter to include a comment describing the meaning of variables in the native language. Translators can then reorder their use using the $ + number construct. See Apple Notes for Localizers .

However, you cannot skip parameters in one language. For example, if you have 3 parameters in English and 4 in French, and you do not need a third in English, you cannot format as %1$@ %2$@ and %4$@ . You can only skip the last one.

+12
source share

Formatted string example:

 NSString *today = [MyHandWatch today]; NSString *msg = [NSString stringWithFormat:NSLocalizedString(@"Today is %@", @""), today]; 

genstrings generates this line in the Localizable.strings file:

 "Today is %@" = "Today is %@"; 
+10
source share

I decided this in the project a few weeks ago, creating my own simple template system using NSScanner . The method uses a template system that finds variables with the syntax ${name} . Variables are passed to the method via NSDictionary .

 - (NSString *)localizedStringFromTemplateString:(NSString *)string variables:(NSDictionary *)variables { NSMutableString *result = [NSMutableString string]; // Create scanner with the localized string NSScanner *scanner = [[NSScanner alloc] initWithString:NSLocalizedString(string, nil)]; [scanner setCharactersToBeSkipped:nil]; NSString *output; while (![scanner isAtEnd]) { output = NULL; // Find ${variable} templates if ([scanner scanUpToString:@"${" intoString:&output]) { [result appendString:output]; // Skip syntax [scanner scanString:@"${" intoString:NULL]; output = NULL; if ([scanner scanUpToString:@"}" intoString:&output]) { id variable = nil; // Check for the variable if ((variable = [variables objectForKey:output])) { if ([variable isKindOfClass:[NSString class]]) { // NSString, append [result appendString:variable]; } else if ([variable respondsToSelector:@selector(description)]) { // Not a NSString, but can handle description, append [result appendString:[variable description]]; } } else { // Not found, localize the template key and append [result appendString:NSLocalizedString(output, nil)]; } // Skip syntax [scanner scanString:@"}" intoString:NULL]; } } } [scanner release]; return result; } 

With a localized file that looks like this:

 "born message" = "I was born in ${birthYear} on a ${birthWeekDay}. ${byebye}"; "byebye" = "Cheers!"; 

We can perform the following results ...

 NSDictionary *variables = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:1986], @"birthYear", @"monday", @"birthWeekDay", nil]; NSString *finalString [self localizedStringFromTemplateString:@"born message" variables:variables]; NSLog(@"%@", finalString); // "I was born in 1986 on a monday. Cheers!" 

As you can see, I have added some additional features. Firstly, any variables that are not found ( ${byebye} in my example) will be localized and added to the results. I did this because I load the HTML files from my application package and run them through the localize method (in this case, I do not localize the input line when creating the scanner). In addition, I added the ability to send things other than NSString objects for some extra flexibility.

This code may not be the most efficient or beautifully written, but it does the job without any noticeable impact :)

+3
source share

All Articles