0

I have a class called CurrentUser, which holds a NSMutableArray called listOfFriends. This listOfFriends holds objects from the class Friends.

Both CurrentUser and Friend classes have the NSCoding protocols handled. The Friend object has a property called userImg, which is a UIImage. There's just one problem. When I try to load the lisOfFriends, the Friends don't come with their UIImages.

If I save any friend, and try to load it back again, it comes with the UIImage with no problem. But if the object is inside the listOfFriends, it doesn't come with the UIImage, but all other informations are loaded correctly.

My question then is: How can I store and load a NSMutableArray with custom objects? Declaration of the friendList:

CurrentUser.h

@property (nonatomic,strong)NSMutableArray *FriendsList;

CurrentUser.m

  - (void) encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:username forKey:@"username"];
    [encoder encodeObject:FriendsList forKey:@"FriendsList"];
    //testing direct friend saving
    [encoder encodeObject:[FriendsList objectAtIndex:0] forKey:@"testFriend"];
    [encoder encodeObject:_userPSW forKey:@"userpassword"];
    [encoder encodeObject:UIImagePNGRepresentation(userImg) forKey:@"userImg"];
    [encoder encodeObject:userID forKey:@"userID"];
    [encoder encodeObject:groups forKey:@"groups"];
    [encoder encodeObject:_email forKey:@"email"];

}

- (id)initWithCoder:(NSCoder *)decoder {
    currentUser *returnUser = [[currentUser alloc] init];
    returnUser.username = [decoder decodeObjectForKey:@"username"];
    returnUser.email = [decoder decodeObjectForKey:@"email"];
    //testing direct friend loading
    Friend *testFriend = [decoder decodeObjectForKey:@"testFriend"];
    returnUser.userPSW = [decoder decodeObjectForKey:@"userpassword"];
    returnUser.userImg = [UIImage imageWithData:[decoder decodeObjectForKey:@"userImg"]];
    returnUser.FriendsList = [decoder decodeObjectForKey:@"FriendsList"];
    returnUser.userID = [decoder decodeObjectForKey:@"userID"];
    returnUser.groups = [decoder decodeObjectForKey:@"groups"];

    return returnUser;
}

Friend.m

- (void)encodeWithCoder:(NSCoder *)encoder{  
    [encoder encodeObject:UIImagePNGRepresentation(userImg) forKey:@"friendIMG"];
    [encoder encodeObject:username forKey:@"friendUN"];
    [encoder encodeObject:userID forKey:@"friendID"];

}

- (id)initWithCoder:(NSCoder *)decoder{
    Friend *obj = [[Friend alloc]init];
    obj.username = [decoder decodeObjectForKey:@"friendUN"];
    obj.userImg = [UIImage imageWithData:[decoder decodeObjectForKey:@"friendIMG"]];
    obj.userID = [decoder decodeObjectForKey:@"friendID"];
    return obj;

}

This is the object I have to save and load the CurrentUser, It's called "Configurations". Configurations.h

#import "currentUser.h"
@interface configurations : NSObject
- (currentUser*)loadCustomObject;
- (void)saveCustomObject:(currentUser *)object;

@end

Configurations.m

#import "configurations.h"

@implementation configurations
- (void)saveCustomObject:(currentUser *)object {
    NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:object];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:encodedObject forKey:@"lastUser"];
    [defaults synchronize];

}

- (currentUser*)loadCustomObject {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSData *encodedObject = [defaults objectForKey:@"lastUser"];
    currentUser *object = [NSKeyedUnarchiver unarchiveObjectWithData:encodedObject];
    return object;
}
@end

This is how I'm loading the CurrentUser.

saver = [[configurations alloc]init];
currentUser *tmpUser = [saver loadCustomObject];
thisUser = [currentUser instance];

static dispatch_once_t once;
dispatch_once(&once, ^ {
        if(tmpUser != nil){
            if(![tmpUser.username isEqualToString:@""]){


            for(Friend *savedFriend in tmpUser.FriendsList)
            {
                [thisUser addFriend:savedFriend];
            }
                thisUser.username = tmpUser.username;
                thisUser.email = tmpUser.email;
                thisUser.userID = tmpUser.userID;
                thisUser.userPSW = tmpUser.userPSW;
                thisUser.userImg = tmpUser.userImg;
});
Dharmesh Dhorajiya
  • 3,976
  • 9
  • 30
  • 39
Fred Novack
  • 727
  • 9
  • 27

1 Answers1

2

Your initWithCoder: methods are incorrect. They need to be in the following pattern:

- (instancetype)initWithCoder:(NSCoder *)decoder {
    self = [super init]; // or [super initWithCoder:decoder] if appropriate
    if (self) {
        _someIvar = [decoder decodeObjectForKey:@"someKey"];
        _someOtherIvar = [decoder decodeObjectForKey:@"someOtherKey"];
    }

    return self;
}

Fixing the initWithCoder: method for both your CurrentUser and Friend classes will help a lot.

CurrentUser:

- (id)initWithCoder:(NSCoder *)decoder {
    self = [super init];
    if (self) {
        _username = [decoder decodeObjectForKey:@"username"];
        _email = [decoder decodeObjectForKey:@"email"];
        //testing direct friend loading
        Friend *testFriend = [decoder decodeObjectForKey:@"testFriend"];
        _userPSW = [decoder decodeObjectForKey:@"userpassword"];
        _userImg = [UIImage imageWithData:[decoder decodeObjectForKey:@"userImg"]];
        _FriendsList = [decoder decodeObjectForKey:@"FriendsList"];
        _userID = [decoder decodeObjectForKey:@"userID"];
        _groups = [decoder decodeObjectForKey:@"groups"];
    }

    return self;
}

Friend:

- (id)initWithCoder:(NSCoder *)decoder {
    self = [super init];
    if (self) {
        _username = [decoder decodeObjectForKey:@"friendUN"];
        _userImg = [UIImage imageWithData:[decoder decodeObjectForKey:@"friendIMG"]];
        _userID = [decoder decodeObjectForKey:@"friendID"];
    }

    return self;
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579