NS User Default help

Discussion in 'iOS Programming' started by ljg93, May 4, 2012.

  1. ljg93 macrumors member

    Joined:
    Mar 13, 2011
    #1
    I keep on getting the error

    Code:
    Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
    
    When I am adding a cell to a tableview that a user can name. I am doing this by having an add button on the table view then once pressed goes to a new view controller with a text field that a user can input a name.

    Here is how I am saving to the NSUserDefault

    Code:
    
    -(void)addNewSectionWithName:(NSString *)name {
      
        [tableInfo addObject:name];  
        [self.tableView reloadData];
    
        NSString *valueToSave = name;
        [[NSUserDefaults standardUserDefaults]
         setObject:valueToSave forKey:@"customCellName"];
        
        NSLog(@"%@", [[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys]);
    
    }
    
    I am calling on the data here

    Code:
    - (void)reloadCells {	
        
        NSString *savedValue = [[NSUserDefaults standardUserDefaults]
                                stringForKey:@"customCellName"];
        
        NSMutableArray *tempArray = [[NSMutableArray alloc]init];
        [tempArray addObject:savedValue];
        [tableInfo addObjectsFromArray:tempArray];
        
    }
    

    This is how I am assigning the value to the cells in my cellForRowAtIndexPath
    Code:
        NSString *savedValue = [[NSUserDefaults standardUserDefaults]
                                stringForKey:@"customCellName"];
    
    	
        cell.textLabel.text = savedValue;
    


    On my other view controller that is doing the adding I am sending the data with the following code

    Code:
    -(void)addNewSection
    
    {
     if (sectionName.text.length >0)
        {
            [sectionName resignFirstResponder];
            [self dismissModalViewControllerAnimated:YES];
            [firstViewController addNewSectionWithName:sectionName.text];
            [firstViewController.tableView reloadData];    
        }
    }
    
    Any suggestions on what I have to do to fix my error?
     
  2. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #2
    This code all looks... odd... and I'm confused why you're using NSUserDefaults at all. NSUserDefaults is for storing things like preferences. You're just putting a variable in it so you can access it elsewhere, unless I'm misreading your code.

    I feel like you're violating MVC... maybe you should look at some sample code to see how you're supposed to set up UITableViews?
     
  3. ljg93 thread starter macrumors member

    Joined:
    Mar 13, 2011
    #3
    I am just trying to learn how to use NSUserDefaults so I was trying to save data to a table using that.
     
  4. iosdev macrumors newbie

    Joined:
    May 4, 2012
    #4
    You forgot to use

    PHP:
    [[NSUserDefaults standardUserDefaultssynchronize];
    to save settings to user defaults
     
  5. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #5
    The error that is terminating your app is that some code is trying to insert nil into an array, and that is illegal. You haven't said which line is the one that causes the assertion failure. You don't show any lines that include a call to insertObject:atIndex: So either the failure is in code you didn't show or it's inside the framework.

    If the failure is due to the line where you setObject:forKey: then the nil object is the objectToSave. Is that the bad line? Is objectToSave nil?
     
  6. ljg93 thread starter macrumors member

    Joined:
    Mar 13, 2011
    #6
    Thank you for both of your replies.

    The line that is causing the app to crash is bolded in the code below
    Code:
    - (void)reloadCells {	
        
        
    
        
        NSString *savedValue = [[NSUserDefaults standardUserDefaults]
                                stringForKey:@"savedkey"];
    
        [[NSUserDefaults standardUserDefaults] synchronize];
    
        
        NSMutableArray *tempArray = [[NSMutableArray alloc]init];
        
    [B]    [tempArray addObject:savedValue];
    [/B]    [tableInfo addObjectsFromArray:tempArray];    
    
    
        
    }
    
    

    Also below is the code to the whole implementation file.
    Code:
    @synthesize tableInfo;
    @synthesize addSection;
    @synthesize sections;
    @synthesize data;
    
    
    - (id)initWithStyle:(UITableViewStyle)style
    {
        self = [super initWithStyle:style];
        if (self) {
            // Custom initialization
        }
        return self;
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        tableInfo = [[NSMutableArray alloc]initWithObjects: nil];
        
        self.title = @"Reminders";
        
        addSection = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addNewSection)];
        
        UIBarButtonItem *deleteButton = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(editTable)];
        
        self.navigationItem.rightBarButtonItem= addSection;
        self.navigationItem.leftBarButtonItem = deleteButton;
        
        [self reloadCells];
        [self.tableView reloadData];
        
    }
    
    -(void)addNewSection {
        
        
        AddViewController *addViewController = [AddViewController alloc];
        addViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
        addViewController.firstViewController = self;
        [self presentModalViewController:addViewController animated:YES];
        
        
    }
    
    -(void)editTable {
        
        
    	if(self.editing)
    	{
            //when the user is in edit mode
    		[super setEditing:NO animated:NO]; 
    		[self.tableView setEditing:NO animated:NO];
    		[self.tableView reloadData];
            [self.navigationItem.leftBarButtonItem setStyle:UIBarButtonItemStylePlain]; 
    
    			}
    	else
    	{
            //when theuser is not in edit mode
    		[super setEditing:YES animated:YES]; 
    		[self.tableView setEditing:YES animated:YES];
    		[self.tableView reloadData];
            [self.navigationItem.leftBarButtonItem setStyle:UIBarButtonItemStyleDone]; 
    
    			}
    
        
    }
    
    
    -(void)addNewSectionWithName:(NSString *)name {
      
        
    
    
        NSString *valueToSave = name;
        [[NSUserDefaults standardUserDefaults]
         setObject:valueToSave forKey:@"savedkey"];
        
        
        [[NSUserDefaults standardUserDefaults] synchronize];
        
        [tableInfo addObject:name];  
        [self.tableView reloadData];
    
    
    
    
    }
    
    - (void)reloadCells {	
        
        
    
        
        NSString *savedValue = [[NSUserDefaults standardUserDefaults]
                                stringForKey:@"savedkey"];
    
        [[NSUserDefaults standardUserDefaults] synchronize];
    
        
        NSMutableArray *tempArray = [[NSMutableArray alloc]init];
        
        //[tempArray addObject:savedValue];
        [tableInfo addObjectsFromArray:tempArray];    
    
    
        
    }
    
    
    
    - (void)viewDidUnload
    {
        [super viewDidUnload];
        // Release any retained subviews of the main view.
        // e.g. self.myOutlet = nil;
    }
    
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
        return (interfaceOrientation == UIInterfaceOrientationPortrait);
    }
    - (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath 
    {
        // No editing style if not editing or the index path is nil.
        if (self.editing == NO || !indexPath) return UITableViewCellEditingStyleNone;
        // Determine the editing style based on whether the cell is a placeholder for adding content or already 
        // existing content. Existing content can be deleted.    
        if (self.editing && indexPath.row == ([tableInfo count])) 
    	{
    		return UITableViewCellEditingStyleInsert;
    	} else 
    	{
    		return UITableViewCellEditingStyleDelete;
    	}
        return UITableViewCellEditingStyleNone;
    }
    
    // Update the data model according to edit actions delete or insert.
    
    
    #pragma mark - Table view data source
    
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        // Return the number of sections.
        return 1;
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {    // Return the number of rows in the section.
        return [tableInfo count];
        
        
        
       
    
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
        
        static NSString *CellIdentifier = @"Cell";
        
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:  UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
            
            [[cell textLabel] setTextAlignment:UITextAlignmentLeft];
            
        }
    
        
    //    
    //   NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    ////    
    ////    // getting an NSString
    //    NSString *myString = [prefs stringForKey:@"customCell"];
    //    
    //    cell.textLabel.text = myString;
        
        
        NSString *savedValue = [[NSUserDefaults standardUserDefaults]
                                stringForKey:@"savedKey"];
    
    	
        cell.textLabel.text = savedValue;
    
        
        
    	//cell.textLabel.text = [tableInfo objectAtIndex:indexPath.row];
    
        
        return cell;
    }
    
    // Update the data model according to edit actions delete or insert.
    
    
    #pragma mark - Table view delegate
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        // Navigation logic may go here. Create and push another view controller.
        
        SecondViewController *secondViewController = [[SecondViewController alloc]init];
        
        UILabel *headerLabel = [[UILabel alloc]initWithFrame:CGRectMake(40, 12, 320, 20)];
        headerLabel.textColor = [UIColor blackColor];
        headerLabel.font = [UIFont fontWithName:@"Test" size:12];
        headerLabel.textAlignment = UITextAlignmentCenter;
        headerLabel.backgroundColor = [UIColor  clearColor];
        headerLabel.text = [tableInfo objectAtIndex:indexPath.row];
        secondViewController.title = [tableInfo objectAtIndex:indexPath.row];
        secondViewController.navigationItem.titleView = headerLabel;
        
         // ...
         // Pass the selected object to the new view controller.
         [self.navigationController pushViewController:secondViewController animated:YES];
         
    }
    
     
  7. iosdev macrumors newbie

    Joined:
    May 4, 2012
    #7
    Man are you joking ?

    There is so much mistakes in code ((

    1
    Code:
    - (void)reloadCells {	
     
        if (![[NSUserDefaults standardUserDefaults]
                                stringForKey:@"savedkey"]) {
    [tableInfo addObjectsFromArray:[[NSUserDefaults standardUserDefaults]
                                stringForKey:@"savedkey"]]; 
        }else{
    //Do what you want if there is no value in defaults, maybe add a @"0", or anything else
    }
        
    
    
        
    }


    ----------

    2
    Code:
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        
        
        static NSString *CellIdentifier = @"Cell";
        
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:  UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
            
            [[cell textLabel] setTextAlignment:UITextAlignmentLeft];
            
        }
    	cell.textLabel.text = [tableInfo objectAtIndex:indexPath.row];
        
        
        return cell;
    }


    ----------

    Now should work
     

Share This Page