NSUserDefaults: application.plist is reset whenever app starts - ios

I am using NSUserDefaults to store my app settings/configuration.
The code responsible to saving defaults is below:
NSUserDefaults * standardUserDefaults = [NSUserDefaults standardUserDefaults];
// saving settings
[standardUserDefaults setObject:address.text forKey:#"URL"];
[standardUserDefaults setObject:username.text forKey:#"username"];
[standardUserDefaults setObject:password.text forKey:#"password"];
// synchronize the settings
[standardUserDefaults synchronize];
Indeed, the settings seem to have been saved. I open plist file from Libary/Preferences and see that the values are saved. I see those after my method is finished working and [even after] after closing the app.
My problem: whenever I start my app again, the saved values are gone from the plist file[the keys are still present], and I obviously cannot load my preferences.
Please advise.

You can use to save Settings:
NSMutableDictionary *dictSetting = [[NSMutableDictionary alloc] init];
[dictSetting setValue:address.text forKey:#"URL"];
[dictSetting setValue:username.text forKey:#"username"];
[dictSetting setValue:password.text forKey:#"password"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:dictSetting forKey:#"SETTINGS"];
[defaults synchronize];
to Retrive Setting:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *dictSettingData = [defaults objectForKey:#"SETTINGS"];
NSString *url = [dictSettingData valueForKey:#"URL"];
NSString *username = [dictSettingData valueForKey:#"username"];
NSString *password = [dictSettingData valueForKey:#"password"];

Related

How can I save text data in an iOS application?

Using my application, the user will take a reading on my application, which will yield a string of text in this format: Reading, Date/Time, Gender, Age. Essentially, what I'm doing is taking this string and storing it in a table view in a different storyboard. Then, every time the application is closed and reopened, the saved values should remain. The action of saving the string should be triggered by pressing a save button. How can this be implemented? Sample code is appreciated.
The easiest solution is to use NSUserDefaults:
// Add a string & save permanently
NSMutableArray *savedStrings = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"SavedStrings"]];
NSString *sampleString = #"Reading, 4 Feb 2017, 12:00, male, 30 years";
[savedStrings addObject:sampleString];
[[NSUserDefaults standardUserDefaults] setObject:savedStrings forKey:#"SavedString"];
[[NSUserDefaults standardUserDefaults] synchronize];
// At launch, get saved strings - use to populate the tableview
NSMutableArray *savedStrings = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"SavedStrings"]];
I think this will help you...
//In firstViewController.m
// Create strings to store the text info
NSString *firstName = [self.firstNameTF text];
NSString *lastName = [self.lastNameTF text];
NSString *age = [self.ageTF text] ;
[defaults synchronize];
// Store the data with key.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:firstName forKey:#"firstName"];
[defaults setObject:lastName forKey:#"lastname"];
[defaults setObject:age forKey:#"age"];
//In requiredViewController.m write this code.
// Get the stored data before the view loads
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *firstName = [defaults objectForKey:#"firstName"];
NSString *lastName = [defaults objectForKey:#"lastname"];
NSString *ageString = [defaults objectForKey:#"age"];
// Set saved data in UIElements.
self.firstNameLabel.text = firstName;
self.lastNameLabel.text = lastName;
self.ageLabel.text = age;

How to set all data into a new .m file and run it in another?

So i would like to make a file called "SavedData.h" "SavedData.m" and store all my games saved data in these files...
How would I wire the whole process up to run in my "MainView.h" and "MainView.m"
I'm not that experienced with xcode...
The action in the MainView.m:
- (IBAction)btncheck:(id)sender {
if ([answer isEqualToString:#"Pizza Pie"]) {
//Name:Pizza Pie *SAVED
NSString *savestring = _textbox.text;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:savestring forKey:#"savedstring"];
[defaults synchronize];
}
_textbox is my textField
and in my SavedData.m:
//Name:Pizza Pie
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *loadstring = [defaults objectForKey:#"savedstring"];
[_textbox setText:loadstring];
}
How is this done?
& is it even possible?
I think you're aiming to save state to a file and restore it later (you wouldn't use source files for this, there's no compiler on the phone). Steps are:
Put whatever you want to save in a dictionary:
NSMutableDictionary *myState = [NSMutableDictionary dictionary];
myState[#"foo"] = #"bar";
Get a path to where you're app is allowed to save:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *pathFile = [paths[0] stringByAppendingPathComponent:#"mystate.plist"];
Save:
[myState writeToFile:pathFile atomically:YES];
Read it later:
myState = [[NSDictionary alloc] initWithContentsofFile:pathFile];
You can also build a mutable dictionary this same way (replace NSDictionary in the last line with NSMutableDictionary).

NSUserDefaults overriding previously saved values

I have two completely separate tasks being carried out but somehow they seem to connect.
In ViewController 1, I have:
NSString *foo = #"foo";
NSUserDefaults *default1 = [NSUserDefaults standardUserDefaults]
[default1 setObject:foo forKey:#"foo"];
[default1 synchronize];
and when I do:
NSLog(#"%#", [[NSUserDefaults standardUserDefaults] objectForKey:#"foo"]);
The value printed is what I expect it to be.
In ViewController 2, I have:
NSString *bar = #"bar";
NSUserDefaults *default2 = [NSUserDefaults standardUserDefaults]
[default2 setObject:bar forKey:#"bar"];
[default2 synchronize];
And same again when I NSLog it, the value is what I expect it to be.
But somehow when i try to print object #"foo" again it gives me the value for the second object, in this case #"bar"
Any guidance on why my original value is being overridden by the second value even tough the variable/key names are different in the 2 classes?
You are doing this for both:
[foo setObject:bar forKey:#"bar"];
Shouldn't it be:
[defaults1 setObject:foo forKey:#"foo"];
And
[defaults2 setObject:bar forKey:#"bar"];
There is however, a greater problem:
NSString *foo = #"foo";
NSUserDefaults *default1 = [NSUserDefaults standardUserDefaults];
[default1 setObject:foo forKey:#"foo"];
[default1 synchronize];
NSLog(#"%#", [[NSUserDefaults standardUserDefaults] objectForKey:#"foo"]);
NSString *bar = #"bar";
NSUserDefaults *default2 = [NSUserDefaults standardUserDefaults];
[default2 setObject:bar forKey:#"bar"];
[default2 synchronize];
NSLog(#"%#", [[NSUserDefaults standardUserDefaults] objectForKey:#"bar"]);
Will work properly, however you're creating defaults1 and defaults2 which are both instances of standard defaults, so:
NSUserDefaults * defaults1 = [NSUserDefaults standardUserDefaults];
NSUserDefaults * defaults2 = [NSUserDefaults standardUserDefaults];
[NSUserDefaults standardUserDefaults];
Are all pointers to the standardUserDefaults singleton. So they are identical instances. You could simply do:
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
NSString *foo = #"foo";
[standardDefaults setObject:foo forKey:#"foo"];
NSString *bar = #"bar";
[standardDefaults setObject:bar forKey:#"bar"];
[standardDefaults synchronize];
NSLog(#"%#", [[NSUserDefaults standardUserDefaults] objectForKey:#"foo"]);
NSLog(#"%#", [[NSUserDefaults standardUserDefaults] objectForKey:#"bar"]);
You can print out the entire set of user defaults with code like this
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *dictionary = [defaults dictionaryRepresentation];
NSLog( #"%#", dictionary );
Note that Apple puts lots of garbage in the user defaults, so you'll have to scroll to the end to see foo and bar. I'm guessing that you have a typo in code that you haven't shown us, and either foo is being overwritten, or foo simply isn't being displayed properly.
The current code in your question (after 1 edit) is all good and should work correctly.

Set switch position to ON by first app launch using NSUserDefaults

I have switches in my app that stores position by standardUserDefaults, but when app starts for first time all my switches are in OFF position. How can I set them to ON by default?
Save
NSUserDefaults *defs1 = [NSUserDefaults standardUserDefaults];
[defs1 setBool: blackSwitch.on forKey: #"blackKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
Load
NSUserDefaults *defs1 = [NSUserDefaults standardUserDefaults];
blackSwitch.on = [defs1 boolForKey: #"blackKey"];
First of all
Do the following
NSUserDefaults *defs1 = [NSUserDefaults standardUserDefaults];
BOOL isOn = [defs1 boolForKey: #"blackKey"];
if(isOn) NSLog(#"isOn");
Second asure that blackSwitch is not nil
if(blackSwitch) NSLog(#"blackSwitch is not nil");
If blackswitch is nil, that means that you are still in early stage of view controller initialization, you should move the code that sets it on to viewDidLoad or viewWillAppear
For setting default values please use this code
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSNumber *testValue = [NSNumber numberWithBool:YES];
NSDictionary *appDefaults = [[NSDictionary alloc] initWithObjectsAndKeys:
testValue, #"blackKey", nil];
[defaults registerDefaults:appDefaults];
[appDefaults release];
Use the NSUserDefaults method registerDefaults to pass a default value of 'true' along with your #"blackKey" key. This will ensure that #"blackKey" is set to ON until the user makes a change to it themselves.

NSUserDefaults Contains Value Or Not?

How to know whether NSUserDefaults contains any value?How to check whether its empty?
There isn't a way to check whether an object within NSUserDefaults is empty or not.
However, you can check whether a value for particular key is nil or not.
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSObject * object = [prefs objectForKey:#"your_particular_key"];
if(object != nil){
//object is there
}
NSUserDefaults *data = [NSUserDefaults standardUserDefaults];
NSString *string = [data objectForKey:#"yourKey"];
if(string==nil)
NSlog(#"nil")
Take a look at NSUserDefault documentation
// For saving the values
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
// saving an NSString
[userDefaults setObject:#"Ttest" forKey:#"key"];
// --- For Retrieving
NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
// getting an NSString
NSString *myString = [userDefaults stringForKey:#"key"];
To check whether a specific value is set or not, no matter of its location (global or application's), check the returned value of -[NSUserDefaults objectForKey:]
id obj = [[NSUserDefaults standardUserDefaults] objectForKey:#"My-Key-Name"];
if (obj != nil) {...}
To check if the application (bundle) has any settings stored in user defaults:
NSUserDefaults* sdu = [NSUserDefaults standardUserDefaults];
NSString* bundleId = [[NSBundle mainBundle] bundleIdentifier];
NSDictionary* mainBundleSettings = [sdu persistentDomainForName:bundleId];
NSLog(#"%#", mainBundleSettings);
If you are interested in all possible values for which -[NSUserDefaults objectForKey:] will return something, including system global settings, simply call
NSDictionary* allPossibleSettings = [sdu dictionaryRepresentation];
NSUserDefaults is never empty. It combines global settings, bundle's settings, temporary data and maybe something else. For example, if you call:
[[NSUserDefaults standardUserDefaults] objectForKey:#"NSBoldSystemFont"]
you will get the #"LucidaGrande-Bold" string value which will be taken from global settings, even when your application has never set this value.

Resources