版本記錄
| 版本號 | 時間 |
|---|---|
| V1.0 | 2018.05.10 |
前言
很多APP都有國際化版本,常見于一些大公司的產(chǎn)品,比如Facebook、Wechat等,那么國際化需要我們APP做哪些更改呢,接下來這幾篇就一起來看一下APP的國際化和本地化。感興趣的可以看上面幾篇。
1. App的國際化和本地化(一) —— 簡單介紹(一)
2. App的國際化和本地化(二) —— 查看語言和區(qū)域設(shè)置(一)
3. App的國際化和本地化(三) —— 國際化用戶界面(一)
4. App的國際化和本地化(四) —— 國際化代碼(一)
回顧
上一篇主要介紹國際化代碼,本篇主要介紹使用區(qū)域設(shè)置格式化數(shù)據(jù)。
Formatting Data Using the Locale Settings - 使用區(qū)域設(shè)置格式化數(shù)據(jù)
不同的國家和地區(qū)對于數(shù)字和時間信息的格式有不同的約定。 區(qū)域設(shè)置提供有關(guān)當(dāng)前用戶使用的格式的信息,在編寫處理面向用戶的數(shù)據(jù)類型的代碼時必須考慮這些信息。 用戶通過在iOS設(shè)備的設(shè)置和Mac上的系統(tǒng)首選項中選擇區(qū)域來設(shè)置區(qū)域設(shè)置。 用戶還可以在應(yīng)用程序運行時更改區(qū)域設(shè)置。 因此,如果您在代碼中操作數(shù)據(jù)對象并將其呈現(xiàn)給用戶,請使用locale APIs正確格式化數(shù)據(jù)。
您不需要知道如何格式化所有不同地區(qū)中的數(shù)據(jù)。 您可以使用自動生成區(qū)域敏感格式的預(yù)設(shè)樣式。 只要您在將它們呈現(xiàn)給用戶之前將其轉(zhuǎn)換為區(qū)域性敏感格式,就可以使用自定義格式。 本章介紹如何編寫區(qū)域敏感代碼。
About Locale Formats - 關(guān)于區(qū)域格式
區(qū)域設(shè)置表示特定用戶的格式選擇,而不是用戶的首選語言。 這些通常是相同的,但可以不同。 例如,住在德國的講英語的母語人士可能會選擇英語作為語言,德國作為該地區(qū)。 文本以英文顯示,但日期,時間和數(shù)字遵循德國格式規(guī)則。 日在月的前面和24小時的時間表示,如Table 4-1所示。

在Mac上,您可以在系統(tǒng)偏好設(shè)置中預(yù)覽修改的區(qū)域設(shè)置首選項。 從“地區(qū)”彈出式菜單中選擇地理區(qū)域時,會顯示日期,時間和數(shù)字格式的樣本。 該屏幕截圖顯示了當(dāng)英語是該語言并且日本是該地區(qū)時的示例數(shù)據(jù)格式:

Mac用戶還可以通過單擊Advanced按鈕來自定義日期,時間和數(shù)字格式,如Reviewing Language and Region Preferences on Your Mac中所述。
Using the Locale Object - 使用地區(qū)對象
NSLocale對象封裝有關(guān)特定區(qū)域的格式標準的信息。 在格式化面向用戶的文本時,會傳遞一個代表用戶所選區(qū)域的NSLocale對象。 NSLocale類提供用于獲取用戶的區(qū)域?qū)ο蟮念惙椒ㄒ约坝嘘P(guān)支持的區(qū)域的其他信息。
1. Getting the User’s Locale - 獲取用戶區(qū)域
您可以使用NSLocale類中的currentLocale或autoupdatingCurrentLocale類方法來獲取用戶的區(qū)域。
如果使用currentLocale方法,則保證返回對象的屬性值不會更改。 因此,如果要執(zhí)行需要一致的操作,請使用currentLocale方法。
如果使用autoupdatingCurrentLocale方法,那么當(dāng)用戶更改區(qū)域設(shè)置時,屬性值可能會更改。 但是,如果返回的對象發(fā)生更改,則不會通知您。
要觀察區(qū)域設(shè)置首選項更改,請閱讀Registering for Locale and Time Zone Changes。
提示:系統(tǒng)設(shè)置與用戶設(shè)置不同。 不要使用systemLocale類方法來獲取用戶的區(qū)域。
2. Getting Information About a Locale - 獲取關(guān)于區(qū)域的信息
使用NSLocale類中的objectForKey:方法來訪問有關(guān)語言環(huán)境的信息。 例如,將NSLocaleUsesMetricSystem密鑰傳遞給此方法以獲取布爾數(shù),該數(shù)字確定區(qū)域設(shè)置是否使用metric系統(tǒng)。
NSNumber *metricSystem = [[NSLocale currentLocale] objectForKey:NSLocaleUsesMetricSystem];
傳遞key為NSLocaleCurrencySymbol以獲取代表當(dāng)?shù)胤柕淖址?/p>
NSString *currencySymbol = [[NSLocale currentLocale] objectForKey:NSLocaleCurrencySymbol];
對于區(qū)域keys的完整列表,請參考NSLocale Component Keys。
3. Getting Localized Language and Dialect Names - 獲取本地語言和方言名稱
不應(yīng)向用戶顯示API和文件夾名稱中指定語言和方言的標識符,例如de-CH,en-AU和pt-PT。 要獲得可讀的本地化語言或方言名稱,請在NSLocale類中使用displayNameForKey:value:方法,傳遞NSLocaleIdentifier作為關(guān)鍵參數(shù)。
To get the localized name for languages and dialects - 獲取地區(qū)名稱用于語言和方言
- 獲取APP正在使用的語言
NSString *languageID = [[NSBundle mainBundle] preferredLocalizations].firstObject;
返回的字符串是標識書面語言或方言的language ID,如Language and Locale IDs中所述。
- 獲取關(guān)聯(lián)的地區(qū)對象
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:languageID];
如果您將語言ID作為區(qū)域設(shè)置ID參數(shù)傳遞,則會返回該語言的區(qū)域設(shè)置。 例如,如果您將de-CH作為語言傳遞,則會返回瑞士語言環(huán)境。
- 獲取區(qū)域語言名稱
NSString *localizedString = [locale displayNameForKey:NSLocaleIdentifier value:languageID];
字符串的格式是[Language]([Dialect])。 例如,如果language ID是de-CH,則本地化語言字符串是Deutsch(Schweiz)。如果語言ID是de,則本地化語言字符串是Deutsch。
4. Getting Language-Specific Quotes - 獲取特定于語言的引號
可以從區(qū)域設(shè)置對象獲取開始和結(jié)束引號,這些引號在不同的語言中有所不同。 使用Getting Localized Language and Dialect Names中描述的相同技術(shù)獲取該語言的默認語言環(huán)境,然后使用區(qū)域鍵獲取特定于語言的引號。
To create a string that uses locale-sensitive quotes - 使用區(qū)域敏感引號創(chuàng)建字符串
- 獲取APP正在使用的語言
NSString *languageID = [[NSBundle mainBundle] preferredLocalizations].firstObject;
- 獲取關(guān)聯(lián)的區(qū)域?qū)ο?/li>
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:languageID];
- 從區(qū)域?qū)ο笾蝎@取引號的開始和結(jié)束符號
bQuote = [locale objectForKey:NSLocaleQuotationBeginDelimiterKey];
eQuote = [locale objectForKey:NSLocaleQuotationEndDelimiterKey];
- 使用區(qū)域敏感的引號形成字符串
quotedString = [NSString stringWithFormat:@"%@%@%@", bQuote, myText, eQuote];
Table 4-2展示了不用區(qū)域,當(dāng)myText是“@iPhone”的不同結(jié)果。

Formatting Strings - 格式字符串
如果可用,請為面向用戶的文本使用替代的,區(qū)域敏感的NSString方法。 有語言環(huán)境敏感的方法來創(chuàng)建帶格式的字符串,更改大小寫,獲取字符串的range以及比較字符串。
1. Creating Formatted Strings - 創(chuàng)建格式字符串
至少,在NSString類中使用localizedStringWithFormat:方法,而不是使用stringWithFormat:方法來格式化面向用戶的文本。 對現(xiàn)有代碼的一個簡單修復(fù)就是在整個代碼中用替代的localizedStringWithFormat:方法替換stringWithFormat:方法的出現(xiàn),如下所示:
NSString *localizedString = [NSString localizedStringWithFormat:@"%3.2f", myNumber];
此方法使用系統(tǒng)區(qū)域設(shè)置。 要指定用戶的區(qū)域設(shè)置首選項,請將[NSLocale currentLocale]作為區(qū)域設(shè)置參數(shù)傳遞給initWithFormat:locale:或initWithFormat:locale:arguments:方法。 為了獲得最佳結(jié)果,請使用Formatting Dates and Times以及Formatting Numbers中所述的數(shù)據(jù)特定格式化程序?qū)ο蠛皖A(yù)設(shè)樣式。
2. Changing the Case of Strings - 更改字符串的大小寫
在字符串中更改大小寫的過程對于所有語言都不相同。 使用這些區(qū)域敏感的NSString方法來更改大小寫:
如果您將nil作為區(qū)域設(shè)置參數(shù)傳遞,則會使用系統(tǒng)區(qū)域設(shè)置,這是不正確的。 要指定用戶的區(qū)域首選項,請將[NSLocale currentLocale]作為語言環(huán)境參數(shù)傳遞。
Formatting Dates and Times - 格式化日期和時間
您可以使用NSDateFormatter類創(chuàng)建也是區(qū)域設(shè)置敏感的NSDate對象的本地化字符串表示。 NSDateFormatter對象通常直接附加到Interface Builder文件中的文本字段,但如果以編程方式創(chuàng)建NSDateFormatter對象,請確保使用返回本地化字符串表示形式的方法。
注意:
NSDateFormatter類不是線程安全的。 詳情請參閱Threading Programming Guide。
1. Using Preset Date and Time Styles - 使用預(yù)設(shè)日期和時間樣式
要使用預(yù)設(shè)樣式獲取日期和時間的本地化字符串表示形式,請在NSDateFormatter類中使用localizedStringFromDate:dateStyle:timeStyle:類方法:
NSString *localizedDateTime = [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterShortStyle];
例如,通過將NSDateFormatterMediumStyle作為style參數(shù)傳遞,指定一個中等樣式來縮寫文本(例如Jun 10, 2013)。 通過將NSDateFormatterShortStyle作為style參數(shù)傳遞,為僅限數(shù)字的表示(例如6/10/13或11:03 AM)指定短樣式。 Table 4-3顯示了當(dāng)英語是該語言且美國是該地區(qū)時使用預(yù)設(shè)格式的結(jié)果。

Table 4-4顯示了針對日期樣式傳遞NSDateFormatterMediumStyle以及針對不同語言和區(qū)域傳遞時間樣式的NSDateFormatterShortStyle的結(jié)果。

日期:WWDC 2013 Making Your App World-Ready: Data Formatting > Preset Date Styles
2. Using Custom Date and Time Styles - 使用自定義日期和時間樣式
僅當(dāng)預(yù)設(shè)樣式不符合您的需要時才使用自定義日期和時間樣式。 但是,在獲取日期和時間的字符串表示之前,請將自定義格式轉(zhuǎn)換為區(qū)域敏感的格式。 NSDateFormatter類中的dateFormatFromTemplate:options:locale:方法重新排列給定的模板以符合指定的區(qū)域。
To get a localized string representation of a date and time using a custom style - 使用自定義樣式獲取日期和時間的本地化字符串表示形式
- 創(chuàng)建NSDateFormatter對象
NSDateFormatter *dateFormatter = [NSDateFormatter new];
- 使用dateFormatFromTemplate:options:locale:類方法從您提供的模板中獲取一個本地化的格式字符串。
NSString *localeFormatString = [NSDateFormatter dateFormatFromTemplate:@"dMMM" options:0 locale:dateFormatter.locale];
dateFormatFromTemplate:options:locale:方法的模板參數(shù)應(yīng)遵循Unicode Technical Standard #35,如Use Format Strings to Specify Custom Formats中所述。 例如,template @“dMMM”指定月份的日期和月份的縮寫應(yīng)該在格式字符串中。 模板中符號和任何非符號字符的順序都將被忽略。
- 將
NSDateFormatter實例的格式設(shè)置為區(qū)域設(shè)置敏感的格式字符串。
dateFormatter.dateFormat = localeFormatString;
- 使用stringFromDate:方法獲取日期的本地化字符串表示形式。
NSString *localizedString = [dateFormatter stringFromDate:[NSDate date]];
例如,如果您不將@“MMM d”字符串轉(zhuǎn)換為區(qū)域設(shè)置敏感格式,則結(jié)果不是本地化的,如表4-5中的第二列所示

視頻:WWDC 2013 Making Your App World-Ready: Date Formatting > Custom Date and Time Styles
3. Parsing Localized Date Strings - 解析本地日期字符串
用戶使用本地化格式輸入日期,因此相應(yīng)地解析輸入字符串。 使用NSDateFormatter對象將本地化的字符串轉(zhuǎn)換為日期對象。 使用其中一種預(yù)設(shè)樣式設(shè)置日期格式化器的樣式。 (僅當(dāng)預(yù)設(shè)樣式不起作用時才使用模板格式字符串。)另外,允許日期格式化程序在解析字符串時使用啟發(fā)式。
To convert a localized date string to a date object - 將本地化的日期字符串轉(zhuǎn)換為日期對象
- 創(chuàng)建日期格式對象
NSDateFormatter *dateFormatter = [NSDateFormatter new];
- 設(shè)置日期格式樣式為預(yù)設(shè)樣式
dateFormatter.dateStyle = NSDateFormatterMediumStyle;
將NSDateFormatterMediumStyle替換為您希望用戶輸入的樣式。
- 如果輸入字符串不包含時間,請將時間樣式設(shè)置為無。
dateFormatter.timeStyle = NSDateFormatterNoStyle;
- 將
leniency設(shè)置為YES(啟用heuristics)。
dateFormatter.lenient = YES;
- 將字符串轉(zhuǎn)化為日期
NSDate *date = [dateFormatter dateFromString:inputString];
例如,如果區(qū)域為美國,輸入字符串為9/3/14,預(yù)設(shè)樣式為NSDateFormatterShortStyle,則日期解釋為2014-09-03 07:00:00 +0000。 但是,如果區(qū)域設(shè)置為德國,則日期變?yōu)?code>2014-03-09 08:00:00 +0000。
Formatting Numbers - 格式化數(shù)字
區(qū)域設(shè)置會影響數(shù)字的格式,例如小數(shù),千位分隔符,貨幣和百分比符號。 例如,意大利的數(shù)字1,234.56被格式化為1.234,56。 因此,使用NSNumberFormatter類來創(chuàng)建NSNumber對象的本地化字符串表示。
注意:NSNumberFormatter類不是線程安全的。 詳情請參閱Threading Programming Guide。
1. Using Preset Number Styles - 使用預(yù)設(shè)數(shù)組樣式
要使用預(yù)設(shè)樣式獲取數(shù)字的本地化字符串表示形式,請在NSNumberFormatter類中使用localizedStringFromNumber:numberStyle:方法:
表4-6列出了可用的預(yù)設(shè)樣式,并將美國預(yù)設(shè)格式與其他區(qū)域進行比較

2. Parsing Localized Number Strings - 解析本地數(shù)字字符串
用戶可以使用本地化的格式輸入數(shù)字,因此可以相應(yīng)地解析這些輸入字符串。 使用NSNumberFormatter對象將字符串轉(zhuǎn)換為數(shù)字對象。 使用其中一種預(yù)設(shè)樣式設(shè)置數(shù)字格式化程序的樣式。 另外,允許數(shù)字格式化程序在解析字符串時使用啟發(fā)式。
To convert a localized number string to a number object - 將本地化的數(shù)字字符串轉(zhuǎn)換為數(shù)字對象
- 創(chuàng)建一個數(shù)字格式化對象
NSNumberFormatter *numberFormatter = [NSNumberFormatter new];
- 將格式化樣式設(shè)置為預(yù)設(shè)樣式
numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;
將NSNumberFormatterDecimalStyle
替換為您希望用戶輸入的樣式。
- 設(shè)置
leniency為YES(啟用heuristics)
numberFormatter.lenient = YES;
- 將字符串轉(zhuǎn)化為數(shù)字對象
NSNumber *number = [numberFormatter numberFromString:inputString];
Computing Dates Using Calendars - 使用日歷計算日期
NSCalendar類封裝了日歷的所有區(qū)域差異和復(fù)雜性,如表4-7所示。 era在某些日歷上的變化比其他日歷上更頻繁 - 例如,日歷中的era隨著每個新皇帝的變化而變化。 每年的月數(shù)可以是12或13個月。每個月的時間長短可能會有所不同。 即使在公歷中,一周的第一天可能是周六,周日或周一。 NSCalendar對象了解時區(qū)以及哪些區(qū)域可以觀察夏令時。 日歷計算(如本月的第三個星期二)取決于用戶的日歷和地區(qū)。

因此,對所有日歷計算使用NSCalendar類,例如計算一個月中的天數(shù),計算增量值以及獲取日期的組件。 您可以使用NSDate對象進行內(nèi)部計算,但使用NSCalendar對象計算面向用戶的日期。
要獲取用戶區(qū)域設(shè)置的日歷,請在NSCalendar類中使用currentCalendar類的方法:
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
使用NSDateComponents對象獲取date的calendar units。
To get the components of a date - 獲取date的組成
- 創(chuàng)建一個NSDateComponents對象
NSDateComponents *components = [[NSCalendar currentCalendar]
components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSEraCalendarUnit
fromDate:[NSDate date]];
- 獲取時代、年、月和日的值。
NSInteger day = [components day];
NSInteger month = [components month];
NSInteger year = [components year];
NSInteger era = [components era];
提示:任何時候您獲取或設(shè)置年份,也可以獲取或設(shè)置era。 Era不是
Gregorian calendar所必需的,但它對于其他幾種日歷是必須的。
有關(guān)使用NSCalendar和NSDateComponents類的更多信息,請閱讀Date and Time Programming Guide或觀看WWDC 2013: Solutions to Common Date and Time Challenges。
Registering for Locale and Time Zone Changes - 注冊區(qū)域和時區(qū)更改
要接收區(qū)域設(shè)置更改通知,請將您的對象添加為NSCurrentLocaleDidChangeNotification通知的觀察者:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(localeDidChange :) name:NSCurrentLocaleDidChangeNotification object:nil];
要接收時區(qū)更改的通知,請觀察NSSystemTimeZoneDidChangeNotification通知。 例如,如果用戶在旅行,則在您的應(yīng)用運行時,時區(qū)可能會發(fā)生變化。 自上次您的應(yīng)用程序處于活動狀態(tài)以來可能會過去很長一段時間。
實施更改通知方法,以使用用戶的新區(qū)域設(shè)置重新格式化并顯示所有面向用戶的日期,時間和數(shù)字。
后記
本篇主要介紹了使用區(qū)域設(shè)置格式化數(shù)據(jù),感興趣的給個贊或者關(guān)注,謝謝~~~~
