I am developing iphone application.
I use NSCoder.
MyApplication.h
#define ITEMS_KEY @\"items\"
#define CATEGORIES_KEY @\"categories\"
#imp
I wrote a helper function for using NSCoding. It's a part of VSCore Library. Check it out here:
@interface QuickCoding : NSObject
+ (void)quickEncode:(NSObject<NSCoding>*)object withEncoder:(NSCoder*)encoder;
+ (void)quickDecode:(NSObject<NSCoding>*)object withDecoder:(NSCoder*)decoder;
@end
And the .m file:
#import "QuickCoding.h"
#import "ReflectionHelper.h"
#define QUICK_CODING_HASH @"h4"
@implementation QuickCoding
+ (void)quickEncode:(NSObject<NSCoding>*)object withEncoder:(NSCoder *)encoder{
NSArray *codingKeys = [ReflectionHelper fieldsList:[object class]];
NSUInteger hash = [[codingKeys componentsJoinedByString:@""] hash];
[encoder encodeObject:@(hash) forKey:QUICK_CODING_HASH];
[codingKeys enumerateObjectsUsingBlock:^(NSString *key, __unused NSUInteger idx, __unused BOOL *stop) {
id val = [object valueForKey:key];
if ([val conformsToProtocol:@protocol(NSCoding)]){
[encoder encodeObject:val forKey:key];
}
}];
}
+ (void)quickDecode:(NSObject<NSCoding>*)object withDecoder:(NSCoder *)decoder{
NSArray *codingKeys = [ReflectionHelper fieldsList:[object class]];
NSUInteger hash = [[codingKeys componentsJoinedByString:@""] hash];
NSUInteger decodedHash = [[decoder decodeObjectForKey:QUICK_CODING_HASH] unsignedIntegerValue];
BOOL equalHash = hash == decodedHash;
[codingKeys enumerateObjectsUsingBlock:^(NSString *key, __unused NSUInteger idx, __unused BOOL *stop) {
id val = [decoder decodeObjectForKey:key];
if (equalHash || val){
[object setValue:val forKey:key];
}
}];
}
@end
Full code is here: https://github.com/voipswitch/VSCore/tree/master/VSCore/Storage
Here is the NSCoding protocal methods from my LogEntry object, you can ignore the switch statement and the schema details though, those are from a base class I have written that allows me to keep sane track of changing data formats.
Please note that in addition to using decodeObjectForKey: you also need to make sure you retain/copy the given values as they are autoreleased when received.
- (id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self != nil) {
switch ([schemaVersion intValue]) {
case 2:
filepath = [[coder decodeObjectForKey:@"filepath"] copy];
identifier = [coder decodeInt64ForKey:@"identifier"];
level = [coder decodeIntForKey:@"level"];
lineNumber = [[coder decodeObjectForKey:@"lineNumber"] retain];
message = [[coder decodeObjectForKey:@"message"] retain];
timestamp = [[coder decodeObjectForKey:@"timestamp"] retain];
break;
default:
[self release], self = nil;
break;
}
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:filepath forKey:@"filepath"];
[coder encodeInt64:identifier forKey:@"identifier"];
[coder encodeInt:level forKey:@"level"];
[coder encodeObject:lineNumber forKey:@"lineNumber"];
[coder encodeObject:message forKey:@"message"];
[coder encodeObject:timestamp forKey:@"timestamp"];
[super encodeWithCoder:coder];
}
I think you should be using -decodeObjectForKey:
Use -decodeObjectForKey:
and read the documentation.