Encoding c-struct with Mantle (NSCoding)

I want to use Mantle framework (https://github.com/github/Mantle) to support NSCoding for my class with struct property:

typedef struct {
    int x;
    int y;
} MPoint;

typedef struct {
    MPoint min;
    MPoint max;
} MRect;


@interface MObject : MTLModel

@property (assign, nonatomic) MRect rect;

@end

@implementation MObject
@end

But when I tried to [NSKeyedArchiver archiveRootObject:obj toFile:@"file"]; its crashed in MTLModel+NSCoding.m, in - (void)encodeWithCoder:(NSCoder *)coder on line

case MTLModelEncodingBehaviorUnconditional:
    [coder encodeObject:value forKey:key];

Does Mantle supports c-struct encoding (and also decoding) or I've need to custom implementing NSCoding protocol for such classes?

Answers


My original data structure is an XML (yeah, I know):

  ...
  <Lat>32.062883</Lat>
  <Lot>34.782904</Lot>
  ...

I used MTLXMLAdapter based on KissXML, but you can see how it's applicable to any other serializer.

+ (NSValueTransformer *)coordinateXMLTransformer {
    return [MTLValueTransformer reversibleTransformerWithBlock:^id(NSArray *nodes) {
        CLLocationCoordinate2D coordinate;
        for (DDXMLNode *node in nodes) {
            if ([[node name] isEqualToString:@"Lat"]) {
                coordinate.latitude = [[node stringValue] doubleValue];
            } else if ([[node name] isEqualToString:@"Lot"]) {
                coordinate.longitude = [[node stringValue] doubleValue];
            }

        }
        return [NSValue value:&coordinate
                 withObjCType:@encode(CLLocationCoordinate2D)];
    }];
}

You can add a reverseBlock if needed.


It was easier than I thought:

  1. Exclude property in +encodingBehaviorsByPropertyKey
  2. Manual encode/encode excluded property

Sample:

#pragma mark - MTLModel + NSCoding

- (id)initWithCoder:(NSCoder *)coder {
    self = [super initWithCoder:coder];
    if (self) {
        self.rect = [[self class] mRectFromData:[coder decodeObjectForKey:@"rectData"]];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)coder {
    [super encodeWithCoder:coder];

    [coder encodeObject:[[self class] dataFromMRect:self.rect] forKey:@"rectData"];
}

+ (NSDictionary *)encodingBehaviorsByPropertyKey {
    NSDictionary *excludeProperties = @{
                                        NSStringFromSelector(@selector(rect)): @(MTLModelEncodingBehaviorExcluded)
                                        };
    NSDictionary *encodingBehaviors = [[super encodingBehaviorsByPropertyKey] mtl_dictionaryByAddingEntriesFromDictionary:excludeProperties];
    return encodingBehaviors;
}

#pragma mark - MRect transformations

+ (MRect)mRectFromData:(NSData *)rectData {
    MRect rect;
    [rectData getBytes:&rect length:sizeof(rect)];
    return rect;
}

+ (NSData *)dataFromMRect:(MRect)rect {
    return [NSData dataWithBytes:&rect length:sizeof(rect)];
}

Need Your Help

Prevent window from being shown by another application

winapi

I am using the ShowWindow function in Windows to show and hide specific windows which are not created by my own application. The use of this function is simple, as you basically only have to pass the

Python script embedded in HTML

python html

I've seen many questions that ask similar things, but I felt none of them asked it in this particular way. I have a Python script that asks for an input number and attempts to calculate another nu...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.