Technical Q&A QA1391

How can I determine the order of the languages set by the user in the Language tab of the International preference pane?

Q:  How can I determine the order of the languages set by the user in the Language tab of the International preference pane?

A: How can I determine the order of the languages set by the user in the Language tab of the International preference pane?

As documented at Internationalization Programming Topics: Getting the Current Language and Locale, most developers do not need to deal with the order of the languages as the appropriate localization will be chosen by the system automatically, and for a finer control, developers can use the CFBundle localization-related APIs.

But there may be situations where you want to get the list of languages directly from the user preferences.

Retrieving the languages in Cocoa

The documentation explains how to retrieve this list with a Cocoa example:

Listing 1  Retrieving the languages in Cocoa (short).

NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; NSArray * languages = [defaults objectForKey:@"AppleLanguages"]; NSLog(@"%@\n", languages);

which would return the following printout:

Listing 2  Languages printout.

(en, fr, de, es, it, nl, sv, nb, ja, "zh-Hans", da, fi, pt, "zh-Hant", ko, hu)

It may be worthwhile to note that the code could also have been written as:

Listing 3  Retrieving the languages in Cocoa (expanded).

NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
NSDictionary * globalDomain = [defaults persistentDomainForName:@"NSGlobalDomain"];
NSArray * languages = [globalDomain objectForKey:@"AppleLanguages"];
NSLog(@"%@\n", languages);

Since the AppleLanguages key is in the global domain of the user defaults.

Since you cannot count on the data to be in canonical form, it is imperative that you use the CFLocale APIs to convert the entries of the AppleLanguages dictionary in canonical forms.

If you are building your code for Mac OS X v10.4 and later, you can use the CFLocaleCreateCanonicalLanguageIdentifierFromString API.

If you are building your code for Mac OS X v10.3 (Panther) and later, you can use the CFLocaleCreateCanonicalLocaleIdentifierFromString API.

If you are building your code for Mac OS X v10.2 (Jaguar) or earlier, you will have to use your own table mapping non-canonical forms to canonical forms.

Retrieving the languages in Terminal

In Terminal, you could obtain the exact same printout with:

Listing 4  Retrieving the languages in Terminal (expanded).

defaults read NSGlobalDomain AppleLanguages

or

Listing 5  Retrieving the languages in Terminal (short).

defaults read -g AppleLanguages

Retrieving the languages in Carbon

To retrieve this order of languages in Carbon you use:

Listing 6  Retrieving the languages in Carbon.

CFArrayRef languages = CFPreferencesCopyValue(
         CFSTR("AppleLanguages"),
         kCFPreferencesAnyApplication,
         kCFPreferencesCurrentUser,
         kCFPreferencesAnyHost);
CFShow(languages);

which would printout:

Listing 7  Carbon Languages printout.

<CFArray 0x30a5d0 [0xa07ba150]>{type = immutable, count = 16, values = (
    0 : <CFString 0x309b10 [0xa07ba150]>{contents = "en"}
    1 : <CFString 0x30a4c0 [0xa07ba150]>{contents = "fr"}
    2 : <CFString 0x30a4d0 [0xa07ba150]>{contents = "de"}
    3 : <CFString 0x30a4e0 [0xa07ba150]>{contents = "es"}
    4 : <CFString 0x30a4f0 [0xa07ba150]>{contents = "it"}
    5 : <CFString 0x30a500 [0xa07ba150]>{contents = "nl"}
    6 : <CFString 0x30a510 [0xa07ba150]>{contents = "sv"}
    7 : <CFString 0x30a520 [0xa07ba150]>{contents = "nb"}
    8 : <CFString 0x30a530 [0xa07ba150]>{contents = "ja"}
    9 : <CFString 0x30a540 [0xa07ba150]>{contents = "zh-Hans"}
    10 : <CFString 0x30a560 [0xa07ba150]>{contents = "da"}
    11 : <CFString 0x30a570 [0xa07ba150]>{contents = "fi"}
    12 : <CFString 0x30a580 [0xa07ba150]>{contents = "pt"}
    13 : <CFString 0x30a590 [0xa07ba150]>{contents = "zh-Hant"}
    14 : <CFString 0x30a5b0 [0xa07ba150]>{contents = "ko"}
    15 : <CFString 0x30a5c0 [0xa07ba150]>{contents = "hu"}
)}


Document Revision History


DateNotes
2006-12-19

New document that retrieving the order of the languages set by the International preference pane in Cocoa, Carbon, and Terminal.