How to change app locale independently from iOS system locale

Flags of european languagesI just want to share a trick on how to gain control over the Locale used for your app. The following code snippet is put in the main-method which kicks of your app.

But basically you should call this code snippet in your app and then make the user quit/terminate the app afterwards to restart with the new set default language AND set these parameters here again depending on a flag you may have stored elsewhere. Because actually all those set default values are actually already used at an earlier point in time i.e. for date formatting.

int main(int argc, char *argv[])
{
    @autoreleasepool {
        
        // OVERRIDE LOCALE (BASICALLY DO THIS WHILE APP RUNS AND LET USER RESTART APP)
        BOOL shouldOverrideLocale = NO; // LET'S TRY TO OVERRIDE IT WITH en_US
        NSString *languageIdentifier = @"en";
        NSString *countryIdentifier = @"US";
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        
        if( shouldOverrideLocale ) {
            NSLog( @"OVERRIDING SYSTEM LOCALE WITH : %@_%@",languageIdentifier, countryIdentifier );
            [defaults setObject:[NSArray arrayWithObject:languageIdentifier] forKey:@"AppleLanguages"];
            [defaults setObject:[NSArray arrayWithObjects:languageIdentifier, nil] forKey:@"NSLanguages"];
            [defaults setObject:[NSString stringWithFormat:@"%@_%@", languageIdentifier, countryIdentifier] forKey:@"AppleLocale"];
            [defaults synchronize];
        }
        else {
            NSArray *keysToRemove = @[@"AppleLanguages",@"NSLanguages",@"AppleLocale"];
            NSLog( @"RESETTING TO USE SYSTEM LOCALE" );
            @try {
                for( NSString *currentKey in keysToRemove ) {
                    if( [defaults objectForKey:currentKey] ) {
                        [defaults removeObjectForKey:currentKey];
                    }
                }
            }
	        @catch (NSException *exception) {
	            // NOTHNG TO CATCH HERE
	        }
	        @finally {
				[defaults synchronize];
	        }
        }
        NSString *languageCode = [[NSLocale autoupdatingCurrentLocale] objectForKey:NSLocaleLanguageCode];
        NSString *countryCode = [[NSLocale autoupdatingCurrentLocale] objectForKey:NSLocaleCountryCode];
        NSLog( @"USING SYSTEM LOCALE: %@_%@", languageCode, countryCode );

        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

If you use this code, keep in mind, that strings and processes related to In-App-Purchase are still delivered in the native language of the user.

See also my Example App in the Github repo called LocaleOverrider.


preview

There may exist other ways of doing this. It may also be the better approach to handle all localization on your own an reinitializing NSBundle usage.

A more advanced insight into localization issues provides help on all the NSNumberFormatter and NSDateFormatter thingys, too. It is written by Ray Lillywhite and has the title „The Nitty Gritty of iOS Internationalization and Localization“.

Update 26.12.2018
How to change language elegantly at runtime.

Why do I blog this? I mentioned this code in UISprech podcast and I want to make it available to others. But be warned, it has side effects of providing the user e.g. with inconsistent language when he enters IAP e.g. and you need to find a way to elegantly terminate the app after you configured the new default language. (Pro-Tipp: shutting down an app that is already in the background won’t be noticed as a crash.)

Bremer Bäder Öffnungszeiten 2014

Aus aktuellem Anlass mal ein vereinfachter Plan für mich.

Offizielle Infoseite der Bremer Bäder

WARNHINWEIS


Nichts is so wie es scheint!

Das was bei den Bremer Bädern gemeinhin als Öffnungszeiten bezeichnet wird bezeichnet nur den Ausnahmefall, falls keine Landesmeisterschaften, keine Polizeimeisterschaften, keine DLRG Meisterschaften, keine sonstigen Schwimmwettkämpfe oder ein zufälliger nuklearer Fallout über der Schwimmbahn zu dem Zeitpunkt stattfinden zu dem man meint man komme da rein.

News: Das Horner Bad soll angeblich am Montag 2. Juno 2014 öffnen.

Das habe ich zumindest durch einen persönlichen Besuch direkt beim Bad in Erfahrung bringen können. Dort vor Ort hing lediglich der Internettext ausgedruckt „hinter Gittern“.

horner_bad

Why do I blog this? Weil ich mich jedes Mal maßlos aufregen könnte, dass das einzige Bad in dem man Schwimmsport machen kann (50 Meter Bahn) so unzugänglich für die Öffentlichkeit ist. Und weil ich es unmöglich finde, wie eine Stadt wie Bremen zusätzlich noch die Infrastruktur der Bäder so runterwirtschaften kann. Da wird Geld zum Fenster rausgeworfen für Spaßbäder, aber für ernsthaft sporttaugliche Infrastruktur fehlt das Geld. Für mich ist ein Ausgleich zur Arbeit ein Standortfaktor und Schwimmen ist mit das gesündeste was man seinem Körper als Ausgleich geben kann. Leider ist das in Bremen nahezu unmöglich, aber das Bad ist ja eh schon von Schließung bedroht, von daher hat sich das Problem bald eh von selbst erledigt. Nur wie sollen bitte leistungsfähige Menschen Bremen als Standort ernsthaft in Betracht ziehen, wenn der wichtigste Ausgleich zur Arbeit quasi unmöglich gemacht wird? Ich könnte mich echt nur aufregen über soviel katastrophales Management. Öffnungszeitenänderungen werden mit Vorlaufzeiten von oft weniger als einer Woche durchgezogen, ich muss mich also schon eine Woche vorher informieren, ob ich am Wochenende überhaupt reinkomme oder wieder nicht. Und dann bleibt nur unter der Woche morgens zwischen 7 und 9 wie toll. Richtig Frühaufsteherfreundlich! Und wo bleiben die die eher nach 1700 oder 1800 Uhr können? Richtig am einzigen Tag wo das geht am Mittwoch… wenn nicht grade die ganze Woche das Bad für die Polizei-Landesschwimmmeisterschaften gesperrt wird. WEIL DIE POLIZEI, die kann ja NUR UNTER DER WOCHE! Ich rege mich auf…