2012-06-27 165 views
0

我想使用RestKit解析SOAP響應。如果我自己定義映射和關係,我能夠成功地將SOAP XML響應轉換爲對象。但是,我想知道是否可以使用自省(或其他)來自動將SOAP XML響應轉換爲Objective-C對象。使用introspection restkit的對象映射

示例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 

我能想出用在返回類的自省來獲取所有最接近的事屬性和使用類似這樣的每個屬性: [映射addAttributeMapping:[RKObjectAttributeMapping mappingFromKeyPath:@「userId.text」toKeyPath:@「userId」]];

而對於關係,我可以再次使用自省,找出我所有的類對象和使用mapRelationship:withMapping:在每一個

+0

你爲什麼不使用Sudzc?管道代碼是自動生成的,你只需要提出請求並處理它。它也會創建所有相關的對象 – doNotCheckMyBlog

+0

我已經嘗試過Sudzc,並且爲我的wsdl生成了一些代碼。我聽說它適用於很多人,但在我的情況下它並沒有! – pshah

+0

爲什麼沒有?任何特定的錯誤?正在使用第三方wsdl?還是你自己的? – doNotCheckMyBlog

回答

0

我最終確立了性能遞歸映射到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]];