NSUserDefaults to add row in a UITableViewController - ios

I am trying to use NSUserDefaults to store a UITextField text and to retrieve it in another controller after you press Done button while editing.
in the controller where the user put information i code this :
-(IBAction)confirmAction:(id)sender{
UIViewController *prevVC = [self.navigationController.viewControllers objectAtIndex:1];
[self.navigationController popToViewController:prevVC animated:YES];
NSUserDefaults *try = [NSUserDefaults standardUserDefaults];
[try setObject:self.nameTextField.text forKey:#"name"];
[try synchronize];
}
and in the other controller i use this :
-(void)doneAction:(id)sender{
[self.tableView setEditing:NO animated:NO];
self.navigationItem.leftBarButtonItem = nil;
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(editButtonClicked:)];
NSUserDefaults *try = [NSUserDefaults standardUserDefaults];
[ingredients addObject:[try stringForKey:#"name"]];
}
why i can't see any results. nothing is added in the tableview. why? did i write something wrong?

The most likely reason why you do not see the changes is that the UITableView does not know that you have added a new item to the ingredients array. In MVC terms, your controller made changes to the model, but it did not notify the view of that change.
You need to call [self.tableView reloadData]; at the end of your doneAction: method:
-(void)doneAction:(id)sender {
[self.tableView setEditing:NO animated:NO];
self.navigationItem.leftBarButtonItem = nil;
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:#selector(editButtonClicked:)];
NSUserDefaults *try = [NSUserDefaults standardUserDefaults];
[ingredients addObject:[try stringForKey:#"name"]];
[self.tableView reloadData];
}

You should add [self.tableView reloadData]; after [ingredients addObject:[try stringForKey:#"name"]];

Related

Pop to viewcontroller Editing Text

I have a ViewcontrollerA as a form filling page and to perform a calculation I push a new viewcontrollerB now when I pop to ViewcontrollerA the existing contents are cleared
My code is
In viewcontroller A
JS_skill *skill_VC = [[JS_skill alloc] initWithNibName:#"JS_skill" bundle:nil];
[[self navigationController] pushViewController:skill_VC animated:NO];
In viewcontroller B
[self.navigationController popViewControllerAnimated:YES];
A quick option would be to save the values of the textfields in userDefaults before you push the viewcontroller. Then when you return to the viewController in viewWillAppear set the textfields back to what you have in userDefaults:
//Just before you push the viewController:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setValue:#"Example Name" forKey:#"nameTextField"];
[defaults setValue:#"Example Surname" forKey:#"surnnameTextField"];
//In ViewWillAppear:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
textField.text = [defaults valueForKey:#"nameTextField"];
surnameField.text = [defaults valueForKey:#"surnnameTextField"];

How to launch a different viewController on the second launch

Here the code I have under the viewController.m
This code will run when a user selects a viewController
-(void)switchViews {
UIStoryboard *mainStory = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [mainStory instantiateViewControllerWithIdentifier:schoolName];
[self presentModalViewController:vc animated:YES];
NSUserDefaults *defaultViewController = [NSUserDefaults standardUserDefaults];
[defaultViewController setObject:nil forKey:#"save"];
[defaultViewController synchronize];
}
This code will run on the second time the app is launched
-(void)loadNewView {
UIStoryboard *mainStory = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
NSUserDefaults *newUserDefault = [NSUserDefaults standardUserDefaults];
NSString *newVC = [NSString stringWithFormat:#"save", schoolName];
UIViewController *newViewController = [mainStory instantiateViewControllerWithIdentifier:newVC];
[self presentModalViewController:newViewController animated:YES];
}
Keeping in mind that schoolNameis a string
How can I run [self loadNewView] under the viewDidLoad but running it on the second time the app is launched?
You should do something like
id value = [[NSUserDefaults standardUserDefaults] objectForKey:#"save"];
if (value) {
UIViewController *vc = [mainStory instantiateViewControllerWithIdentifier:value];
[self presentModalViewController:vc animated:YES];
} else {
// first time logic
}
in your AppDelegate or wherever you have your navigation logic. You should not have that logic in viewDidLoad.
-(void)viewDidLoad {
[super viewDidLoad];
NSString *launchCount = #"LaunchCount";
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSInteger count;
if([userDefaults objectForKey:launchCount]) {
count = [userDefaults integerForKey:launchCount];
}
else {
count = 0;
}
count++; //increment the launch count
[userDefaults setObject:[NSNumber numberWithInt:count] forKey:launchCount];
[userDefaults synchronize];
if([userDefaults integerForKey:launchCount] >= 2) {
// Do your thang
}
}
on ViewDidLoad function do something like this
if (![[NSUserDefaults standardUserDefaults] boolForKey:#"HasLaunchedFirst"])
{
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"HasLauncheFirst"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self switchViews];
}
else
{
[[NSUserDefaults standardUserDefaults] setBool:No forKey:#"HasLauncheFirst"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self loadNewView];
}

First time app launch PageView

I Have an UIPageView as first time welcome view, with a little help of appcoda.
The middle view is the PageContentViewController and the last the RootViewController is called PageViewController.
Now I want to connect it with the NSUserDefault, which i did in the regulair first screen Controller:
- (void)Loadview_afterdelay
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![defaults objectForKey:#"firstRun"])
{
PageViewController *intro = [[PageViewController alloc] initWithNibName:nil bundle:nil];
intro.modalTransitionStyle = UIModalTransitionStyleCoverVertical ;
[self presentModalViewController:intro animated:YES];
[defaults setObject:[NSDate date] forKey:#"firstRun"];
}
[[NSUserDefaults standardUserDefaults] synchronize];
}
And in the ViewDidLoad of my RootViewController in the app:
[self performSelector:#selector(Loadview_afterdelay) withObject:nil afterDelay:0.5];
I know that the PageViewController is the screen where I need to go.
When I try to do this the above way I get a crash:
-[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]'
I'm not sure what I'm doing wrong.

NSUserDefaults Saving only last entered data

I am saving Textfield text using NSUserDefaults on button click in ViewController2
My code is
ButtonClick()
{
NSUserDefaults *userDefaults =[NSUserDefaults standardUserDefaults];
[userDefaults setObject:keyWordField.text forKey:#"Keywords"];
[userDefaults synchronize];
}
Then ViewDidLoad method i am Retrieving like this
-(void)viewDidLoad
{
NSUserDefaults *userDefaults =[NSUserDefaults standardUserDefaults];
[keyWordArray addObject:[userDefaults objectForKey:#"Keywords"]];
[userDefaults synchronize];
}
Here i am assigning this keyWordArray to tableview
like cell.textlabel.text =[keyWordArray objectAtIndex:indexPath.row];
First i entered text(First) in textfield and click button it is showing in table like
First
Second time i entered text (second) in textfield and click button it is showing table like
First
Second
Here everything working fine. The problem is when i come to viewController2 from ViewController1. It is showing last entered value only
like
Second
what going wrong here?
Try This
- (IBAction)buttonclick:(id)sender {
[keyWordArray addObject:keyWordField.text];
NSUserDefaults *userDefaults =[NSUserDefaults standardUserDefaults];
[userDefaults setObject:keyWordArray forKey:#"Keywords"];
[userDefaults synchronize];
[selt.tableView reload]; //reload the table every time a new text is added
}
-(void)viewDidLoad {
if([[NSUserDefaults standardUserDefaults] objectForKey:#"Keywords"]==nil){
keyWordArray = [[NSMutableArray alloc] init];
}
else{
keyWordArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"Keywords"];
}
}
Try this,
- (IBAction)buttonclick:(id)sender {
[keyWordArray addObject:keyWordField.text];
NSUserDefaults *userDefaults =[NSUserDefaults standardUserDefaults];
[userDefaults setObject:keyWordArray forKey:#"Keywords"];
[userDefaults synchronize];
}
and
-(void)viewDidLoad
{
NSArray *array = [[NSUserDefaults standardUserDefaults] objectForKey:#"Keywords"];
if (!array) {
keyWordArray = [[NSMutableArray alloc] init];
} else {
keyWordArray = [NSMutableArray arrayWithArray:nameArray];
}
}
Since you are overriding your
[userDefaults setObject:keyWordField.text forKey:#"Keywords"];
every then and there your every object in the array will be referring to your [userDefaults setObject:keyWordField.text forKey:#"Keywords"]; object thats y the problem comes
Because if you are navigate to another viewController. since the your user default value save in second only.
After pop to back through viewDidLoad is loaded. so far its have second string only save in User Default.
that way it display second only.
You code is overwrite the last value and remove previous values from NSUserDefault. You have to use array to stored all value and you have save array into NSUserDefault.
NSMutableArray *aryDataDefault = [[NSUserDefaults standardUserDefaults] valueForKey:#"YourKey"];
[aryDataDefault addObject:textfield.text];
[[NSUserDefaults standardUserDefaults] setObject:aryDataDefault forKey:#"YourKey"];
[[NSUserDefaults standardUserDefaults] synchronize];

Random data loss (NSUserDefaults) when popToRootViewControllerAnimated

From time to time, my app loses all data when using:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// 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];
*/
[tableView deselectRowAtIndexPath:indexPath animated:YES];
switch (indexPath.row)
{
case kLANG_HEBREW:
// Hebrew is the default
self.arrayOfLanguages = [NSMutableArray arrayWithObjects:#"he", #"en", nil];
break;
case kLANG_ENGLISH:
self.arrayOfLanShorts = [NSMutableArray arrayWithObjects:#"en", #"he", nil];
break;
case kLANG_RUSSIAN:
self.arrayOfLanShorts = [NSMutableArray arrayWithObjects:#"ru", #"en", nil];
break;
case kLANG_ARABIC:
self.arrayOfLanShorts = [NSMutableArray arrayWithObjects:#"ar", #"en", nil];
break;
}
[[NSUserDefaults standardUserDefaults] setObject:self.arrayOfLanShorts forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"come_from_change_lang"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self.navigationController popToRootViewControllerAnimated:YES];
}
Thats very strange since I don't clear data in my app.
My guess is that your switch statement isn't always setting self.arrayOfLanShorts and it is then nil. Then when you set that in our user defaults it nils out the stored value and it would appear you lost your data. I would put a check of an if statement that your array is not nil before adding it to the defaults and if it is trace down how it didn't hit your switch statement.

Resources