Why Isn't NSUserDefaults working with my UISwitch - iphone

I'm trying to setup a UISwitch that is off by default until the user turns it on. However it is showing ON by default now.
AppDelegate's didFinishLaunching:
NSString *testValue = [[NSUserDefaults standardUserDefaults] stringForKey:#"pinCodeSwitch"];
if (!testValue) {
// since no default values have been set, create them here
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:#"pinCodeSwitch"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
VC's viewDidAppear:
UISwitch* testSwitch = [[[UISwitch alloc] init] autorelease];
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"pinCodeSwitch"]) {
[testSwitch setOn:NO animated:NO];
}
self.pinCodeSwitch = testSwitch;
Method to save BOOL when UISwitch's value changed:
- (IBAction)pinCodeSwitchChanged:(id)sender
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"pinCodeSwitch"];
BOOL test = [[NSUserDefaults standardUserDefaults] boolForKey:#"pinCodeSwitch"];
}

You're not getting to set the switch since you set 'pinCodeSwitch' to NO. It skips the if statement.
Change it to:
if (![[NSUserDefaults standardUserDefaults] boolForKey:#"pinCodeSwitch"])
(Negate your test), then the switch will turn off.

you can specify this value in the Interface Builder by the "STATE" value to OFF.
and after that save the switch value by applying this code:
[YourUiSwitch setOn:NO animated:YES];
[[NSUserDefaults standardUserDefaults]setValue:YourUiSwitch forKey:#"youruiswitch"];
[[NSUserDefaults standardUserDefaults]synchronize];
and when the view did load comes load it from the defaults like this:`YourUiSwitch =
[[NSUserDefaults standardUserDefaults]valueForKey:#"youruiswitch"];`
GOOD LUCK BUDDY!

Related

UILabel text doesn't update after receiving notification

When I set a label using this
self.versionLbl.text = [[NSUserDefaults standardUserDefaults] objectForKey:#"version"];
in the viewDidLoad method, it works when the view gets loaded but I also want to set the label when a notification was received.
- (void)receiveNotification:(NSNotification *) notification
{
if ([[notification name] isEqualToString:#"versionNotification"]){
NSLog (#"Successfully received the notification!");
self.versionLbl.text = [[NSUserDefaults standardUserDefaults] objectForKey:#"version"];
}
}
The string "Successfully received the notification!" gets printed out, but the label doesn't get updated/set with the string unless I reload the view again and the viewDidLoad method gets called.
EDIT
I found out that it has nothing to do with the notification, when I put self.versionLbl.text = [[NSUserDefaults standardUserDefaults] objectForKey:#"version"]; in another function is doesn't get set aswell... it only gets set when I put it in the viewDidLoad method
Make sure that your label is not nil and that you're calling UIKit methods in the main thread. You can try this:
dispatch_async(dispatch_get_main_queue(), ^{
self.versionLbl.text = [[NSUserDefaults standardUserDefaults] objectForKey:#"version"];
});
First of all make sure that the object stored in [[NSUserDefaults standardUserDefaults] objectForKey:#"version"]; is actually a NSString object.
If not you have several alternatives:
self.versionLbl.text = [[NSUserDefaults standardUserDefaults] stringForKey:#"version"];
or
id versionObject = [[NSUserDefaults standardUserDefaults] objectForKey:#"version"];
self.versionLbl.text = [NSString stringWithFormat:#"%#", versionObject];
or
id versionObject = [[NSUserDefaults standardUserDefaults] objectForKey:#"version"];
self.versionLbl.text = [versionObject stringValue];
Check IBOutlet at your UILabel. You should connect IBOutlet UILabel declared with a Property with label on your .xib file.
If its loading after the view has already loaded, try [myLabel setNeedsDisplay];

Detecting the first ever run of an app

I am creating an app in which I have to create a plist when the app launches for the first time. I'm later going to use the plist to store details a user later inputs. How can I detect the first launch of the app? I was experimenting with NSUserDefaults but I think I'm doing something wrong.
You can do this with NSUserDefaults. But be careful with the Version Number.
Do the following:
NSString *bundleVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
NSString *appFirstStartOfVersionKey = [NSString stringWithFormat:#"first_start_%#", bundleVersion];
NSNumber *alreadyStartedOnVersion = [[NSUserDefaults standardUserDefaults] objectForKey:appFirstStartOfVersionKey];
if(!alreadyStartedOnVersion || [alreadyStartedOnVersion boolValue] == NO) {
[self firstStartCode];
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES] forKey:appFirstStartOfVersionKey];
}
the selector firstStartCode will only be called on time for each application version on the very first run.
Okay?
I like to use NSUserDefaults to store an indication of the the first run.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![defaults objectForKey:#"firstRun"])
[defaults setObject:[NSDate date] forKey:#"firstRun"];
[[NSUserDefaults standardUserDefaults] synchronize];
You can then test for it later...
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if([defaults objectForKey:#"firstRun"])
{
// do something or not...
}
Taken from: Best way to check if an iPhone app is running for the first time
You can use the following:
-(void) firstLaunch {
//Code goes here
}
-(void) firstLaunchCheck {
if(![[NSUserDefaults standardUserDefaults] boolForKey:#"didLaunchFirstTime"]) {
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:#"didLaunchFirstTime"];
[self firstLaunch];
}
}

Saving and displaying data with NSUserDefaults

I've saved some input from a UITextField using the following code:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:myTextField.text forKey:#"myTextFieldKey"];
[defaults synchronize];
I'd like to display this saved text on a UILabel in another view controller.
I tried this:
myLabel.text = [[NSUserDefaults standardUserDefaults] objectForKey:#"myTextFieldKey"];
but nothing displays. Any help with this would be great. thanks.
Well the loading and saving code is correct, so it looks like the problem is something else.
Try this to debug:
NSString *aValue = [[NSUserDefaults standardUserDefaults] objectForKey:#"myTextFieldKey"];
NSLog(#"Value from standardUserDefaults: %#", aValue);
NSLog(#"Label: %#", myLabel);
myLabel.text = aValue;
Now you will see if the value retriever from the NSUserDefaults is set and if the label is assinged.
[[NSUserDefaults standardUserDefaults] setValue:myTextField.text forKey:#"myTextFieldKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
After that use valueForKey not objectForKey:
myLabel.text = [[NSUserDefaults standardUserDefaults] valueForKey:#"myTextFieldKey"];
Try:
myLabel.text = [[NSUserDefaults standardUserDefaults] stringForKey:#"myTextFieldKey"];
Check that myTextField and myLabel aren't nil.

UISwitch Not Responding To NSUserDefault Changes

I have a UISwitch in my app along with one in my settings bundle with the same functionality. The UISwitch in my app however is not saving its settings properly. Can anyone see anything wrong with the code?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Set the application defaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:#"No" forKey:#"isKgs"];
[defaults registerDefaults:appDefaults];
[defaults synchronize];
}
- (void)switchChanged
{
[[NSUserDefaults standardUserDefaults] setBool:unitSwitch.selected forKey:#"isKgs"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"SwitchGhanged:");
}
-(void)cellForRowAtIndexPath
{
[unitSwitch addTarget:self action:#selector(switchChanged) forControlEvents:UIControlEventValueChanged];
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"isKgs"])
{
[unitSwitch setOn:YES animated:NO];
}
}
And here is the settings bundle
[[NSUserDefaults standardUserDefaults] setBool:unitSwitch.on forKey:#"isKgs"];
Use the on property for setting.
Try using on on the UISwitch:
[[NSUserDefaults standardUserDefaults] setBool:unitSwitch.on forKey:#"isKgs"];
EDIT: No need to test as unitSwitch.on is already BOOLEAN, you can assign it directly.

How To Connect NSUserDefaults To UISwitch?

So I have setup my settings bundle which works in the iPhone's settings app. I want to add one of the settings within my own app. I know I can use InAppSettings framework, but I just want to add one settings, not all of them, and I already have an page ready that I want to add this settings option to.
So I have replicated the cell with UISwitch in my app which looks the same as the settings one. My question is, how can I now connect this UISwitch to my NSUserDefaults so it functions as a settings UISwitch?
In my appDelegate, I have:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:#"No" forKey:#"isKgs"];
[defaults registerDefaults:appDefaults];
[defaults synchronize];
Edit - All related code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:NO forKey: #"isKgs"];
[defaults synchronize];
}
The cell inside the app where I want the UISwitch to be
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
cell.accessoryView = switchView;
[switchView addTarget:self action:#selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
[switchView setOn:[[NSUserDefaults standardUserDefaults] boolForKey:#"isKgs"] animated:NO];
[switchView release];
}
And the settings bundle where I have the same UISwitch that can be acceded through iPhone settings app:
Edit 2:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (nil == [defaults objectForKey:#"isKgs"])
{
[defaults setBool:NO forKey: #"isKgs"];
}
else
{
}
[defaults synchronize];
It's easier to use a boolean variable if you want to use a UISwitch. In the app delegate, set the default value for the settings, if not existed:
// set the default settings
NSString *testValue = [[NSUserDefaults standardUserDefaults] stringForKey:#"testSwitch"];
if (!testValue) {
// since no default values have been set, create them here
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"testSwitch"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
And then create use the value from the NSUserDefaults settings to turn on the switch if needed:
UISwitch* testSwitch = [[[UISwitch alloc] init] autorelease];
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"testSwitch"]) {
[testSwitch setOn:YES animated:NO];
}
You should head aporat's suggestion and use a BOOL instead. However, if you are insistent on using a string as in your question, then you will have to do this:
if ([[[NSUserDefaults standardUserDefaults] objectForKey:#"isKgs"] isEqualToString:#"No") {
[switch setOn:NO animated:NO];
}
However, if you use a BOOL, you can set the switch in one simple line:
[switch setOn:[[NSUserDefaults standardUserDefaults] boolForKey:#"isKgs"] animated:NO];
This means that you must go back and set up the defaults like this:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:NO forKey#"isKgs"];
[defaults synchronize];
At some point in your code you are going to have to check the switch state and write it back to userDefaults:
[[NSUserDefaults standardUserDefaults] setBool:[switch on] forKey:#"isKgsk"];
[defaults synchronize];
you can write the changes back to userDefaults in your switchChanged: function.
Also, if you always set your key to NO in didFinishLaunchingWithOptions: then it will never reflect changes made in the settings app, it will always be NO.... this is probably not what you want.