XCODE: Get the Value of a setting - nsuserdefaults

I almost despair because my settings doesn't save properly.
I save a setting in a UITableView when a user select a cell:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
checkedCell = indexPath;
NSUInteger row1 = [indexPath row];
NSString *TD = [listData objectAtIndex:row1];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:TD forKey:#"TestData"];
[defaults synchronize];
NSLog(#"Save");
[tableView reloadData];
}
In an other ViewController i load the Data and make a if-else statement:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *TD = [defaults objectForKey:#"TestData"];
NSLog(#"%#",TD);
if (TD == #"0") {
NSString *NTD = #"TRUE";
}
else {
NSString *NTD = #"FALSE";
}
}
I see that the NSLog is 0 but NTD is FALSE.

Make if condition like this
if ([TD isEqualToString:#"0"]) {
NSString *NTD = #"TRUE";
}
else {
NSString *NTD = #"FALSE";
}
Surely this will helpful

Related

UITableView cell displays "null" value in index 0

I have textview in VC. Saving this textview using nsuserdefaults and get it later. In VC1 im getting saved textview and displaying in UITableView. But when i launch the app it automcatically displays "null" text in index 0.
VC:
-(void)save:(id)sender{
NSUserDefaults *userData1 = [NSUserDefaults standardUserDefaults];
[userData1 setObject:textView.text forKey:#"savetext"];
[userData1 synchronize];
}
VC1:
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
// textArray=[[NSMutableArray alloc]init];
txt=[[UITextView alloc]initWithFrame:CGRectMake(0, 0, 320, 400)];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// getting an NSString
NSString *savedValue = [prefs stringForKey:#"savetext"];
NSLog(#"saved is %#",savedValue);
txt.text = [NSString stringWithFormat:#"%#", savedValue];
NSLog(#"text.txt is %#", txt.text);
MyAppDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if(![MyAppDelegate.textArray containsObject:txt.text]){
[MyAppDelegate.textArray addObject:txt.text];
}
NSUserDefaults *userData1 = [NSUserDefaults standardUserDefaults];
[userData1 setObject:MyAppDelegate.textArray forKey:#"save"];
[userData1 synchronize];
}
UITableView displays the text values using array:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSMutableArray* myMutableArrayAgain = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"save"]];
NSLog(#"array is %#",myMutableArrayAgain);
return [myMutableArrayAgain count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSMutableArray* myMutableArrayAgain = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"save"]];
NSLog(#"mycell is %#",myMutableArrayAgain);
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSLog(#"cell is %#",cell);
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
NSLog(#"cell inside is %#",cell);
}
// Configure the cell...
cell.textLabel.text = [myMutableArrayAgain objectAtIndex:indexPath.row];
[cell.textLabel setFont:[UIFont fontWithName:#"Arial-BoldMT" size:14]];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
This is all because the code is wrong at some places:
1) Nsmutable array with array is wrong:- as the userdefaults is returning you a single string.
So do it like this:-
NSUserDefaults *userData1 = [NSUserDefaults standardUserDefaults];
NSMutableArray* myMutableArrayAgain = [NSMutableArray arrayWithObject:[userData1 valueForKey:#"savetext"]];
2) In VC you are saving the value for key in "savetext" but in VC1 you are retrieving the value as "save", so change it, it has been done in the above code.
// The above 2 points would solve your problem but I would say don't code like this as it would consume more memory and would remove tidyness of your code. The code which you have done can be done in a very efficient way.
I tell you .
// Take first View controller VC and add IBAction to a button and a textView or textField what ever.
Write this code in VC :-
.h file
#interface demoViewController : UIViewController{
IBOutlet UITextField *txt1;
}
-(IBAction)getData:(id)sender;
.m file
// first include header file of the next controller where you want to redirect suppose XYZ
#import XYZ.h
-(IBAction)getData:(id)sender{
NSUserDefaults *userData1 = [NSUserDefaults standardUserDefaults];
[userData1 setObject:txt1.text forKey:#"savetext"];
demoViewController1 *demo=[[demoViewController1 alloc]initWithNibName:#"demoViewController1" bundle:nil];
[self.navigationController pushViewController:demo animated:NO];
}
// Take the second controller IN taht on ViewDisLoad or ViewDidAppear whatever you feel like
// Take a global MuttableArray
NSMutableArray *myMutableArrayAgain;
// I write this code on ViewDidload allocate the array here as MutableObject need to be allocated
NSUserDefaults *userData1 = [NSUserDefaults standardUserDefaults];
myMutableArrayAgain=[[NSMutableArray alloc]init];
[myMutableArrayAgain addObject: [userData1 valueForKey:#"savetext"]];
// Now table View Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [myMutableArrayAgain count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSLog(#"cell is %#",cell);
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
NSLog(#"cell inside is %#",cell);
}
// Configure the cell...
cell.textLabel.text = [myMutableArrayAgain objectAtIndex:indexPath.row];
[cell.textLabel setFont:[UIFont fontWithName:#"Arial-BoldMT" size:14]];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
// Apply this way you can do the stuff in less code and in a great way.

Xcode: saving data issue with NSUserDefaults and TableView

I am trying to save data via NSUserDefaults and view it on the tableView but nothing happen after I click on the save button, after I stop and run the application again the data that I saved it I can see it which every time it overwrite on the old data. Am I doing something wrong? Or should I use something different from NSUserDefaults?
Thanks in advance.
-(IBAction)save{
NSUserDefaults *add1 = [NSUserDefaults standardUserDefaults];
[add1 setObject:txt1.text forKey:#"txt1"];
[add1 synchronize];
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
self.dataArray = [NSArray arrayWithObjects:[prefs objectForKey:#"txt1"], nil];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [dataArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *string = [dataArray objectAtIndex:indexPath.row];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text=string;
return cell;
}
There are two issues in your code:
You are not refreshing the tableview. You can do this by calling:
[self.tableView reloadData]; // Or whatever property is pointing to your tableview
Every time you save a value, you save it under the same key (txt1) and that's why you override every time. If you want a list of items (an array) and to append the item into this array, you could do something like this:
NSMutableArray *myList = [[[NSUserDefaults standardUserDefaults] valueForKey:#"myTxtList"] mutableCopy];
[myList addObject:txt1.text];
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithArray:myList] forKey:#"myTxtList"];
[add1 synchronize];
self.dataArray = myList;
[self.tableView reloadData];
P.S. Of course you need to set your dataArray accordingly in your viewDidLoad:
self.dataArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"myTxtList"];
As A for Alpha said try that & in addition I am having doubt in your save method definition too. Just try changing it to the following
-(IBAction)save:(id)sender{
NSUserDefaults *add1 = [NSUserDefaults standardUserDefaults];
[add1 setObject:txt1.text forKey:#"txt1"];
[add1 synchronize];
[tableView reloadData];
}
This may work out for u.
I guess you need to call [yourTableView reloadData] after saving the data in userDefaults. This should solve your problem.

Save checkmarked row into appsettings. EDITED

EDIT: I got a saving and now It do not work.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:countries forKey:#"country"];
[defaults synchronize];
Saving.
But I think I must load the arrays from the appsettings. how?
Got this now:
countries = [[NSArray alloc] initWithObjects:#"All",#"Austria",#"Belarus",#"Canada",#"Czech Republic",#"Denmark",#"Germany",#"Finland",#"France",#"Latvia",#"Norway",#"Russia",#"Slovakia",#"Slovenia",#"Switzerland",#"Sweden", #"USA", nil];
Use synchronize mathod of NSUserDefault.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
int newRow = [indexPath row];
int oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
if (newRow != oldRow)
{
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:
indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:
lastIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
lastIndexPath = indexPath;
}
NSUInteger row = [indexPath row];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//Suppose you have used **myArrayUsedInTableView** Array to construct TableView
..................................................................................
............./*Do changes here in myArrayUsedInTableView as per your requirement*/
....................................................................................
//Now store your array myArrayUsedInTableView in NSUserDefault
[defaults setObject:myArrayUsedInTableView forKey:#"StoredArray"];
[defaults synchronize];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

saving checkmark accessory value in nsuserdefaults and then retreving them

hi
i am trying to save state of ticked row in nsuserdefaults.Some how i am getting error
:setObject undeclared.
my code is as:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
NSInteger newRow = [indexPath row];
NSInteger oldRow = (lastIndexPath != nil) ? [lastIndexPath row] : -1;
if(newRow != oldRow)
{
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:lastIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
lastIndexPath = indexPath;
}
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
prefs = [setObject:lastIndexPath forKey:#"lastIndexPath"];
}
also i am trying to fetch row state in viewdidload method(should i fetch here?in view did load).my code is as:
- (void)viewDidLoad {
menuList=[[NSMutableArray alloc] initWithObjects:
[NSArray arrayWithObjects:#"LOCATION1",nil],
[NSArray arrayWithObjects:#"LOCATION2",nil],
[NSArray arrayWithObjects:#"LOCATION3",nil],
[NSArray arrayWithObjects:#"LOCATION4",nil],
[NSArray arrayWithObjects:#"LOCATION5",nil],
[NSArray arrayWithObjects:#"LOCATION6",nil],
[NSArray arrayWithObjects:#"LOCATION7",nil],
nil];
[self.navigationController setNavigationBarHidden:NO];
self.navigationController.navigationBar.tintColor=[UIColor blackColor];
self.navigationController.navigationBar.barStyle=UIBarStyleBlackTranslucent;
self.title=#"Location Selection";
[table reloadData];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
if([[prefs objectForKey:#"lastIndexPath"] compare: indexPath]== NSOrderedSame){
cell.AccessoryType = UITableViewCellAccessoryCheckMark;
}
[super viewDidLoad];
}
and getting errors: indexPath Undeclared and cell undeclared.
i am getting why these errors are coming coz both of them(indexpath and cell) are not in scope,then where to place this code(nsuserdefaults data retriving code).Please guide my.
Thanks!
Try replacing this:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
prefs = [setObject:lastIndexPath forKey:#"lastIndexPath"];
With this:
[[NSUserDefaults standardUserDefaults] setObject:lastIndexPath forKey:#"lastIndexPath"];
Your error is because you are invoking setObject:forKey: without specifying that your prefs object is calling it. So the compilor is not identifying it as a valid message. You are also trying to assing that messages output to your prefs object, which is not correct.
This said, I am pretty sure you cant store an NSIndexPath inside of a plist directly, you would either have to store as an NSNumber, NSString, or NSData.
This would look like this:
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:lastIndexPath.row] forKey:#"lastIndexPath"];

UITableView Checkmark Only Select One

I am using the code below to set a UITableViewCell's accessory to a checkmark and then write to NSUserDefaults. However it doesn't seem to be working properly. The NSUserDefault never seems to be set. If you can see the problem please point it out.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *text = [array objectAtIndex:indexPath.row];
if (cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
if ([text isEqualToString:[NSString stringWithFormat:#"%i", k10]]) {
[defaults setInteger:k10 forKey:kNumberOfChartsToDownload];
} else if ([text isEqualToString:[NSString stringWithFormat:#"%i", k25]]) {
[defaults setInteger:k25 forKey:kNumberOfChartsToDownload];
} else if ([text isEqualToString:[NSString stringWithFormat:#"%i", k50]]) {
[defaults setInteger:k50 forKey:kNumberOfChartsToDownload];
} else if ([text isEqualToString:[NSString stringWithFormat:#"%i", k75]]) {
[defaults setInteger:k75 forKey:kNumberOfChartsToDownload];
} else if ([text isEqualToString:[NSString stringWithFormat:#"%i", k100]]) {
[defaults setInteger:k100 forKey:kNumberOfChartsToDownload];
}
}
[self.navigationController popViewControllerAnimated:YES];
}
else if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
}
I am also NSLogging the NSUserDefault when the application launches. However the integer is allways 100. Please do the same if you can see the problem.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (! [defaults objectForKey:#"firstRun"]) {
[defaults setObject:[NSDate date] forKey:#"firstRun"];
}
NSInteger daysSinceInstall = [[NSDate date] timeIntervalSinceDate:[defaults objectForKey:#"firstRun"]] / 86400;
if (! [defaults objectForKey:#"first"]) {
[defaults setObject:[NSDate date] forKey:#"first"];
}
if (daysSinceInstall == 0 && [defaults boolForKey:#"askedForSettings"] == NO) {
if (![defaults integerForKey:kNumberOfChartsToDownload]) {
NSLog(#"no defaults");
[defaults setInteger:k25 forKey:kNumberOfChartsToDownload];
} else if ([defaults integerForKey:kNumberOfChartsToDownload]) {
NSLog(#"%i", [defaults integerForKey:kNumberOfChartsToDownload]);
}
[defaults setBool:YES forKey:#"askedForSettings"];
}
By default, NSUserDefaults saves just before the application is unloaded from memory. A problem I have encountered, is that if you quit your application from Xcode, various cleanup methods are never called. Add [[NSUserDefaults standardUserDefaults] synchronize]; to your code after you are done saving the objects in the defaults. This should force NSUserDefaults to save any unsaved changes at that time.