使用自省restkit的对象映射

Posted

技术标签:

【中文标题】使用自省restkit的对象映射【英文标题】:object mapping using introspection restkit 【发布时间】:2012-06-27 01:35:53 【问题描述】:

我正在尝试使用 RestKit 解析 SOAP 响应。如果我自己定义映射和关系,我就能够成功地将 SOAP XML 响应转换为对象。但是,我想知道是否可以使用自省(或其他方法)将 SOAP XML 响应自动转换为 Objective-C 对象。

示例 XML:

<return>
    <userId xsi:type="xsd:int">1113050187</userId>
    <location xsi:type="ns1:Location">
       <city xsi:type="xsd:string">San Francisco</city>
       <state xsi:type="xsd:string">California</state>
    </location>
</return>

我想把这个 XML 转换成这个对象:

@interface Return : NSObject

@property (strong, nonatomic) NSInteger userId; // attribute
@property (strong, nonatomic) Location *location; // relation

@end

我能想到的最接近的方法是在 Return 类上使用自省来获取所有属性,并对每个属性使用类似的东西: [映射addAttributeMapping:[RKObjectAttributeMapping mappingFromKeyPath:@"userId.text" toKeyPath:@"userId"]];

对于关系,我可以再次使用自省来找出我所有的类对象并在每个对象上使用 mapRelationship:withMapping:

【问题讨论】:

你为什么不使用 Sudzc?管道代码是自动生成的,您只需要提出请求并处理它。它也会创建所有相关的对象 我已经尝试过 Sudzc,但为我的 wsdl 生成的代码运气不佳。我听说它适用于很多人,但在我的情况下它没有! 为什么没有?任何具体错误?正在使用第三方 wsdl?还是你自己的? 它是“RESTful 工具包”中的“RestKit”。我不知道它与 SOAP 接口的兼容性如何(但我不是专家)。你为什么不像@Owl 所说的那样使用 Sudzc - 它就是它的用途。 我什至无法使用 ARC 编译生成的代码。如果没有 ARC,我的很多调用都不会按预期工作,并且发现它有问题并且有很多内存泄漏。我正在使用我自己的由 Zend Soap 服务器生成的 wsdl。就像我之前说的,我听说过关于 Sudzc 的好消息,但不幸的是它对我的项目不起作用。 【参考方案1】:

我最终定义了一个方法,如果它们的名称匹配,则递归地将属性映射到 XML 节点。命名约定和属性的数据类型对于它的工作很重要。

在将其发布到此处之前,我已尽力清理此问题,但如果您需要任何帮助,请告诉我。

- (RKObjectMapping *)mapMe:(Class)class

    RKObjectManager *objectManager = [RKObjectManager sharedManager];
    RKObjectMapping *mapping = [RKObjectMapping mappingForClass:class];
    id classType = objc_getClass([NSStringFromClass(class) UTF8String]);
    unsigned int outCount, i;
    objc_property_t *properties = class_copyPropertyList(classType, &outCount);
    for (i = 0; i < outCount; i++) 
        objc_property_t property = properties[i];
//        fprintf(stdout, "%s\n", property_getName(property));

        const char *type = property_getAttributes(property);
        NSString *typeString = [NSString stringWithUTF8String:type];
        NSArray *attributes = [typeString componentsSeparatedByString:@","];
//        NSLog(@"attributes = %@", attributes);
        NSString *typeAttribute = [attributes objectAtIndex:0];
//        NSLog(@"typeAttribute = %@", typeAttribute);
        NSString *propertyType = [typeAttribute substringFromIndex:1];

        if ([propertyType hasPrefix:@"@"] && [propertyType length] > 1) 
            NSString * typeClassName = [propertyType substringWithRange:NSMakeRange(2, [propertyType length]-3)];  //turns @"NSDate" into NSDate
            Class typeClass = NSClassFromString(typeClassName);
            if (typeClass != nil && ![typeClassName hasPrefix:@"NS"]) 
//            my custom class detected.
                RKObjectMapping *subMapping = [self mapMe:typeClass forObjectManager:objectManager];
                [mapping mapRelationship:[NSString stringWithUTF8String:property_getName(property)] withMapping:subMapping];
                [objectManager.mappingProvider setMapping:subMapping forKeyPath:[NSString stringWithUTF8String:property_getName(property)]];
             else 
                [mapping addAttributeMapping:[RKObjectAttributeMapping mappingFromKeyPath:[NSString stringWithFormat:@"%@.text", [NSString stringWithUTF8String:property_getName(property)]] toKeyPath:[NSString stringWithUTF8String:property_getName(property)]]];
            
        
    
    free(properties);
    return mapping;

然后将其映射自动调用为:

[self mapMe:[Myclass class]];

【讨论】:

以上是关于使用自省restkit的对象映射的主要内容,如果未能解决你的问题,请参考以下文章

RestKit 仅用于对象映射

RestKit 更新对象映射空属性

RestKit - 没有对象映射的请求

Restkit 0.20 嵌套对象数组映射问题

Restkit 对象映射在映射过程中遇到错误

RestKit:将单个对象映射到现有数组