Mantle property class based on another property?

折月煮酒 提交于 2019-12-21 04:35:15

问题


How can I use Github Mantle to choose a property class based on another property in the same class? (or in the worse case another part of the JSON object).

For example if i have an object like this:

{
  "content": {"mention_text": "some text"},
  "created_at": 1411750819000,
  "id": 600,
  "type": "mention"
}

I want to make a transformer like this:

+(NSValueTransformer *)contentJSONTransformer {
    return [MTLValueTransformer transformerWithBlock:^id(NSDictionary* contentDict) {
          return [MTLJSONAdapter modelOfClass:ETMentionActivityContent.class fromJSONDictionary:contentDict error:nil];
    }];
}

But the dictionary passed to the transformer only includes the 'content' piece of the JSON, so I don't have access to the 'type' field. Is there anyway to access the rest of the object? Or somehow base the model class of 'content' on the 'type'?

I have previously been forced to do hack solutions like this:

+(NSValueTransformer *)contentJSONTransformer {
    return [MTLValueTransformer transformerWithBlock:^id(NSDictionary* contentDict) {
        if (contentDict[@"mention_text"]) {
            return [MTLJSONAdapter modelOfClass:ETMentionActivityContent.class fromJSONDictionary:contentDict error:nil];
        } else {
            return [MTLJSONAdapter modelOfClass:ETActivityContent.class fromJSONDictionary:contentDict error:nil];
        }
    }];
}

回答1:


You can pass the type information by modifying the JSONKeyPathsByPropertyKey method:

+ (NSDictionary *)JSONKeyPathsByPropertyKey
{
    return @{
        NSStringFromSelector(@selector(content)) : @[ @"type", @"content" ],
    };
}

Then in contentJSONTransformer, you can access the "type" property:

+ (NSValueTransformer *)contentJSONTransformer 
{
    return [MTLValueTransformer ...
        ...
        NSString *type = value[@"type"];
        id content = value[@"content"];
    ];
}



回答2:


I've had a similar issue, and I suspect my solution isn't much better than yours.

I have a common base class for my Mantle objects, and after each is constructed, I call a configure method to give them chance to set up properties that are dependent on more than one "base" (== JSON) property.

Like this:

+(id)entityWithDictionary:(NSDictionary*)dictionary {

    NSError* error = nil;
    Class derivedClass = [self classWithDictionary:dictionary];
    NSAssert(derivedClass,@"entityWithDictionary failed to make derivedClass");
    HVEntity* entity = [MTLJSONAdapter modelOfClass:derivedClass fromJSONDictionary:dictionary error:&error];
    NSAssert(entity,@"entityWithDictionary failed to make object");
    entity.raw = dictionary;
    [entity configureWithDictionary:dictionary]; // Give the new entity a chance to set up derived properties
    return entity;
}


来源:https://stackoverflow.com/questions/26122616/mantle-property-class-based-on-another-property

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!