0

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 クラスでイントロスペクションを使用してすべてのプロパティを取得し、各属性に対して次のようなものを使用することです。 ;

リレーションについては、イントロスペクションを使用してすべてのクラス オブジェクトを見つけ、それぞれに対して mapRelationship:withMapping: を使用できます。

4

1 に答える 1

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]];
于 2012-07-12T00:41:42.427 に答える