How To Connect NSUserDefaults To UISwitch? - iphone

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.

Related

Why Isn't NSUserDefaults working with my UISwitch

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!

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.

NSUserDefaults problem

I have this in my app delegate applicationDidFinishLaunching method:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if([defaults objectForKey:#"AcceptTC"] == nil){
NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:#"NO" forKey:#"AcceptTC"];
[defaults registerDefaults:appDefaults];
}
and I have this in my RootViewController viewDidLoad method:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if(![defaults boolForKey:#"AcceptTC"]){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Notice" message:#"By using this application you agree to be bound by the Terms and Conditions as stated within this application." delegate:self cancelButtonTitle:#"No Deal" otherButtonTitles:#"I Understand",nil];
[alert show];
[alert release];
}
and my alert view delegate does this:
if(buttonIndex == 0){
exit(0);
}
else{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:#"YES" forKey:#"AcceptTC"];
}
However when I click "I understand" (button index 1) and then restart the application I still see the alert view! Even though I've definiely set the value to YES.
I have no idea how to change this. :( I only want it to show the first time a user starts the application - i don't want to keep showing it every time they want to use it.
Thanks
In my application I'm using NSUserDefaults with a bool, works fine.
When the first ViewController loads, it will do:
BOOL terms = [[NSUserDefaults standardUserDefaults] boolForKey:#"termsaccepted"];
if (!terms) {
[self presentModalViewController:disclaimerViewController animated:YES];
}
Within the disclaimer view, after the button has been tapped:
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"termsaccepted"];
[[NSUserDefaults standardUserDefaults] synchronize];
I think you're missing the "synchronize" part. However I find using a bool more streamlined, too.
Maybe you need to call synchronize on the defaults to save the changes to disk?
Concering registerDefaults:
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.
// Load default defaults
[[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary \
dictionaryWithContentsOfFile:[[NSBundle mainBundle] \
pathForResource:#"Defaults" ofType:#"plist"]]];
Code taken from this SO answer.
Another blog article about NSDefaults:
http://retrodreamer.com/blog/2010/07/slight-change-of-plan/