iOS: override NSLocale language - iphone

If you have a localized version of your app in several languages but if the user is not using any of the languages the app is localize.
How to set a default language? Or what will be the best practice to define a default language in this case?
Here are the scenarios I was trying to tackle:
The application has be localize in en/fr/es but if language locale is not en/fr/es how you define a default?
In case the the language locale is either one of this en/fr/es and the user whants to use a different language define on there NSUserDefaults. Let's say is using english as NSUserDefaults but wants to use the fr localized version of the aplication. There is a way to overwrite the language on NSUserDefaults ?

write the NSUserDefaults before the apps start
question1 : you can set your prefer order as below.
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:#"de", #"en", #"fr", nil] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
Question2: force to use fr
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:#"de", nil] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];

I'm finding this no longer works in iOS 9 (and probably 10). We have several targets in our code base. For a couple of them I always want it to come up in English even though localized strings may be present in the bundle.
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:#"en", nil] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
I have added the above code in main(). The first time the app runs it comes up in the user's chosen language. On subsequent runs it will come up in English as desired.
Can anyone confirm this doesn't work in iOS 9 and suggest an alternative? I'd rather not delete the other lproj entries if I don't have to.

Related

UIImagePickerController language not changed

In my app used
[[NSUserDefaults standardUserDefaults] setObject:#[#"fr"] forKey:#"AppleLanguages"];
this func to change app language.
It working fine all labels,button and all other elements. but, it is not replicated in UIImagePickerController.
Language change when i kill and reopen the app.
pls any suggestion.
Advance thanks
You need to synchronize your NSUserDefaults and change it like this:
[[NSUserDefaults standardUserDefaults] setValue:#"fr" forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
Next you need to use the macro :
NSLocalizedString(string, nil)
for the text inside your UIImagePickerController.
I change in Info.plist file string Localization native development region to my language, and then in app UIImagePickerController changed language. Maybe and for you it will work.

iOS able to read plist file on simulator but not on device

Previously I read posts with same problem but my question persists. My app needs to read firstly a plist file to get some parameters and, when loaded on device, is unable to read default settings plist (working on simulator). One solution should be copy that plist into documents directory, but only this one? Is device unable to read user defaults set in plist? if I copy it to docs directory, will device be able to associate keys for plist if has another location? I need to read user defaults before executing any function. Thank you.
-(void)loadSettings
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
self.userID = [[NSUserDefaults standardUserDefaults] stringForKey:#"userID"];
self.nom2 = [[NSUserDefaults standardUserDefaults] stringForKey:#"t2"];
self.nom3 = [[NSUserDefaults standardUserDefaults] stringForKey:#"t3"];
self.nom4 = [[NSUserDefaults standardUserDefaults] stringForKey:#"t4"];
self.currentGlobal = [[NSUserDefaults standardUserDefaults] stringForKey:#"versionApp"];
NSLog(#"Version App = %#", currentGlobal);
self.colorTab = [[NSUserDefaults standardUserDefaults] stringForKey:#"color"];
firstBoot = [[NSUserDefaults standardUserDefaults] boolForKey:#"firstBoot"];
[defaults synchronize];
}
It sounds like you just want to set some initial values in user defaults so your app can read them in. If that is the case then you'll simply want to use the registerDefaults: method of NSUserDefaults. Example:
[[NSUserDefaults standardUserDefaults] registerDefaults:
[NSDictionary dictionaryWithObject: [NSNumber numberWithBool:YES]
forKey: #"firstBoot"]];
The beauty of NSUserDefaults is you never have to mess with pList stuff or the iOS filesystem.
You do no need to copy the plist for the standardUserDefaults to the documents directory. You should let iOS create this file on its own and not include it with your app. If you need to set defaults, then you should use the registerDefaults: method on the standardUserDefaults instance to do so by passing in a dictionary of key-value pairs.
Have you looked at using NSUserDefaults?
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html
It automatically does what you are describing and you don't need to manage files. It's a simple API that you can read and write settings to and iOS takes care of storage for you.

How to store settings on iPhone immediately?

Is it possible to store settings on the iPhone immediately? The apps on iOS 4+ don't close on exit, and if I press 'Stop process' in Xcode settings are not saved? How to save them?
- (void)compLoad {
compTotal = [[NSUserDefaults standardUserDefaults] integerForKey: #"compTotal"];
compCount = [[NSUserDefaults standardUserDefaults] integerForKey: #"compCount"];
compShow = [[NSUserDefaults standardUserDefaults] boolForKey: #"compShow"];
}
- (void)compSave {
[[NSUserDefaults standardUserDefaults] setInteger: compTotal forKey: #"compTotal"];
[[NSUserDefaults standardUserDefaults] setInteger: compCount forKey: #"compCount"];
[[NSUserDefaults standardUserDefaults] setBool: compShow forKey: #"compShow"];
}
[[NSUserDefaults standardUserDefaults] synchronize];
synchronize - this method is automatically invoked at periodic
intervals, use this method only if you cannot wait for the automatic
synchronization (for example, if your application is about to exit) or
if you want to update the user defaults to what is on disk even though
you have not made any changes.
According to the documentation, the following call will persist any outstanding modifications. To check if this has been successful, check the return value of this call. A value of YES indicates success.
[[NSUserDefaults standardUserDefaults] synchronize];
Call your compSave in your AppDelegate
- (void)applicationWillResignActive:(UIApplication *)application
{
// Call your compSave here to force saving before app is going to the background
}
also
- (void)compSave
{
[[NSUserDefaults standardUserDefaults] setInteger: compTotal forKey: #"compTotal"];
[[NSUserDefaults standardUserDefaults] setInteger: compCount forKey: #"compCount"];
[[NSUserDefaults standardUserDefaults] setBool: compShow forKey: #"compShow"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Simply call [[NSUserDefaults standardUserDefaults] synchronize];. But usually you do not need to that: iOS will save once your app goes into background and also on a few other occasions. Calling synchronize too often is a considered to be a Bad Thing(tm).
Try using the synchronize method.
Update: you should consider registering your defaults, like it suggests in the Preferences and Settings Programming Guide:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Register the preference defaults early.
NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:#"CacheDataAgressively"];
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
// Other initialization...
}
Also, from this guide ("Synchronizing and Detecting Preference Changes"), regarding syncing:
To detect when changes to a preference value occur, apps can also register for the notification NSUserDefaultsDidChangeNotification. The shared NSUserDefaults object sends this notification to your app whenever it detects a change to a preference located in one of the persistent domains. You can use this notification to respond to changes that might impact your user interface. For example, you could use it to detect changes to the user’s preferred language and update your app content appropriately.
Pretty sure you still need to use synchronize if you want to re-read settings directly.

Language change after selecting a option from the drop down list in iphone

I was working with language localisation .I want to change the language of my application whenever i select a language from a drop down list which is present in my application , that is it should change the language without changing the language of device .please suggest me how can i implement
Thanks in advance
Have a look at this: How to force NSLocalizedString to use a specific language
You can do this, but it won't play nicely with the built in localization functions in Foundation (e.g. NSLocalizedString), so you'll need to ignore them and write your own string-getting function, XIB-loading path, etc.
The question and answer here covers how to access localizations in the bundle on the fly like this:
Overriding preferred strings localization on the fly for testing
You can force the "AppleLanguages" user default.
The example below shows how can be done; in particular here I'm switching the first (default) with the second language.
NSArray *lang = [[NSUserDefaults standardUserDefaults] arrayForKey:#"AppleLanguages"];
NSLog(#"current lang: %#",lang);
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:
[lang objectAtIndex:1],
[lang objectAtIndex:0],
nil]
forKey:#"AppleLanguages"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *languages = [NSMutableArray arrayWithArray:[defaults objectForKey:#"AppleLanguages"]];
[languages replaceObjectAtIndex:0 withObject:#"fr"];
[defaults setObject:languages forKey:#"AppleLanguages"];
[defaults synchronize];
This is setting the language to French. Just put on position 0 what language you want to be loaded.

Change locale for current iphone application (custom locale for NSBundle?)

i want to change the locale programmatically in my iphone app (basically because not all languages are supported by iphone itself, it should be possible for the user to switch language only for my application). I have seen on a different question How to force NSLocalizedString to use a specific language that on OSX apps? it should work with [[NSUserDefaults standardUserDefaults] setObject: [NSArray arrayWithObjects:#"de", nil] forKey:#"AppleLanguages"]; - but for me it doesn't...
[NSLocale currentLocale] still returns the system wide locale and the 'main bundle' gives me files from the system wide locale..
so.. is there a way to set a custom locale for my application? or - which would be sufficient for me - create a new NSBundle instance with a different locale?
ok, stupid me.. as the question linked already answered.. that code requires a restart.. ie. when the user selects another language call [[NSUserDefaults standardUserDefaults] setObject: [NSArray arrayWithObjects:#"de", nil] forKey:#"AppleLanguages"]; - the next time the application is launched the [NSBundle mainBundle] will return the correct resources for the given locale.. (although [NSLocale currentLocale] will still return the iphone-wide locale.. but i think this doesn't matter to me anyway...)