使用Mantle编码c-struct(NSCoding)

时间:2013-12-09 13:32:16

标签: ios struct nscoding github-mantle

我想使用Mantle框架(https://github.com/github/Mantle)来支持带有struct属性的类的NSCoding:

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

但当我尝试[NSKeyedArchiver archiveRootObject:obj toFile:@"file"];在MTLModel + NSCoding.m中崩溃时,在- (void)encodeWithCoder:(NSCoder *)coder在线

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

Mantle是否支持c-struct编码(以及解码),或者我需要为这些类自定义实现NSCoding协议?

2 个答案:

答案 0 :(得分:4)

我的原始数据结构是XML(是的,我知道):

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

我使用基于MTLXMLAdapter的{​​{1}},但您可以看到它如何适用于任何其他序列化程序。

KissXML

如果需要,您可以添加+ (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)]; }]; }

答案 1 :(得分:4)

比我想象的容易:

  1. 排除+encodingBehaviorsByPropertyKey
  2. 中的属性
  3. 手动编码/编码排除属性
  4. 样品:

    #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)];
    }