objective c - object mapping using introspection restkit -
i'm trying parse soap response using restkit. i'm able convert soap xml response objects if define mappings , relationships myself. but, wondering if it's possible use introspection (or else) automatically convert soap xml response objective-c object.
sample 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>
i convert xml object:
@interface return : nsobject @property (strong, nonatomic) nsinteger userid; // attribute @property (strong, nonatomic) location *location; // relation @end
the closest thing come using introspection on return class properties , using each attribute: [mapping addattributemapping:[rkobjectattributemapping mappingfromkeypath:@"userid.text" tokeypath:@"userid"]];
and relations, again use introspection find out class objects , use maprelationship:withmapping: on each one
i ended defining method recursively maps properties xml nodes if names match. naming convention , data type of property important work.
i've tried best clean before post here, let me know if need help.
- (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); (i = 0; < 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" nsdate class typeclass = nsclassfromstring(typeclassname); if (typeclass != nil && ![typeclassname hasprefix:@"ns"]) { // 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; }
and map automatically call as:
[self mapme:[myclass class]];
Comments
Post a Comment