代码改变世界

本地化iPhone应用程序

2011-09-21 16:41  Paul Wong  阅读(3751)  评论(0编辑  收藏  举报

本地化的iPhone应用程序Ⅰ:介绍

 

  iPhone应用程序本地化是很重要的,因为您的应用程序很可能被七十多个不同的国家的用户使用。肯定的是,用户更希望看到的信息是根据母语国家或地区进行格式化的。
  本地化不是一种语言,仅仅是数据的一种表示形式而已,就像货币单位,日期时间表示格式一样。在本教程中,我们将会学习到如何根据用户所在的国家或地区展示一些数据(如日期时间)。

 
格式化:
   我们一般使用用户所在语言环境的表达方式,而不是一些特定的标准,这就要用到格式化了。在Cocoa中,有NSNumberFormatter和NSDateFormatter。这些类对用户语言环境是敏感的,这意味着当你实例化实例时,它会使用用户当地的语言环境。NSLocate是一个用来得到用户本地标准或新建一个标准的类。
  为了得到当前的语言环境,代码如下:
1: NSLocale *currentUsersLocale = [NSLocale currentLocale];
2: NSLog(@"Current Locale: %@", [currentUsersLocale localeIdentifier]);
3:
4: //Output
5: Current Locale: en_US
   我们通过推送currentLocale消息得到当前区域,以及通过推送localeIdentifier消息得到当前区域的标识(字符串形式)。如果地区设置为美国,将会输出en_US。

使用NSNumberFormatter类
   代码是很简单的,不会占用你太多的时间,我们只需要创建一新对象,设置一些属性,把它和NSNumber类结合使用。下面是数字的不同转换,会输出在控制台上。
1: //Get the current user locale.
2: NSLocale *currentLocale = [NSLocale currentLocale];
3: NSLog(@"Current Locale: %@", [currentLocale localeIdentifier]);
4:
5: NSLog(@"Test numbers: 4.0, 0.4, 4.6, -64");
6:
7: NSNumber *number40 = [NSNumber numberWithFloat:4.0];
8: NSNumber *number04 = [NSNumber numberWithFloat:0.4];
9: NSNumber *number46 = [NSNumber numberWithFloat:4.6];
10: NSNumber *number64 = [NSNumber numberWithInt:-64];
11:
12: //Working with number 4.0 and representing as No Style
13: NSNumberFormatter *noStyleFormatter = [[NSNumberFormatter alloc] init];
14: [noStyleFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
15: [noStyleFormatter setNumberStyle:NSNumberFormatterNoStyle];
16:
17: //Decimal Style
18: NSNumberFormatter *decimalStyle = [[NSNumberFormatter alloc] init];
19: [decimalStyle setFormatterBehavior:NSNumberFormatterBehavior10_4];
20: [decimalStyle setNumberStyle:NSNumberFormatterDecimalStyle];
21: [decimalStyle setRoundingMode:NSNumberFormatterRoundFloor];
22: [decimalStyle setRoundingIncrement:[NSNumber numberWithInt:1]];
23:
24: //Currency Style
25: NSNumberFormatter *currencyStyle = [[NSNumberFormatter alloc] init];
26: [currencyStyle setFormatterBehavior:NSNumberFormatterBehavior10_4];
27: [currencyStyle setNumberStyle:NSNumberFormatterCurrencyStyle];
28:
29: //Percent Style
30: NSNumberFormatter *percentStyle = [[NSNumberFormatter alloc] init];
31: [percentStyle setFormatterBehavior:NSNumberFormatterBehavior10_4];
32: [percentStyle setNumberStyle:NSNumberFormatterPercentStyle];
33:
34: //Scientific Style
35: NSNumberFormatter *scientificStyle = [[NSNumberFormatter alloc] init];
36: [scientificStyle setFormatterBehavior:NSNumberFormatterBehavior10_4];
37: [scientificStyle setNumberStyle:NSNumberFormatterScientificStyle];
38:
39: //Spell Out Style
40: NSNumberFormatter *spellOutStyle = [[NSNumberFormatter alloc] init];
41: [spellOutStyle setFormatterBehavior:NSNumberFormatterBehavior10_4];
42: [spellOutStyle setNumberStyle:NSNumberFormatterSpellOutStyle];
43:
44: NSLog(@"Locale of noStyle formatter: %@", [[noStyleFormatter locale] localeIdentifier]);
45: NSLog(@"Locale of decimal style formatter: %@", [[decimalStyle locale] localeIdentifier]);
46: NSLog(@"Locale of currency style formatter: %@", [[currencyStyle locale] localeIdentifier]);
47: NSLog(@"Locale of percent style formatter: %@", [[percentStyle locale] localeIdentifier]);
48: NSLog(@"Locale of scientific style formatter: %@", [[scientificStyle locale] localeIdentifier]);
49: NSLog(@"Locale of spell-out style formatter: %@", [[spellOutStyle locale] localeIdentifier]);
50: NSLog(@"---------------------------------------");
51:
52: //Display Results
53: NSLog(@"Different formatting results for NSNumber 4.0 with Locale: %@", [currentLocale localeIdentifier]);
54: NSLog(@"---------------------------------------");
55: NSLog(@"Formatting 4.0 with No Style: %@", [noStyleFormatter stringFromNumber:number40]);
56: NSLog(@"Formatting 4.0 with Decimal Style: %@", [decimalStyle stringFromNumber:number40]);
57: NSLog(@"Formatting 4.0 with Currency Style: %@", [currencyStyle stringFromNumber:number40]);
58: NSLog(@"Formatting 4.0 with Percent Style: %@", [percentStyle stringFromNumber:number40]);
59: NSLog(@"Formatting 4.0 with Scientific Style: %@", [scientificStyle stringFromNumber:number40]);
60: NSLog(@"Formatting 4.0 with Spell Out Style: %@", [spellOutStyle stringFromNumber:number40]);
61: NSLog(@"---------------------------------------");
62:
63: NSLog(@"Different formatting results for NSNumber 0.4 with Locale: %@", [currentLocale localeIdentifier]);
64: NSLog(@"---------------------------------------");
65: NSLog(@"Formatting with No Style: %@", [noStyleFormatter stringFromNumber:number04]);
66: NSLog(@"Formatting with Decimal Style: %@", [decimalStyle stringFromNumber:number04]);
67: NSLog(@"Formatting with Currency Style: %@", [currencyStyle stringFromNumber:number04]);
68: NSLog(@"Formatting with Percent Style: %@", [percentStyle stringFromNumber:number04]);
69: NSLog(@"Formatting with Scientific Style: %@", [scientificStyle stringFromNumber:number04]);
70: NSLog(@"Formatting with Spell Out Style: %@", [spellOutStyle stringFromNumber:number04]);
71: NSLog(@"---------------------------------------");
72:
73: NSLog(@"Different formatting results for NSNumber 4.6 with Locale: %@", [currentLocale localeIdentifier]);
74: NSLog(@"---------------------------------------");
75: NSLog(@"Formatting with No Style: %@", [noStyleFormatter stringFromNumber:number46]);
76: NSLog(@"Formatting with Decimal Style: %@", [decimalStyle stringFromNumber:number46]);
77: NSLog(@"Formatting with Currency Style: %@", [currencyStyle stringFromNumber:number46]);
78: NSLog(@"Formatting with Percent Style: %@", [percentStyle stringFromNumber:number46]);
79: NSLog(@"Formatting with Scientific Style: %@", [scientificStyle stringFromNumber:number46]);
80: NSLog(@"Formatting with Spell Out Style: %@", [spellOutStyle stringFromNumber:number46]);
81: NSLog(@"---------------------------------------");
82:
83: NSLog(@"Different formatting results for NSNumber -64 with Locale: %@", [currentLocale localeIdentifier]);
84: NSLog(@"---------------------------------------");
85: NSLog(@"Formatting with No Style: %@", [noStyleFormatter stringFromNumber:number64]);
86: NSLog(@"Formatting with Decimal Style: %@", [decimalStyle stringFromNumber:number64]);
87: NSLog(@"Formatting with Currency Style: %@", [currencyStyle stringFromNumber:number64]);
88: NSLog(@"Formatting with Percent Style: %@", [percentStyle stringFromNumber:number64]);
89: NSLog(@"Formatting with Scientific Style: %@", [scientificStyle stringFromNumber:number64]);
90: NSLog(@"Formatting with Spell Out Style: %@", [spellOutStyle stringFromNumber:number64]);
91: NSLog(@"---------------------------------------");


使用NSDateFormatter类
   和NSNumberFormatter, NSDateFormatter 一样对本地化敏感,以下有一些介绍如何使用NSDateFormatter类的代码。
1: //Date Formatters.
2: [NSDateFormatter setDefaultFormatterBehavior:NSDateFormatterBehavior10_4];
3: NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
4: [dateFormatter setDateStyle:NSDateFormatterLongStyle];
5: [dateFormatter setTimeStyle:NSDateFormatterNoStyle];
6: NSDate *date = [NSDate date];
7:
8: NSString *formattedDateString = [dateFormatter stringFromDate:date];
9: NSLog(@"Formatted date string for locale %@: %@", [[dateFormatter locale] localeIdentifier], formattedDateString);
10:
11: //Custom Date Formatter.
12: NSDateFormatter *customDateFormatter = [[NSDateFormatter alloc] init];
13:
14: //When setting the date format, do not set the date and time format style.
15: //Only one of the two can be set if not, the latter setting will take precedence.
16: [customDateFormatter setDateFormat:@"'The time is' hh:mm 'on' EEEE MMMM d"];
17:
18: NSLog(@"%@", [customDateFormatter stringFromDate:date]);

  我们经常使用格式化来处理货币,单位和时间格式,这样就可符合当前语言环境的格式了。 这部分有点简单,接下来进入第二部分

 

本地化的iPhone应用程序Ⅱ:自定义格式化

 

这部分是创建一个自定义的格式化程序,用来显示特定语言环境的数据。我们将创建一个新类,根据用户当前语言环境来显示电话号码。如果区域设置为en_US,这电话号码看起来像1(111)111-1111.


NSFormatter类:
  要创建一自定义格式化,先创建一个继承于NSFormatter的类,命名为PhoneNumberFormatter。头文件如下:
1: #import <UIKit/UIKit.h>
2:
3: @interface PhoneNumberFormatter : NSFormatter {
4:
5: NSLocale *locale;
6: }
7:
8: @property (nonatomic, copy) NSLocale *locale;
9:
10: - (NSString *) stringFromPhoneNumber:(NSNumber *)aNumber;
11:
12: @end
由于继承于NSFormatter类,所以要覆盖一些方法。有三个方法需要覆盖的:

看我们看看initWithLocale方法和stringFromPhoneNumber方法的代码吧:
1: - (void) initWithLocale {
2: [super init];
3:
4: locale = [NSLocale currentLocale];
5: }
6:
7: - (NSString *) stringFromPhoneNumber:(NSNumber *)aNumber {
8:
9: NSString *localeString = [locale localeIdentifier];
10: NSString *tempStr = [[NSString alloc] initWithString:@""];
11: NSRange range;
12: range.length = 3;
13: range.location = 3;
14: //Returns the phone number 2032225200 as 1(203)222-5200
15: if([localeString compare:@"en_US"] == NSOrderedSame) {
16: NSString *areaCode = [[aNumber stringValue] substringToIndex:3];
17: NSString *phone1 = [[aNumber stringValue] substringWithRange:range];
18: NSString *phone2 = [[aNumber stringValue] substringFromIndex:6];
19:
20: tempStr = [NSString stringWithFormat:@"1(%@)%@-%@", areaCode, phone1, phone2];
21: }
22:
23: return tempStr;
24: }
在initWithLocale方法中,我们得到了当前用户的语言环境并将它复制实例变量中。在stringFromPhoneNumbe方法中,我们根据语言环境显示了NSNumber值。


让我们看看stringForObjectValue方法:
1: - (NSString *) stringForObjectValue:(id)anObject {
2:
3: if(![anObject isKindOfClass:[NSNumber class]])
4: return nil;
5: else
6: return [self stringFromPhoneNumber:anObject];
7: }
我们先判断这对象是否为NSNumber,如果是,就通过stringFromPhoneNumber方法处理。
下面是把代码用在应用程序中:
1: - (void)applicationDidFinishLaunching:(UIApplication *)application {
2:
3: NSNumber *phoneNumber = [NSNumber numberWithInt:1231231212];
4: PhoneNumberFormatter *pnf = [[PhoneNumberFormatter alloc] initWithLocale];
5:
6: NSLog(@"Phone Number: %@ for locale: %@", [pnf stringFromPhoneNumber:phoneNumber], [[pnf locale] localeIdentifier]);
7:
8: [pnf release];
9:
10: // Override point for customization after application launch
11: [window makeKeyAndVisible];
12: }
这样,电话号码和当前区域就显示在调试窗口中了。


本地化的iPhone应用程序Ⅲ:国际化


本地化与国际化我们经常面对,我们可以根据用户的喜好用它来显示一些信息。好吧,让我们用用户的首先语言来显示文本吧。


准备国际化:
  在我们的示例程序中,我们将支持两种语言,英语和意大利语。在Xcode中创建一个新的项目,创建后,在Finder中打开项目的位置,并创建两个文件夹为en.lproj和it.lproj。这两个文件将成为您的应用程序的语言项目了,所有的语言资源将分别存储在这两个目录中。它们包含可以本地化的字符串资源,其默认名称为Localizable.strings,但我们命名其为strings文件。

 
本地化字符串文件:
  字符串是被本地化为键-值格式,键和值格式如下。你还可以按这格式继续添加键-值对。
//Localizable.String file for the English version.
"WelcomeKey" = "Welcome!!!";
//Localizable.strings file for the Italian version.
"WelcomeKey" = "Benvenuto!!!";
好了,让我们看看怎样把这些值从资源文件中取出来吧。
1: - (void)applicationDidFinishLaunching:(UIApplication *)application {
2:
3: NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
4: NSArray *languages = [defaults objectForKey:@"AppleLanguages"];
5: NSString *currentLanguage = [languages objectAtIndex:0];
6:
7: NSLog(@"Current Locale: %@", [[NSLocale currentLocale] localeIdentifier]);
8: NSLog(@"Current language: %@", currentLanguage);
9: NSLog(@"Welcome Text: %@", NSLocalizedString(@"WelcomeKey", @""));
10:
11: // Override point for customization after application launch
12: [window makeKeyAndVisible];
13: }


用genstrings创建资源文件:
  使用genstrings工具自动创建strings文件。为了确保能使用NSLocalizedString方法来显示本地化文本。当在资源文件中使用该工具时,它会提取所有的键,注释并为你创建一个strings文件。接下来你要做的就是,根据语言来为键寻找出值。
1: genstrings -o en.lproj *.m


本地化iPhone程序显示名称:
当用户更改其首先语言设置时,iPhone应用程序的名称也要变化的。好了,让我们看看怎样如何用意大利语或英语显示名称吧。创建一个新的strings名为InfoPlist.strings文件保存在it.lproj目录下。新增一个键-值为”CFBundleDisplayName”-“Stringhe di file”的实体。这文件如下:
CFBundleDisplayName = "Stringhe di file";
  现在,当你的首选语言为意大利语时,应用程序的名称也随之改变。一旦更改为英语,它会改为StringsFile,这样我们并不需要为英语创建一个新的InfoPlist.strings文件

结束:

  本教程结束,翻译资料Localizing iPhone Apps,您可以在此下载源文化,感谢阅读,希望对您有帮助。