使用自省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的对象映射的主要内容,如果未能解决你的问题,请参考以下文章