I have added category methods to NSUserDefaults to store and retrieve encoded objects (in this case, an NSArray). I am having a problem retrieving the encoded data. Here is my code:
- (void)encodeObject:(id<NSCoding>)object forKey:(NSString *)key {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:object requiringSecureCoding:NO error:nil];
[self setObject:data forKey:key];
[self synchronize];
}
- (id)decodeObjectForKey:(NSString *)key class:(Class)aClass {
NSData *data = [self objectForKey:key];
NSError *error = nil;
id object = [NSKeyedUnarchiver unarchivedObjectOfClass:aClass fromData:data error:&error];
NSLog(@"E: %@ %@", error.localizedDescription, object);
return object;
}
Calling [[NSUserDefaults standardDefaults] encodeObject:object forKey:key]
should encode the object passed and store it in defaults, and then calling [[NSUserDefaults standardDefaults] decodeObjectForKey:key class:aClass
should return the encoded object.
The problem is that [NSKeyedUnarchiver unarchivedObjectOfClass:fromData:error:]
is returning nil
, and the error text is logged as The data couldn’t be read because it isn’t in the correct format.
. The data retrieved using [self objectForKey:]
is of type __NSCFData
. I don't know if this is relevant since AFAIK __NSCFData is toll-free bridged to NSData.
Replacing [NSKeyedUnarchiver unarchivedObjectOfClass:fromData:error:]
with [NSKeyedUnarchiver unarchiveObjectWithData:]
solves the problem. The data are stored and retrieved correctly. But this method is now deprecated so I need to move to the more modern method, but cannot identify why it isn't working.
I had a similar issue. I found that I had to pass in the classes for the objects that were in the NSArray.
NSSet *set = [NSSet setWithArray:@[
[NSArray class],
[STUFF_IN_ARRAY class]
]];
NSArray *results = [NSKeyedUnarchiver unarchivedObjectOfClasses:set fromData: rawData error: &error];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With