< Previous PageNext Page > Hide TOC

Getting the Current Language and Locale

For most developers, choosing a localization to use is not something you ever have to do. The NSBundle and CFBundle interfaces automatically apply the user’s preferences to determine which localized resource files to return in response to a programmatic request. However, there may be situations beyond simply loading resources from a bundle that would require your program to know which localization was in use. For those situations, both NSBundle and CFBundle provides ways for you to get that information.

Contents:

Specifying Supported Localizations in Your Bundle
Getting the Preferred Localizations
Getting Canonical Language and Locale IDs
Getting Language and Locale Preferences Directly


Specifying Supported Localizations in Your Bundle

Before discussing the techniques of how to get localizations, it is important to remember how a bundle communicates its supported localizations to the system. Most bundled applications contain a Resources directory, inside of which reside language-specific project (.lproj) directories. Each of these .lproj directories contains the resources associated with a specific language or regional dialect. NSBundle and CFBundle look for these directories and use them to build a list of supported localizations. However, this is not the only way to build this list.

An application can notify the system that it supports additional localizations through its information property list (Info.plist) file. To specify localizations not included in your bundle’s .lproj directories, add the CFBundleLocalizations key to this file. The value for the key is an array of strings, each of which contains an ISO language designator as described in “Language and Locale Designations.”

Getting the Preferred Localizations

If you have a Carbon application or are using the CFBundle functions to manage your program bundle, you can use the CFBundleCopyPreferredLocalizationsFromArray function to get the most relevant localizations. When calling this method, you must pass in a list of localizations your software supports. You can use the function CFBundleCopyBundleLocalizations to generate this list for you using the bundle information.

This function compares the supported localizations against the user’s language and region preferences. From this comparison, it returns an array of strings, one of which is the language-only localization most appropriate for the user. If a region-specific localization is also available, it returns that localization as well, giving it preference over the language-only localization.

If you are writing a Cocoa application, you can use the preferredLocalizationsFromArray: and localizations methods of NSBundle to implement the same behavior as CFBundleCopyPreferredLocalizationsFromArray and CFBundleCopyBundleLocalizations. You can also use the method preferredLocalizations as a shortcut to perform both actions with a single method. As with the CFBundle functions, the preferredLocalizations and preferredLocalizationsFromArray: methods return an array of strings containing the language designators in use by the bundle.

Mac OS X stores each user’s list of preferred languages in that user’s defaults database, along with other system-wide and application-specific preferences. You can access this database using the preference-management routines found in both Core Foundation or Cocoa. An array of preferred languages is associated with the AppleLanguages key. The currently selected locale is associated with the AppleLocale key. Both of these keys are in the NSGlobalDomain.

Important: It is recommended you use the CFBundle functions or NSBundle methods to read the preferred locale and languages instead of reading the contents of the defaults database directly. The codes found in the database may not include the canonical forms of the language or locale IDs.

Getting Canonical Language and Locale IDs

Prior to Mac OS X v10.4, language dialects were specified by combining a language designator with a region designator. With the introduction of support for custom dialect codes (see “Language and Locale IDs”), getting the appropriate language code is now somewhat more complicated. Fortunately, Mac OS X provides routines to help you determine the appropriate language and locale codes based on the information you have.

In Mac OS X v10.3, the CFLocale opaque type was introduced in Core Foundation. One of the functions introduced with this type is the CFLocaleCreateCanonicalLocaleIdentifierFromString function, which takes the locale code you specify and returns an appropriate canonical version. This function is particularly useful for converting older locale strings, such as the older, English-based .lproj directory names, into the ISO-compliant names.

In Mac OS X v10.4, the CFLocaleCreateCanonicalLanguageIdentifierFromString function was added to perform the same canonical conversion for language and dialect codes. For example, this function converts the old specifier for traditional Chinese (zh_TW) to the more modern version (zh-Hant). Also in Mac OS X v10.4, Cocoa added the NSLocale class to provide Objective-C wrappers for the corresponding Core Foundation functions.

If you use CFBundle or NSBundle to retrieve language-specific resources from your bundle, then you do not need to worry about language identifiers directly. The CFBundle and NSBundle routines automatically handle language and locale IDs in canonical and non-canonical forms.

If your code requires Mac OS X v10.4 or later, you should start using the new canonical forms for language and locale IDs. Some older language codes are replaced by newer codes in v10.4. In addition to several of the Chinese language codes, support for the newer Norwegian ISO code (nb) is now available and should be preferred over the older version.

Note: If your program also supports versions of Mac OS X prior to 10.3, you may need to maintain your own table of canonical IDs.

Getting Language and Locale Preferences Directly

There may be situations where you want to get the preferred locale ID or the list of languages directly from the user preferences. Mac OS X stores each user’s list of preferred languages in that user’s defaults database. The list of preferred languages is identified by the defaults key AppleLanguages and is stored in the global variable NSGlobalDomain. You can access that list using the NSUserDefaults class in Cocoa or the Core Foundation preferences functions.

Important: If you get the user language preference from the defaults database, you must get the canonical form using the CFLocaleCreateCanonicalLanguageIdentifierFromString function (in Mac OS X v10.4 and later) or CFLocaleCreateCanonicalLocaleIdentifierFromString function (in Mac OS X v10.3 and later) before using the identifier.

The following example shows you to get the list of preferred languages from the defaults database using Cocoa. The returned array contains the languages associated with the AppleLanguages key in the user's preferred order. Thus, in most cases, you would simply want to get the first object in the array.

NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
NSArray* languages = [defs objectForKey:@"AppleLanguages"];
NSString* preferredLang = [languages objectAtIndex:0];

The locale for the current user is also stored in the defaults database under the AppleLocale key.

Important: Although you can get the user's preferred settings from the defaults database, it is recommended you use the CFBundle functions or NSBundle class instead. The associated functions and methods of those objects return the preferred language or locale that is also supported by your application. (Bear in mind that the returned values may not correspond directly with the user's exact preferences.)



< Previous PageNext Page > Hide TOC


© 2003, 2009 Apple Inc. All Rights Reserved. (Last updated: 2009-01-06)


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.