- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
myFavsTwo = [NSMutableArray arrayWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:[[[NSUserDefaults standardUserDefaults] objectForKey:#"MyFavoritez"] mutableCopy]]];
[self.tableView reloadData];
NSLog(#"Number of items in my array is: %d", [myFavsTwo count]);
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Number of items in my array is: %d", indexPath.row+1);
[myFavsTwo removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:myFavsTwo] forKey:#"MyFavoritez"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
on delete my app keeps crashing at:
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver
archivedDataWithRootObject:myFavsTwo] forKey:#"MyFavoritez"];
if I 'continue' on my debugging it still works as it should and everything continues like normal...
not getting any error messages either just a 'break point' message
my view will appear looks like this:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
myFavsTwo = [NSKeyedUnarchiver unarchiveObjectWithData:[[[NSUserDefaults standardUserDefaults] objectForKey:#"MyFavoritez"] mutableCopy]];
[self.tableView reloadData];
NSLog(#"Number of items in my array is: %d", [myFavsTwo count]);
}
and the info is coming from here:
- (void)buttonPressed:(id) sender
{
NSMutableArray *myfavs = [[[NSUserDefaults standardUserDefaults] objectForKey:#"MyFavoritez"]mutableCopy];
if(myfavs != nil)
{
NSLog(#"Array found. Contents: %#",myfavs);
}
else
{
myfavs = [[NSMutableArray alloc] initWithCapacity:0];
}
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:#"MyFavoritez"];
if (dataRepresentingSavedArray != nil)
{
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
if (oldSavedArray != nil)
_myfavs = [[NSMutableArray alloc] initWithArray:oldSavedArray];
else
_myfavs = [[NSMutableArray alloc] init];
}
[_myfavs addObject:self.word];
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:_myfavs] forKey:#"MyFavoritez"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"Number of items in my array is: %d", [_myfavs count]);
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"passFavs"]) {
FavViewController *con = segue.destinationViewController;
con.myFavsTwo = _myfavs; }
}
hope that's not TMI
Have a look at the advice given in this answer - crash on deleteRowsAtIndexPaths in particular it is good practice to bracket your updates to the table view and your data model with [self.tableView beginUpdates] and [self.tableView endUpdates]
Related
I have some problem with saving and loading data in UITableView. After I press button2, I can't find my data that I saved(maybe I didn't save it).
My.h file:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDelegate,UITableViewDataSource>
{
NSMutableArray * arrayIdea;
NSMutableArray * arrayEdit;
IBOutlet UITableViewCell * cell;
}
#property(nonatomic,strong)IBOutlet UITextField * txtField;
#property(nonatomic,strong)IBOutlet UITableView * tabel1;
-(IBAction)button2:(id)sender;
-(IBAction)button1:(id)sender;
#end
My .m file:
#import "ViewController.h"
#interface ViewController ()<UITextFieldDelegate>
#end
#implementation ViewController
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
arrayIdea = [[NSMutableArray alloc] init];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (arrayIdea.count > 0) {
return arrayIdea.count;
}
return 0;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
cell = [tableView dequeueReusableCellWithIdentifier:#"cell1"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell1"];
}
cell.textLabel.text =[NSString stringWithFormat:#"%#", arrayIdea[indexPath.row]];
return cell;
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
if(editingStyle == UITableViewCellEditingStyleDelete) {
[arrayIdea removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath,nil] withRowAnimation: UITableViewRowAnimationFade];
}
}
-(IBAction)button1:(id)sender;{
[arrayIdea addObject:self.txtField.text];
[self.tabel1 reloadData];
self.txtField.text = #"";
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:arrayIdea forKey:#"savedstring"];
[defaults synchronize];
}
-(IBAction)button2:(id)sender;{
NSUserDefaults*defaults = [NSUserDefaults standardUserDefaults];
cell.textLabel.text =[defaults objectForKey:#"savedstring"];
}
#end
You need to encode/decode your array to be able to save it/ retrieve it in NSUserDefaults.
Save
NSData *dataSave = [NSKeyedArchiver archivedDataWithRootObject: arrayIdea];
[[NSUserDefaults standardUserDefaults] setObject:dataSave forKey:#"savedstring"];
[[NSUserDefaults standardUserDefaults] synchronize];
Read
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:#"savedstring"];
NSArray *savedArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
You can save and retrieve like this ..
Save
[[NSUserDefaults standardUserDefaults]setObject:arrayIdea forKey:#"savedstring"];
And retrieve
[[NSUserDefaults standardUserDefaults] objectForKey:#"savedstring"];
In cellForRowAtIndexpath, If you write code like below.
cell.textlabel.text = [[defaults objectForKey:#"saved string"] objectAtIndex:indexPath.row];
instead of passing array.
In numberOfRowsInSection you can pass
[[defalts objectForKey:#"saved string"] count];
You already called table reload method, so there is no need of button 2.
Please try.
I have a method that is working but its not saving the data that I enter.
This is the code I use to enter data on a
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) {
NSString *tempTextField = [alertView textFieldAtIndex:0].text;
if (!numbers) {
numbers = [[NSMutableArray alloc] init];
}
[[NSUserDefaults standardUserDefaults] setObject:tempTextField forKey:#"Save"];
[numbers insertObject:tempTextField atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.myTableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
} }
It is using a UIAlertView with a plain text input. I try to use an NSUSerDefaults to save the data with the method above and I'm able to retrieve the data on the viewDidLoad with this code
-(void)viewDidLoad {
[super viewDidLoad];
NSArray *siteNameValue = [[NSUserDefaults standardUserDefaults] valueForKey:#"Save"];
numbers = [[NSMutableArray alloc] initWithObjects:siteNameValue, nil];
}
But it would only save one of the data that is entered, it doesnt save multiple data. Any leads?
the variable numbers is an NSMutableArray.
You can store a NSMutableArray object created alertView:clickedButtonAtIndex in the user defaults and reuse it in viewDidLoad:
[numbers insertObject:tempTextField atIndex:0];
[[NSUserDefaults standardUserDefaults] setObject:numbers forKey:#"Save"];
You can get the array with same content in viewDidLoad as follows:
NSMutableArray *numbers = [[[NSUserDefaults standardUserDefaults] arrayForKey:#"Save"] mutableCopy];
Problem is you are saving just one NSString, not a NSArray in NSUserDefaults.
You need to save "numbers" (whole NSArray) instead and also load it as an array (additional encapsulation on loading is not necessary).
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) {
NSString *tempTextField = [alertView textFieldAtIndex:0].text;
if (!numbers) {
numbers = [[NSMutableArray alloc] init];
}
[[NSUserDefaults standardUserDefaults] setObject:numbers forKey:#"Save"];
[numbers insertObject:tempTextField atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.myTableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
-(void)viewDidLoad {
[super viewDidLoad];
numbers = [[NSUserDefaults standardUserDefaults] valueForKey:#"Save"];
}
Solution
This is the method to ADD and SAVE data on the tableview using a UIALertView plain text style.
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) {
NSString *tempTextField = [alertView textFieldAtIndex:0].text;
if (!numbers) {
numbers = [[NSMutableArray alloc] init];
}
[numbers insertObject:tempTextField atIndex:0];
[[NSUserDefaults standardUserDefaults] setObject:numbers forKey:#"3"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.myTableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
below is to retrieve it under the viewDidLoad
NSMutableArray *siteNameValue = [[[NSUserDefaults standardUserDefaults] arrayForKey:#"3"] mutableCopy];
numbers = siteNameValue;
I have an array of dictionaries in NSUserDefaults and those values are used to display data in a table view in another tab on the tab bar. It works ok if I add a new value to my NSUserDefaults array and close the app then go back into it and go the table view tab. The problem I'm having is when I add a new object to the user defaults array then go to the table view tab without leaving the app. When I do this, the table view does not show the just added values.
Here is where I add the dictionaries to NSUserDefaults:
- (void)addFavorite {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *favoritesLoaded = [defaults objectForKey:#"favorites"];
NSDictionary *fav = [NSDictionary dictionaryWithObjectsAndKeys:
self.postTitle, #"title",
self.postUrlString, #"url",
nil];
NSMutableArray *favorites = [NSMutableArray array];
if (favoritesLoaded) {
favorites = [[NSMutableArray alloc] initWithArray:favoritesLoaded];
} else {
favorites = [[NSMutableArray alloc] init];
}
[favorites insertObject:fav atIndex:0];
[defaults setObject:favorites forKey:#"favorites"];
[defaults synchronize];
}
In my table view:
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = self.editButtonItem;
[self.tableView setDataSource:self];
[self.tableView setDelegate:self];
self.tableView.backgroundColor = [UIColor blackColor];
if ([[NSUserDefaults standardUserDefaults] objectForKey:#"favorites"]) {
self.redditPosts = [[NSUserDefaults standardUserDefaults] objectForKey:#"favorites"];
}
else {
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CustomCell"];
NSDictionary *post = [self.redditPosts objectAtIndex:[indexPath row]];
if (cell == nil) {
cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CustomCell"];
}
if (cell) {
cell.textLabel.text = [post objectForKey:#"title"];
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.textColor = [UIColor whiteColor];
}
return cell;
}
just after inserting your new content you should reload the tableView:
[self.tableView reloadData];
if this can take a while you can use the following so it won't freeze-up your app:
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
I'm trying to save the selected row for my UITableView. So, when the user comes back to the screen, it shows their last selection.
This is the code I tried, which, i thought would do the trick:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.lastIndexPathUsed = indexPath;
NSData *responseData = [NSKeyedArchiver archivedDataWithRootObject:indexPath];
[[NSUserDefaults standardUserDefaults] setObject:responseData forKey:#"IndexPathData"];
[[NSUserDefaults standardUserDefaults] synchronize];
[tableView reloadData];
}
Then in my viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
NSData *responseData = [[NSUserDefaults standardUserDefaults]objectForKey:#"IndexPathData"];
NSIndexPath *index = [NSKeyedUnarchiver unarchiveObjectWithData:responseData];
self.lastIndexPath = index;
}
However, responseData hasn't have the index path saved. Its always NULL. Even in the didSelectRowAtIndexPath method.
Anyone know of a better way to do this?
You can save it as two values and recreate the NSIndexPath later:
Save indexPath.row and indexPath.section separately then recreate it with:
[NSIndexPath indexPathForRow:inSection:]
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUserDefaults *userdefaults = [NSUserDefaults standardUserDefaults];
[userdefaults setObject:[NSString stringWithFormat:#"%d",indexPath.row] forKey:#"lastIndexPathUsed"];
}
Then in viewDidLoad Method
-(void)viewDidLoad
{
[super viewDidLoad];
self.lastIndexPath = [[NSUserDefaults standardUserDefaults] objectForKey:#"lastIndexPathUsed"];
}
In my application I am giving name to my PDF file with the help of AlertView textfield. The names are saving in Array of table list as well as NSUserDefault to access at any time. Now when I am deleting the single row of table the whole list of NSUserDefault is getting disappeared. Could you please suggest some trick over here in my code. Thanks in advance.
Updated code(viewDidLoad) with comments
- (void)viewDidLoad
{
[super viewDidLoad];
NSIndexPath * indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
//Checking previous NSUserDefault. Here I need trick to open the previous updated NSUserDefault
if([[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:#"%#",[self.tablePdfListArray objectAtIndex:indexPath.row]]] != nil)
{
self.tablePdfListArray = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:#"%#",[self.tablePdfListArray objectAtIndex:indexPath.row]]]];
}
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0)
{
if(!self. tablePdfListArray)
{
self.tablePdfListArray = [[NSMutableArray alloc]init];
}
//the below if condition will not allow repeatative string array in tableList and textfield lenth.
if ([[alertView textFieldAtIndex:0].text length] != 0 && ![self.tablePdfListArray containsObject:self.myPDFName])
{
[self.tablePdfListArray insertObject:[NSString stringWithFormat:#"%#", [alertView textFieldAtIndex:0].text] atIndex:0];
NSIndexPath * indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.pdfListnameTable insertRowsAtIndexPaths:#[indexPath]withRowAnimation:UITableViewRowAnimationAutomatic];
//adding table Array in NSUserDefaults
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
[defaults setObject:self.tablePdfListArray forKey:[NSString stringWithFormat:#"%#.",[self.tablePdfListArray objectAtIndex:indexPath.row]]];
[defaults synchronize];
}
}
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
//Deleting single table row. The NSUserDefault should be updated here.
// NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
// [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:[NSString stringWithFormat:#"%#.",[self.tablePdfListArray objectAtIndex:indexPath.row]]];
[pdfListnameTable beginUpdates];
[pdfListnameTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[pdfListnameTable deleteSections:indexes withRowAnimation:UITableViewRowAnimationFade];
[pdfListnameTable endUpdates];
}
}
As I understand you are removing all defaults when using
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
Just remove this line of code