Storing preferences that ship with the iPhone without a Settings App - iphone

I want to ship my iPhone app with some preferences but I don't need to create a "Settings App" using a plist and all that. I would like to do this using NSUserDefaults and know how to store and retrieve using this class. However, I'm struggling with how to have an initial set of preferences there when the user loads the app for the first time. Should I retrieve my NSUserDefaults in ViewDidLoad and if they return nil, set them at that point? Or is there a better method?

I'd do it like you proposed. Check whether the user default keys do exist already and if not, create them using default values.
Where you do this check is up to you, but of course it should happen before any part of your app actually needs some of the info. So, like mbehan suggested, you might want to perform that init check within didFinishLaunching of your appdelegate.

There's a method for that:
[[NSUserDefaults standardUserDefaults] registerDefaults:aDictionary];
The method takes a dictionary of keys/values for NSUserDefaults to use if the user hasn't set anything more specific.
You need to call this every time the app starts. Apple suggest:
The contents of the registration domain are not written to disk; you need to call this method each time your application starts. You can place a plist file in the application's Resources directory and call registerDefaults: with the contents that you read in from that file.

I spent some time reviewing the iPhone documentation and multiple posts. I think the following is adequate for most purposes if you do not want to create settings for your app in the Settings application.
Here is a code snippet that you can drop in AppDelegate didFinishLaunching:
NSString *test = #"Test";
NSString *testKey = #"TestKey";
NSString *test2 = #"Test2";
NSString *test2Key = #"Test2Key";
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:test,testKey,test2,test2Key,nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dict];
/*
Alternative if we want to create default values in a file called Defaults.plist in Resources folder
[[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Defaults" ofType:#"plist"]]];
To set the preference within the app:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:#"MyNewTest" forKey:#"TestKey"];
To retrieve the preference within the app:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *results = [defaults stringForKey:#"TestKey"];
Can also use the following syntax:
intForKey:
floatForKey:
boolForKey:
objectForKey:
Returns Objective-C object like NSString, NDDate, or NSNumber
If the object is not a string, may need to specify the value, such as
Label.text = [[defaults objectForKey:#"TestPreferenceStoredAsNumber"]stringValue];
*/
Place the following in AppDelegate applicationWillTerminate and applicationDidEnterBackground:
[[NSUserDefaults standardUserDefaults]synchronize];
Then to view the preferences, place this code in a convenient spot:
// View all keys and values in Console
NSLog(#"%#", [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]);

Related

Sharing NSUserDefaults plist file?

I'd like to use the features of NSUserDefaults for saving state. I do currently have that working. But I want to copy this plist file and apply it to the same app on another device.
Is there some way to pass a file name to NSUserDefaults or do I need to use some other class? Or is it fine to share the plist with the same app another device?
The app on device1 and device2 is the same app. I'm not trying to share data between different apps.
Would passing it as a dictionary work for you?
NSDictionary *dict = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
Then on the other device:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
for (NSString *key in dictionaryRepresentation.allKeys) {
id ob = dictionaryRepresentation[key];
[defaults setObject:ob forKey:key];
}
Or, you could write the dict to a .plist file, transport that over, decode from .plist to dict and do as I have above.
Writing to a .plist file:
[dict writeToFile:#"path/to/your/file.plist" atomically:YES];
Reading from a .plist file:
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:#"path/to/your/file.plist"];
If they're both your apps, you could look into using app groups to have both apps access a shared container. You'd use NSUserDefaults as usual in this scenario.
Otherwise, you can't pass in a file name or URL to NSUserDefaults. You'd need to either roll your own with NSDictionary + archiving, or just do that one time – i.e. copy the current defaults to a plist, transfer that over somehow, and then write the values to the defaults.

NSUserDefaults not saving in iOS 7

I'm having this issue with NSUserDefaults. It is saving the defaults until I kill the app in the background then when I return all the defaults are gone. They are also gone every time a build a new version onto my device. But again, they are there within app so long as I don't kill it in the background. It's working fine in iOS 6. Thoughts?
Take your value in string(or any other as per your requirement) and save the string in user defaults
NSUserDefaults *userdefault=[NSUserDefaults standardUserDefaults];
NSString *str=[NSString stringWithFormat:#"%#",[dicUser objectForKey:#"device_token"]];
[userdefault setObject:str forKey:#"YOURKEY"];
Since you haven't your code, so i am giving example which is perfectly working for me on iOS 7, give it a try. Hopefully works for you too.
For saving boolean value
bool flag = YES;
[[NSUserDefaults standardUserDefaults] setBool:flag forKey:#"flag"];
For retrieving boolean value
bool flag = [[NSUserDefaults standardUserDefaults] boolForKey:#"flag"];
make sure few things like you have declared the userDefaults before using it and if you've taken that in you AppDelegate file then here is a sample code how i am saving values and it works fine so try it this way
APP_DELEGATE.userDefaults = [NSUserDefaults standardUserDefaults];
[APP_DELEGATE.userDefaults setObject:#"unChecked" forKey:#"CheckMark"];
[APP_DELEGATE.userDefaults synchronize];
here APP_DELEGATE is declared like this in my AppDelegate.h file
#define APP_DELEGATE ((AppDelegate*)[[UIApplication sharedApplication] delegate])
hope it helps!

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 save variables after application shut down?

I want to save some integers after application shut down and restore them after application opening, what is the easiest way to do this?
You should store and load data from NSUserDefaults:
http://developer.apple.com/library/IOS/#documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// to store
[defaults setObject:[NSNumber numberWithInt:12345] forKey:#"myKey"];
[defaults synchronize];
// to load
NSNumber *aNumber = [defaults objectForKey:#"myKey"];
NSInteger anInt = [aNumber intValue];
Check out the NSUserDefaults documentation. You can set arbitrary key-value pairs there which (as long as you call the shared user defaults object’s -synchronize at some point before your app terminates) will persist between launches.
You can save them in the NSUserDefaults. This is mainly used for preferences.
[[NSUserDefaults standardUserDefaults] setObject:someInteger forKey:#"someIntegerKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
You can also save them to a Property List file if you have more data you'd like to store.
NSDictionary *someDictionary = [NSDictionary dictionaryWithObjectsAndKeys:someInt1, #"someIntKey1", someInt2, #"someIntKey2", nil];
[someDictionary writeToFile:somePath error:&error];
To save upon exiting the app place any code in
- (void)applicationWillTerminate:(UIApplication *)application
Look into using NSUserDefaults. This works like a dictionary that you can add key/value pairs to. You save the variables in your app delegate's applicationWillTerminate and applicationDidEnterBackground methods. You load the variables again in applicationDidFinishLoading.
The easiest way is to use NSUserDefaults. Your app delegate will get an -applicationWillTerminate: message when the app is about to shut down, and you can write your data to NSUserDefaults (or write it into your own file if the amount of data is large). Then, when your app starts up again, your app delegate will get an -applicationDidFinishLaunching, and you can read your data back again.
Serialize them and store them on memory. You have to do this before shut down and load when app is reopened

Making an in-app settings page (iPhone)

I am making an app which needs a settings page. Which will be a different class, so how do I pass data from one class to the other? For example: There is a UISwitch on the settings page, and I need to see what option the user selected for another class.
Thanks.
On your settings page, use the following code to synchronize your settings -
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject: data forKey: #""]; // The forKey is the name of the setting you're going to sync
[defaults synchronize];
And to get the value of the setting in your other controllers, use the following -
NSString *settingValue = [[NSUserDefaults standardUserDefaults] objectForKey: #""]; // The objectForKey is the name of the setting you're getting the value for.
Hope this helps you!