Non-English default language for iOS App?
Asked Answered
C

4

40

I am developing an app for a client in Europe. I am an English-speaker in the US. Our app is going to support a number of languages, but not English. I have all the strings in our app in translated Localized.strings files, set up correctly for the different languages, and they all work fine when the device is set to the correct language (device's language is German = app is correctly localized for German).

There is a problem when the device is not set to one of the languages we support, for example, on my phone which is set to English. We want the phone to fall back to German in cases like this, but that is not happening. What we are seeing is that the phone is using the language that appears highest on the Language list in the International section of Settings.app. For my phone, the highest non-English language on the list is French, so when I run the app, it is localized for French. If I change my phone to German and then back to English (which changes the order in the Languages list), the app then localizes to German.

How can I ensure the app defaults to German for non-supported languages? I used this tutorial to set up the locales for the project. This includes removing the default "English" locale that is created when you first localize a file. In the project file, I've added:

developmentRegion = de;

Also, in the Info.plist, I have

<key>CFBundleDevelopmentRegion</key>
<string>de</string>

With no success.

Any ideas would be appreciated!

Charterhouse answered 1/11, 2010 at 19:24 Comment(0)
T
46

Defaulting to a particular language is not what you should strive for. Suppose a japanese user living in France and fluently speaking French has his phone set to Japanese. Your App would default to German, despite it having a French translation; I guess that's not what you want and it's certainly not what the user wants.

For this reason I suggest to respect the language prioritization as set by the user.

Since you don't want to support English but have developed the App in English, the easiest thing you can do is to just get rid of en.lproj right after compiling. This will leave the app with only the languages you plan to support, and the iPhone will chose the language best suited for the user, as set in iPhone's defaults.


There is a pretty straightforward solution to deleting a specific localization:

Let Xcode build the App with all the present localizations and just before code-signing kicks in delete the en.lproj folder and all localized files for that language are gone. You can easily do this by adding a Run Script build phase to the target, containing this one line of code (it's a Bash Script):

rm -r "${TARGET_BUILD_DIR}/${PRODUCT_NAME}.app/en.lproj"

Code Signing always kicks in after all build phases have completed, so just put that build phase at the end of your current phases.

Note that this increases the time to build because Xcode recreates all English files, so you might want to disable this step during testing.

I hope that's a viable solution for you.


Concerning "the app must fall back to German in the case that an appropriate localization doesn't exist":

Question is what is an appropriate localization? If the user's third choice is French (after 2 unsupported languages), this solution will make the app fall back to French, which is an appropriate localization. More appropriate than setting the user's fifth choice, German, by hand.

What happens when an app launches is simple: The OS descends the users language list, as set in Preferences, until it finds a matching localization, and uses this language. The reason many apps default to English and not German is simply because English appears on most user language lists above German. There is no inherent language preference to the system. If you delete the English translation, only the languages you want to support are there, and of these languages the one higher on a user's list is taken.

Tubuliflorous answered 4/11, 2010 at 8:23 Comment(7)
Pascal has the right answer: The application will fall back to the next most reasonable localization; this is by design, and is the way all applications on iOS and Mac OS X are supposed to work. Your app is not special.Bernita
I'm still mulling this answer. While this obviously a well thought-out response, at the end of the day, the business requirement is still that the app must fall back to German in the case that an appropriate localization doesn't exist; this is non-negotiable with the client. What is interesting, and what I am alluding to in the title of my question, is that if the English.lproj folder is kept in the project, it IS used as the fall-back when there is no other localization available. If I can't figure anything else out, I'll just keep that folder around, and copy the "de" assets in there.Charterhouse
No, English is also not a system default. It's simple, the OS has a list of localizations, as set in the preferences. When starting an app, it looks for corresponding *.lproj folders and uses the first one that matches a language from the list. That's why it uses English when nothing else is around. ;) But I know another trick, will formulate a new answer...Tubuliflorous
Apple's documentation makes it sound like iOS does not support language prioritization (only supported in OS X): Because iOS-based devices support only one user, only one language at a time is selected. In Mac OS X, the Language & Text system preference panel lets the user designate both a preferred language and one or more fallback languages in case the preferred language is unavailable.Saddletree
@Jon-Eric: It's true that iOS does not offer the same language prioritization as OS X, however internally it works this way. If you change the language to e.g. Japanese, then back to e.g. English, Japanese will be treated as your second choice. Try it and look at the output of [NSLocale preferredLanguages]. But indeed that's not obvious to the user, I forgot that you can't rearrange but merely select your preferred language on iOS.Tubuliflorous
Pascal: thanks for the info about the preferredLanguages. It seems to be what is deciding the actual lang used in an app more than CFBundleDevelopmentRegion (which probably very rarely is used at all then!). However, changing between German and Japanese repeatedly always kept English as 2nd preferred language. Actually selecting any non-English language, English will always be number 2. Well, as far as I've tried. There seems to be no way of having another default language than English, UNLESS you delete English altogether from the app.Waldenses
Ingenious answer :) I've edited the paths to work with iOS 6.Foregather
T
14

I don't like posting this answer since it runs against Apples Human Interface Guidelines. Localizations are something the user should set, not something management should decide, so managers requiring a certain default language don't understand nothing and should change business.

That being said, there is a way to force iOS using certain languages in a certain order. I mainly use this to debug localizations without the need to set the device language to something else, whether it is possible to use this to solve the nonexistent problem in this question I can't tell.

There is a key AppleLanguages in the user defaults that dictates the order of languages to be used, normally set to the order the user sets in iOS's preferences. If you change this order, the app will try to find localizations in that order first. What you could do is read the current language preferences and decide to default to German as follows:

NSArray *langOrder = [NSArray arrayWithObjects:@"de", nil];
[[NSUserDefaults standardUserDefaults] setObject:langOrder forKey:@"AppleLanguages"];

Note that you need to do this in main.m before UIApplicationMain, otherwise you need to restart the app for this change to take effect.

I cannot state enough that nobody should do this in a real app, unless you go all the way and implement a preference setting that allows the user to change the language manually. If you just default to a given language, the user has no option to change your choice.

Tubuliflorous answered 9/11, 2010 at 11:40 Comment(6)
We have a real world example that does not break any HIG or whatsoever. Moreover I thank Pascal for answering (albeit after an exsuse). I hate when people answer with a suggestion/counsel/guidance that is not pertinent to the tech question: either you answer, or you don't.. anyway,the case: we are developing an app for theinternational market (thus, it's in english) but we have to provide a customized version for an Italian client. The codebase is the same, and we want to force (as per client request) the customized version in Italian. Regardless of the user settings (i.e. on my dev iPad)Airfoil
This is useful but if I have Launch splash screen with internationalisation , this does not apply the correct image, even if I put the code on main.m, do you know how I can fix it? ThanksOkubo
The HIG is a set of Guidelines (not Rules) for a reason. In my case, the app is a Point-of-Sale Enterprise app and needs to do business in the currency of the store location. The prices retrieved from a server database are IN Euro, USD, Yen or whatever. If the user sets the locale to something else, bad things happen. Unfortunately my app can't get the store's (a.k.a. server) locale until we are well past main.m. Do I have any option other than comparing the device's locale to what the store requires and displaying an alert?Rove
@KevinOMara Since the store requires specific currencies I wouldn't even bother with locales and just use what the store requires you to use.Tubuliflorous
@Airfoil Only now saw your comment. You'd be better off writing a build script that deletes all languages but Italian, as per my accepted answer. Problem solved.Tubuliflorous
@zontar: I disagree. Not having a comment about how this breaks the guidelines would incite people to do it without thinking about the consequences. If you have a good reason to break the guidelines, then well, they're only guidelines, you can break them if you need to, and Pascal gave you a detailed answer to enable you to do just that. But if you don't have a strong reason to break the guidelines, just refrain. It's good that the advice is there. It doesn't harm you, and it will prevent a lot of other developers to do the wrong thing without knowing.Pathway
P
-1

Try this in your didFinishLaunchingWithOptions() function

[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"de_DE", nil] forKey:@"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
int retVal = UIApplicationMain(argc, argv, nil, nil);
Pad answered 7/10, 2014 at 14:9 Comment(0)
H
-1

To make the default language as a particular one this following code works like a charm which is already described in this page. Here is the swift version: (Swift 4.2)

let arr = NSArray(objects: "ja")
UserDefaults.standard.set(arr, forKey: "AppleLanguages")
Hayashi answered 19/4, 2019 at 8:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.