-
Notifications
You must be signed in to change notification settings - Fork 27
Custom type mappings Custom classes
Let’s say you have a custom object which is returned by your webservice and looks like this:
Class Book
- String title
- String publisher
- Number year
ASObjects are key-value compliant. That means you can use them like any other dictionary:
ASObject *book = [AMFUnarchiver unarchiveObjectWithData:myAMFData encoding:kAMF3Version];
NSLog(@"title: %@, year: %d", [book valueForKey:title], [[book valueForKey:year] intValue]);
Alternatively you could have a class around which is also named Book
. Now you’re responsible for decoding the object yourself, by implementing the NSCoding protocol. You’re class would look like this:
@interface Book : NSObject
{
NSString *title;
NSString *publisher;
NSNumber *year;
}
@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSString *publisher;
@property (nonatomic, retain) NSNumber *year;
@end
@implementation Book
@synthesize title, publisher, year;
- (id)initWithCoder:(NSCoder *)coder
{
if (self = [super init])
{
self.title = [coder decodeObjectForKey:@"title"];
self.publisher = [coder decodeObjectForKey:@"publisher"];
self.year = [coder decodeObjectForKey:@"year"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:title forKey:@"title"];
[encoder encodeObject:publisher forKey:@"publisher"];
[encoder encodeObject:year forKey:@"year"];
}
@end
Now you’re class is ready to be serialized and deserialized from and to AMF.
Imaging you had the very same class Book
but you’re a good Cocoa citizen and namespaced your class, so that it’s called MyBook. There would be now way for CocoaAMF to figure out, that Book
from your webservice should become MyBook
on the client side. That’s why you need to register it, either
[AMFUnarchiver setClass:[MyBook class] forClassName:@"Book"];
[AMFArchiver setClassName:@"Book" forClass:[MyBook class]];
which will affect every instance of AMFArchiver and AMFUnarchiver. Or you could do it
AMFUnarchiver *unarchiver = [[AMFUnarchiver alloc] initForReadingWithData:myAMFData encoding:kAMF3Version];
[unarchiver setClass:[MyBook class] forClassName:@"Book"];
which of course will only affect the used unarchiver.
Externalizable classes are non-keyed archives in Cocoa context, where they are infrequently used. Nevertheless since externalizable classes are the only way in Flash to control the serialization you’ll might want to use them. So let’s jump back to example 2, but this time with a class which supports its externalized counterpart:
@interface Book : NSObject
{
NSString *title;
NSString *publisher;
NSNumber *year;
}
@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSString *publisher;
@property (nonatomic, retain) NSNumber *year;
@end
@implementation Book
@synthesize title, publisher, year;
- (id)initWithCoder:(NSCoder *)coder
{
if (self = [super init])
{
self.title = [coder decodeObject];
self.publisher = [coder decodeObject];
self.year = [coder decodeObject];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:title];
[encoder encodeObject:publisher];
[encoder encodeObject:year];
}
@end
You see it’s essentially the same and only uses a non-keyed archiver this time. Of course you can call allowsKeyedCoding
in order to know whether the AMFUnarchiver/AMFArchiver is in keyed coding mode or not.