1

I am trying to save a NSMutableArray to NSUserDefaults then reload it and use it to populate the button labels. Can someone please take a look and tell me what i am doing wrong here?

When I am loading the file to new array it appears empty. All of the buttons I am trying to set the titles to are in ibCollectionOutlet called buttons

-(void)save {
    [[NSUserDefaults standardUserDefaults] setObject:self.pressCountArray forKey:@"savedFile"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

-(void)load{

    NSMutableArray *countArray = [[[NSUserDefaults standardUserDefaults] arrayForKey:@"savedFile"] mutableCopy];

    for (NSInteger i = 0; i < [self.pressCountArray count]; i++){
        self.pressCountArray[i] = countArray[i];
    }

    for (NSInteger i = 0; i < [self.buttons count]; i++){
        UIButton *btn = self.buttons[i];
        int curCnt = [[self.pressCountArray objectAtIndex:i] integerValue];

        [btn setTitle:[NSString stringWithFormat:@"%i",curCnt] forState:UIControlStateNormal];
    }
}
modusCell
  • 13,151
  • 9
  • 53
  • 80
burrGGG
  • 617
  • 2
  • 9
  • 18
  • put breakpoint or NSlog the values before save and after , to know what is happening – Kumar KL Aug 11 '14 at 10:50
  • How is pressCountArray declared and how do you set its contents? The first loop should be replaced with `self.pressCountArray = [[[NSUserDefaults standardUserDefaults] arrayForKey:@"saveFile"] mutableCopy]; I would try to put a breakpoint in the save method and print the contents of [NSUserDefaults standardDefaults] in the debugger. – Lev Landau Aug 11 '14 at 10:52
  • Can you manually examine your user defaults or print it out before and after both methods? Maybe you'll find your error through that. – TheAmateurProgrammer Aug 11 '14 at 10:54
  • PressCountArray as 16 integers, between 1-3, when i use a break point after load my pressCountArray is empty? – burrGGG Aug 12 '14 at 09:54

2 Answers2

4

I think your array contains custom objects. If that is the case then you should implement NSCoding protocol (for serialization and de-serialization) in your custom model class.

Implement the following NSCoding protocol methods in your class:

- (void)encodeWithCoder:(NSCoder *)encoder;
- (id)initWithCoder:(NSCoder *)decoder;

After that save the data like:

NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:self.pressCountArray];
[[NSUserDefaults standardUserDefaults] setObject:encodedObject forKey:[NSString stringWithFormat:@"savedFile"]];

And retrieve the data like:

NSData *encodedObject = [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"savedFile"]];
self.pressCountArray  = [NSKeyedUnarchiver unarchiveObjectWithData:encodedObject];
Midhun MP
  • 103,496
  • 31
  • 153
  • 200
  • If that was true there would be an exception "attempt to insert non-property list object". So this cannot be the answer. – trojanfoe Aug 11 '14 at 11:21
0

It looks like you are not allocating self.pressCountArray during the load and are probably attempting to populate an empty array (in a fairly strange way). Instead simply do:

-(void)load{

    self.pressCountArray = [[[NSUserDefaults standardUserDefaults] arrayForKey:@"savedFile"] mutableCopy];

    NSAssert([self.pressCountArray count] == [self.buttons count], @"Array count mismatch");

    for (NSInteger i = 0; i < [self.buttons count]; i++){
        UIButton *btn = self.buttons[i];
        int curCnt = [[self.pressCountArray objectAtIndex:i] integerValue];

        [btn setTitle:[NSString stringWithFormat:@"%i",curCnt] forState:UIControlStateNormal];
    }
}

Note that you need to check that the correct number of array elements have been loaded. I've used an NSAssert in the above code, but you probably need to return NO given it's probably something that can happen in production.

trojanfoe
  • 120,358
  • 21
  • 212
  • 242