4

The 3 preferredLocalizations of Bundle are so confusing that I have so many questions:

  1. Why the 2 preferredLocalizations methods are class methods but keep talking about some unspecified specific bundle as if they are called on some individual Bundle instance?

    • preferredLocalizations(from:): What exactly are a bundle object and the bundle?

      1. Returns one or more localizations from the specified list that a bundle object would use to locate resources for the current user.

      2. An array of NSString objects, each of which specifies the language ID for a localization that the bundle supports.

    • preferred​Localizations(from:​for​Preferences:​): What exactly are the specified bundle and the receiver’s bundle?

      1. Returns the localizations that a bundle object would prefer, given the specified bundle and user’s language preferences.

      2. An array of NSString objects, each of which identifies a localization in the receiver’s bundle. These strings are ordered in the array according to the specified preferences and are taken from the strings in the localizations​Array parameter. If none of the user-preferred localizations are available in the bundle, this method returns one of the bundle localizations.

  2. Why preferredLocalizations(from: localizations) does't return the same result as preferred​Localizations(from: localizations, ​for​Preferences:​ nil)? As noted above reading their docs doesn't really help. Sure they look designed this way but actually not:

    // Locale.preferredLanguages: ["es-CN", "ja-CN", "zh-Hans-CN", "en-CN", "he-IL"].
    let localizations = ["de", "en", "es", "fr", "it"]
    print(Bundle.preferredLocalizations(from: localizations)) // ["en"]
    print(Bundle.preferredLocalizations(from: localizations, forPreferences: nil)) // ["es"]
    
an0
  • 17,191
  • 12
  • 86
  • 136

1 Answers1

3

The reference documentation isn't that great; Technical Note 2418 explains it better.

Specifically, it says

Note that Bundle.preferredLocalizations(from:) will restrict the results to localizations supported by Bundle.mainBundle(), or the return value of Bundle.mainBundle().localizations(). If you would like to match against a different set of language identifiers, use Bundle.preferredLocalizations(from:forPreferences:) which does not rely on mainBundle’s localizations and instead solely relies on the two arguments passed in.

So,

  • If you use Bundle.preferredLocalizations(from:), the localizations list you give it is first filtered against the localizations defined for the main bundle (Bundle.main.localizations).
  • If you use Bundle.preferredLocalizations(from:forPreferences:), it works with the list you give it.

In the example you gave, Bundle.preferredLocalizations(from: localizations) returns ["en"]. This is likely because your app does not have any version of Spanish ("es") defined. If you add a Spanish localization to your project, it should return ["es"], since "es-CN" is listed before "en-CN".

rjpadula
  • 944
  • 7
  • 7