Search code examples
objective-cparse-platformnscoder

Having trouble archiving custom object


So I am having this custom made class:

LocationSupplementaryObject.h:

@interface LocationSupplementaryObject : NSObject <NSCoding>

@property (nonatomic) NSString* storedPlaceName;

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

- (void)saveCustomObject:(LocationSupplementaryObject *)object key:(NSString *)key;
- (LocationSupplementaryObject *)loadCustomObjectWithKey:(NSString *)key;
@end

LocationSupplementaryObject.m:

@implementation LocationSupplementaryObject

- (id)initWithLocationName:(NSString *)locationName
{
    self = [super init];
    if (self) {
        self.storedPlaceName = locationName;
        NSLog(@"Initialization success! Name is %@",self.storedPlaceName);
    }
    return self;
}

-(void)encodeWithCoder:(NSCoder *)encoder {
    // Encode the properties of the object
    [encoder encodeObject:self.storedPlaceName forKey:@"stored_placeName"];
}

-(id)initWithCoder:(NSCoder *)decoder {
    self = [super init];
    if (self) {
        // Decode properties for the object
        self.storedPlaceName = [decoder decodeObjectForKey:@"stored_placeName"];
    }
    return self;
}

- (void)saveCustomObject:(LocationSupplementaryObject *)object key:(NSString *)key {
    NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:object];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:encodedObject forKey:key];
    [defaults synchronize];

}

- (LocationSupplementaryObject *)loadCustomObjectWithKey:(NSString *)key {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSData *encodedObject = [defaults objectForKey:key];
    LocationSupplementaryObject *object = [NSKeyedUnarchiver unarchiveObjectWithData:encodedObject];
    return object;
}

@end

So later in my program I am using LocationSupplementaryObject class:

LocationSupplementaryObject *suppObject = [[LocationSupplementaryObject alloc]initWithLocationName:[object objectForKey:(NSString*)kCCName]];

//  Writing the object to defaults

    [suppObject saveCustomObject:suppObject key:@"StoredLocation"];
    NSLog(@"%@ Successfully packed",suppObject.storedPlaceName);

    LocationSupplementaryObject *newObject = [[LocationSupplementaryObject alloc]init];
    [newObject loadCustomObjectWithKey:@"StoredLocation"];
    NSLog(@"Re initializing from defaults %@",newObject.storedPlaceName);

To initialise the name, I am taking object, loaded from the parse.com, we could see that suppObject.storedPlaceName is set correctly trough NSLog message. But, name retrieved and unarchived from NSUserDefaults turns out to be (null), I know that NSUserDefaults could be slow, even though we called synchronise so I am checking for the object in another side of program:

LocationSupplementaryObject *suppObject = [[LocationSupplementaryObject alloc]init];
[suppObject loadCustomObjectWithKey:@"StoredLocation"];
if (suppObject) {
NSLog(@"We got our name %@",suppObject.storedPlaceName);
}

And even though class was initialised with a legit NSString, it still shows me (null) for the name stored in NSUserDefaults. I should admit, that I doesn't have a lot of experience with NSCoder, so any help will be appreciated.


Solution

  • Your load and save methods should be class methods. Creating them as instance methods means you're getting consused and not dealing with the return values. So the object you expect to be one thing actually isn't. Your coder code is actually fine.