I just wrote a few values to my user preferences using NSUserDefaults. Is there a way I can go in and examine the persisted preferences file manually (when running on the simulator) to make sure they were written properly?
See related: Easy way to see saved NSUserDefaults?
NSString *text = [[NSUserDefaults standardUserDefaults] stringForKey:#"ValueName"];
NSLog(#"%#",text);
Related
I want to change the language of my app. At the moment I am doing it at the following way.
I have two buttons which are change the languages in NSUserDefaults. But before this affects my app I need to restart it.
Here is my code.
- (IBAction)changeDutch:(id)sender {
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:#"nl", #"en", nil] forKey:#"AppleLanguages"];
}
- (IBAction)changeEnglish:(id)sender {
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:#"en", #"nl", nil] forKey:#"AppleLanguages"];
}
This works fine. But I don't want every time to restart my app. Can anyone tell me how to do that?
Kind regards!
Check out HMLocalization: https://github.com/HeshamMegid/HMLocalization
It's a replacement for the default localisation framework. It has a demo showing how to change language without having to restart the app.
There is a method to change app language without restart mentioned this tutorial post I've tried it in an app and it works mostly but still if you are using system items like More tab in tabbar, Edit button on MoreNavigationController and Cancel button on UISearchBar and so on, there text can't be changed for selected language without restarting app. If there is no such item that is controlled by iOS instead of your app, this is a perfect solution for you.
If your data is in UITableView then you could use [tableView reloadData];.
You can even set the app languages in appDelegate, defined in Constants, keys, then on the IBAction call those keys then be stored in NSUserDefaults.
which way you're using for localization, I mean to ask is that native in which we just only maintain the folder structure or taken from Db.
Anyways, If you're using native part, then look at following link which may assist you as I think we can replace the language option there:
"http://stackoverflow.com/questions/3910244/getting-current-device-language-in-ios"
(Frankly speaking, I've no idea)
But if you are using the db part, then in that case you just use some enum based tact and according to which just fetch your data, that approach is simple as I've already applied in so many apps.
In any concern, just back to me. :)
I just started using the preferences pane to let users customize some settings in my iOS app, and it was pretty easy to create the Settings.bundle and access the information from it. My problem is that I read in the Apple docs that the settings should be programatically initialized:
It is recommended that you register any default preference values programmatically at launch time in addition to including them in your settings bundle property lists. For newly installed applications, default preference values from the application’s settings bundle are not set until the Settings application runs. This means that if the user runs your application before running Settings, the default values specified in your settings bundle will not be available. Setting such values programmatically at launch time ensures that your application always has appropriate values. To register default values programmatically, use the registerDefaults: method of the NSUserDefaults class.
Where in the app is this initialization done, and how can I be sure that I'm not overwriting a user-supplied value? Is this handled in some method of the App Delegate?
You should register your defaults before you try to access a value stored in your NSUserDefaults.
You could do it in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions.
Registering your defaults is fast, so there is no need to optimize this. Just do it at the launch of the app.
I store my userdefaults in a plist and register the content of this list, like this:
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"DefaultUserDefaults" ofType:#"plist"]];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
If you register your defaults like this you don't have to worry that you overwrite user supplied values.
NSUserdefaults uses "domains" where it stores it's values. If you register your defaults they are stored in the registration domain. If a User stores a value those values are stored in the application domain.
If you try to get a value from NSUserdefaults it looks if the value is present in the application domain, and if it's not there it takes the value from the registration domain.
Edit:
you would access those values (or better, the values that are stored in your nsuserdefaults, and those as a fallback if there are no user provided values) like this:
NSInteger minutesToWait = [[NSUserDefaults standardUserDefaults] integerForKey:#"MinutesToWait";
NSString *urlString = [[NSUserDefaults standardUserDefaults] stringForKey:#"DefaultURLStr"];
The plist is just another representation of a NSDictionary with keys and values. The key is the same key you use to access the userdefaults, and the value is your defaultvalue.
Pretty straight forward.
It doesn't matter how you create the dictionary. You can do it in code as well.
As #fluchtpunkt suggested, you can register the defaults using:
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"DefaultUserDefaults" ofType:#"plist"]];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
Personally, I check for each value independently in my App Delegate.
#define kSettings [NSUserDefaults]
if([kSettings boolForKey:#"firstRun"] == nil){
//
// Set up the initial settings...
//
[kSettings setBool:NO forKey:#"firstRun"];
}
I write a "reset" method and then call it on first run. I prefer doing this in code, but you theoretically could use a plist. I just feel like it's one less place to go wrong.
You can use the same method inside your app delegate that you use to setup your initial window, didFinishLaunchingWithOptions:
However, you may also need some logic inside applicationWillEnterForeground:, because potentially your user could put your app into the background, change settings inside the settings app, then resume your app and expect those changes to have been applied.
#MatthiasBauch or #Moshe's answers will most likely work for most people, but for anyone who like me had their settings in a Root.plist file (I was using the InAppSettingsKit), you have to dig a bit deeper into that particular plist file to get the actual default values of the settings (since they're not at the top level of the plist, but nested under the key PreferenceSpecifiers). Here is a link to another answer here, containing the extra code that worked for me:
https://stackoverflow.com/a/10497898/381233
Having some trouble with NSUserDefaults here.
Here's how I'm creating it:
NSString *theCity = #"Test City";
[[NSUserDefaults standardUserDefaults] setObject:theCity forKey:#"SavedCity"];
Here's how I'm trying to retrieve it:
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"SavedCity"])
{
NSLog(#"Key exists! %#",[[NSUserDefaults standardUserDefaults] objectForKey:#"SavedCity"]);
}
else {
NSLog(#"No city saved!");
}
The problem I have is that even if there IS a key for "SavedCity" (I check the pref file in the Simulator directory), it always displays "No city saved". Am I doing something wrong?
Thanks!
Two things you could try.
1) Try synchronizing the user defaults after settings the string. [[NSUserDefaults standardUserDefaults] synchronize]
2) Try retrieving the string using -stringForKey:
I ran into a similar problem myself recently. Here's what fixed it for me.
From the iOS Application Programming Guide:
It is recommended that you register any default preference values programmatically at launch time in addition to including them in your settings bundle property lists. For newly installed applications, default preference values from the application’s settings bundle are not set until the Settings application runs. This means that if the user runs your application before running Settings, the default values specified in your settings bundle will not be available. Setting such values programmatically at launch time ensures that your application always has appropriate values. To register default values programmatically, use the registerDefaults: method of the NSUserDefaults class.
What you should add is:
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"SavedCity"] != nil)
Because you want to check if you've saved something.
I'm using Monotouch for iPhone/iPad development and I have a built in system where the user can submit a bug report from the app. It would be nice to capture their "settings" which I store in NSUserDefaults.StandardUserDefaults so I can see their exact configuration.
Anyone know how to capture the NSUserDefaults.StandardUserDefaults and write out to text or file to include in the e-mail?
Thank you.
You could save the NSUserDefaults as a plist. Might be easier to de-code on the other end.
NSDictionary *defaults = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
[defaults writeToFile:#"path" atomically:YES];
[EDIT]
I have no idea if this will work.
var = NSUserDefaults.StandardUserDefaults.DictionaryRepresentation();
Or just cycle through your properties and print them to a file?
NSUserDefaults.StandardUserDefaults.StringForKey("thisorthatKey");
I ended up just attaching the .plist file directly to the e-mail and that worked just fine.
I've got application settings working just fine. However, I'd like to be able to change my app settings from within my app.
It seems as though there should be some kind of generic way to add this functionality to my app without having to recreate all the controls myself. I mean, the code is already written in apple's settings app.
Maybe someone wrote this code and open sourced it? (if it is not already available)
I prefer my own Settings class as I don't like to write the same stuff again and again. Therefore I am using a method like ...
- (void) setValue:(id)value forKey:(NSString *)aKey {
[[NSUserDefaults standardUserDefaults] setObject:value forKey:aKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}
and fetching would be ...
- (id) valueForKey:(NSString *)aKey {
return [[NSUserDefaults standardUserDefaults] valueForKey:aKey];
}
A lot of people have thought the same; file a bug with Apple, and maybe eventually they'll listen.
I believe you're looking for NSUserDefaults. The documentation is available here.