I have a JSON end path which accepts post requests in the following format.
{'values': [
{
"date":<measurement date as Unix time stamp>
"value":<weight>
}
{
"date":<measurement date as Unix time stamp>
"value":<weight>
}
...]}
"Values" is represented by the class "EntryCollection", while each value is represented by the class "Entry". I am puzzled finding the correct way to map my objects to the JSON representation. Right now I have the following code which causes the error: "The mapping operation was unable to find any nested object representations at the key paths searched".
RKObjectMapping *entryMapping = [RKObjectMapping requestMapping];
RKObjectMapping *valuesMapping = [RKObjectMapping mappingForClass:[EntriesCollection class]];
[valuesMapping addAttributeMappingsFromDictionary:[EntryCollection attributesMapping]];
[singleEntryMapping addAttributeMappingsFromDictionary:[SingleEntry attributesMapping]];
[singleEntryMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"entries" toKeyPath:#"entries" withMapping:valuesMapping]];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:entryMapping
objectClass:mappedClass
rootKeyPath:nil];
[self.objectManager addRequestDescriptor:requestDescriptor];
NSString *path = [self pathForPOST];
[self.objectManager postObject:weights path:path parameters:nil success:nil failure:nil];
EDIT for data structure
My data structure is simple (I suppose):
EntryCollection
- NSArray *entries (a collection of objects of type Entry)
Entry
- NSDate *date
- NSNumber *weight;
I would like to POST an EntryCollection filled with entries. The mapping of EntryCollection is "entries -> values", the one of Entry is "date -> date, weight -> value".
In any case, your JSON request payload must confirm to following data structure:
NSArray
|
|______NSDictionary ->Key: Date Value: weight
| ->Key: value Value: weight
|
|______NSDictionary ->Key: Date Value: weight
| ->Key: value Value: weight
|
|______NSDictionary ->Key: Date Value: weight
->Key: value Value: weight
Both NSArray and NSDictionary are fully compatible with JSON data format. I don't know about your underlying object structure, but ultimately this array should get posted as request payload NSData, and you will be done.
Well, if you have an issue in mapping, then you'll either have to show your model and class and mapping, or put RKLogConfigureByName("RestKit/ObjectMapping", RKLogLevelTrace); somewhere in your code and let us see output.
As an alternative, if your entities structure varies from what you want to Post to the server, you can use embedded AFNetworking client and do a simple request.
[[RKObjectManager sharedManager].HTTPClient postPath:#"" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"WHOOO");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//
}];
I have found the solution. Turns out, I needed a relationship mapping to describe the hierarchy implied in the JSON. Since there is no type for each entity of values, I created an "empty" mapping and added the relationship mapping to it.
I also forgot to set the correct MIMEType and inverse the attributes mapping of my class. I guess a few days in restkit are needed to get a grasp of it.
RKObjectMapping *entryMapping = [RKObjectMapping requestMapping];
[entryMapping addAttributeMappingsFromDictionary:[SingleEntry attributesMapping]];
RKObjectMapping *entrySerializedMapping = [entryMapping inverseMapping];
RKRelationshipMapping *entryRelationship = [RKRelationshipMapping relationshipMappingFromKeyPath:#"entries" toKeyPath:#"values" withMapping:entrySerializedMapping];
RKObjectMapping *valueMapping = [RKObjectMapping requestMapping];
[valueMapping addPropertyMapping:valueMapping];
RKRequestDescriptor *descriptor = [RKRequestDescriptor requestDescriptorWithMapping:valueMapping objectClass:[EntriesCollection class] rootKeyPath:nil];
[self.objectManager addRequestDescriptor:descriptor];
self.objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
NSString *path = [self pathForPOST];
[self.objectManager postObject:entryCollection path:path parameters:nil success:nil failure:nil];
Related
I have an iOS app that uses RestKit to sync between my Core Data model and a Rails API.
I have Game and Team entities in my Core Data model. A Game has a to-many relationship to Teams. I am trying to update the 'score' attribute of the Teams, and then I am trying to run the putObject method on my RKObjectManager by sending in the Game. The scores of the teams are not updating on the server.
If I change an attribute of the Game, e.g. the 'state', and then send in the Game with putObject, it works correctly.
Is it possible to update more than one object with putObject given that the object has nested objects inside of it? Or do I need to run putObject on the Team when I update its 'score' attribute?
Here is my mapping code for Games.
Class itemClass = [Game class];
RKEntityMapping *mapping = [RKEntityMapping
mappingForEntityForName:#"Game"
inManagedObjectStore:managedObjectStore];
mapping.identificationAttributes = #[#"gameID"];
NSDictionary *standardDict = #{#"id": #"gameID",
#"created_at": #"createdAt",
#"updated_at": #"updatedAt"};
NSDictionary *gameDict = #{#"league_id": #"leagueID",
#"location_id": #"locationID",
#"state": #"state",
//.... more attributes....
};
[mapping addAttributeMappingsFromDictionary:standardDict];
[mapping addAttributeMappingsFromDictionary:gameDict];
[mapping addConnectionForRelationship:#"league" connectedBy:#{#"leagueID": #"leagueID"}];
[mapping addConnectionForRelationship:#"location" connectedBy:#{#"locationID": #"locationID"}];
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
NSString *keyPath = nil;
NSString *itemsPath = #"games/:gameID";
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:mapping
method:RKRequestMethodAny
pathPattern:itemsPath
keyPath:keyPath
statusCodes:statusCodes];
[manager addResponseDescriptor:responseDescriptor];
NSString *itemPath = #"game";
RKEntityMapping *requestMapping = [mapping inverseMapping];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping
objectClass:itemClass
rootKeyPath:itemPath
method:RKRequestMethodAny];
[manager addRequestDescriptor:requestDescriptor];
//route for manipulating with existing object
RKRoute *itemRoute = [RKRoute routeWithClass:itemClass pathPattern:#"games/:gameID" method:RKRequestMethodAny];
itemRoute.shouldEscapePath = YES;
[manager.router.routeSet addRoutes:#[itemRoute]];
The mapping for a Team is written basically the exact same way, except a Team has a connection to a Game based on the Game's 'gameID.' So --> [mapping addConnectionForRelationship:#"game" connectedBy:#{#"gameID": #"gameID"}];
You are using foreign key mappings on your response mapping:
[mapping addConnectionForRelationship:#"league" connectedBy:#{#"leagueID": #"leagueID"}];
[mapping addConnectionForRelationship:#"location" connectedBy:#{#"locationID": #"locationID"}];
and these are not reversed when you use inverseMapping (because they don't contain enough information to create the inverse).
So, your requestMapping needs to be explicitly updated to include a relationship mapping to tell RestKit to process the relationship and how to map the relationship contents into the resulting JSON.
Is there a way to POST large NSObject-derived object structures without having to manually specify every property and property collection to RestKit?
Here is a simple example, with a single class DABUser But imagine it contained properties which were also objects, collections, and those had more of the same to represent some larger object tree.
The class to POST:
#interface DABUser : NSObject
#property (nonatomic) int age;
#property (copy, nonatomic) NSString *name;
#end
POST a DABUser object:
RKObjectMapping *userMapping = [RKObjectMapping requestMapping];
[userMapping addAttributeMappingsFromArray:#[ #"age", #"name"]];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:userMapping objectClass:[DABUser class] rootKeyPath:nil method:RKRequestMethodPOST];
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:#"http://localhost:3000"]];
objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
[objectManager addRequestDescriptor:requestDescriptor];
DABUser *user = [[DABUser alloc] init];
user.age = 20;
user.name = #"Charlie Brown";
[objectManager postObject:user path:#"users/123" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"Success!");
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"Failed!");
}];
The JSON generated from the above code being and sent via the request body is:
{ "age":20,"name":"Charlie Brown" }
When I have a large object tree, defining the property mappings can get tiresome (and error-prone), with many lines of similar code to this example's:
RKObjectMapping *userMapping = [RKObjectMapping requestMapping];
[userMapping addAttributeMappingsFromArray:#[ #"age", #"name"]];
Is there a way that I could just get RestKit to generate the JSON from the objects, without all this setup?
"When I have a large object tree, defining the property mappings can get tiresome (and error-prone), with many lines of similar code to this example's:"
I personally think this is the easiest way and a good approach.I have done object mapping to large objects with so many object mapping and multiple object linking and found this is the easiest way to deal with it correctly
So, i m sending a POST request for the first time. I m Mapping classes and as I thought and read from the Documentation that it would work in this way:
Init RK:
- (void)initRK{
if(!manager){
manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:BASE_CONTEXT_URL]];
}
if (!reqMapping) {
reqMapping = [RKObjectMapping requestMapping];
}
}
POST Method:
// Configure a request mapping for our Article class. We want to send back title, body, and publicationDate
RKObjectMapping* deviceRequestMapping = [RKObjectMapping mappingForClass:[DeviceDTO class]];
[deviceRequestMapping addAttributeMappingsFromArray:#[ #"model", #"name", #"systemName", #"systemVersion", #"devToken" ]];
RKObjectMapping* msRequestMapping = [RKObjectMapping mappingForClass:[MemberShipDTO class]];
[msRequestMapping addAttributeMappingsFromArray:#[ #"validSince", #"validTill" ]];
RKObjectMapping* countryRequestMapping = [RKObjectMapping mappingForClass:[CountryDTO class]];
[countryRequestMapping addAttributeMappingsFromArray:#[ #"idNumberDTO", #"iso2DTO", #"short_nameDTO", #"calling_codeDTO" ]];
RKObjectMapping* userRequestMapping = [RKObjectMapping requestMapping];
[userRequestMapping addAttributeMappingsFromArray:#[ #"displayName", #"phoneNumber", #"status", #"userID" ]];
[userRequestMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil toKeyPath:#"device" withMapping:deviceRequestMapping]];
[userRequestMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil toKeyPath:#"memberShip" withMapping:msRequestMapping]];
[userRequestMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:nil toKeyPath:#"country" withMapping:countryRequestMapping]];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:userRequestMapping objectClass:[User class] rootKeyPath:#"user"];
//Create Objects
UserDTO *user = [[UserDTO alloc]init];
user.displayName = userDTO.displayName;
user.phoneNumber = userDTO.phoneNumber;
user.status = userDTO.status;
user.userID = userDTO.userID;
user.country = userDTO.country;
DeviceDTO *device = [[DeviceDTO alloc]init];
device.name = devDTO.name;
device.systemName = devDTO.systemName;
device.systemVersion = devDTO.systemVersion;
device.model = devDTO.model;
device.devToken = [[NSUserDefaults standardUserDefaults]objectForKey:PUSHTOKEN_USER_DEFAULTS_KEY];
user.deviceInfo = device;
MemberShipDTO *ms = [[MemberShipDTO alloc]init];
ms.validSince = [NSDate date];
ms.validTill = [[UtilitieHandler new] getDateByAdd:+1 :0 :0 :0];
user.memberShipDetails = ms;
[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:#"application/json"];
[[RKObjectManager sharedManager] setRequestSerializationMIMEType:RKMIMETypeJSON];
[[RKObjectManager sharedManager] setAcceptHeaderWithMIMEType:RKMIMETypeJSON];
[[RKObjectManager sharedManager] addRequestDescriptor:requestDescriptor];
[[RKObjectManager sharedManager] postObject:user path:#"user/integrate" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult){
RKLogInfo(#"Load collection of Articles: %#", mappingResult.array);
}failure:^(RKObjectRequestOperation *operation, NSError *error) {
RKLogError(#"Operation failed with error: %#", error);
}];
So I tried different things and after i used wireshark to capture the request it returns that theres no content send. That means the mapping is not working correct. I tried a lot and nothing helped. Any advice would be great!
Here the captured packet:
POST /WAZZUUPWS/rest/service/user/integrate HTTP/1.1
Host: 192.168.2.115:8080
Accept-Encoding: gzip, deflate
Accept: application/json
Content-Length: 0
Connection: keep-alive
Accept-Language: de;q=1, en;q=0.9, fr;q=0.8, ja;q=0.7, nl;q=0.6, it;q=0.5
User-Agent: WAZZUUP!/1.0 (iPhone; iOS 6.1.4; Scale/2.00)
It might just be a typo in your question but requestDescriptor doesn't appear to be linked to the UserDTO class.
It seems like you do not have an understanding of Core Data objects yet. Objects that are persisted using Core Data are subclasses of NSManagedObject and have to be created differently. Read further on this link:
http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/CoreData/Articles/cdCreateMOs.html
As for the current problem, you have to use this instead:
NSEntityDescription *entity = [NSEntityDescription entityForName:#"UserDTO" inManagedObjectContext:[RKManagedObjectStore defaultStore].mainQueueManagedObjectContext];
UserDTO *user = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];
However, if UserDTO is a subclass of NSObject, that would need to change to NSManagedObject.
My workflow is something like this - create Core Data model and use mogenerator to automatically generate the NSManagedObject class definitions. Read more about it here:http://raptureinvenice.com/getting-started-with-mogenerator/
I'm struggling to even get basic stuff working in restkit. I am an experienced developer too which makes it even more frustrating.
I have successfully have it posting a json object to my service and via debugging through the RestKit source I have verified that the desired json has been returned. It returns to the success block but with nothing except an empty object.
Here is my code that sets up the mappings and launches the request.
Note: I have obscured some sensitive passwords/urls.
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromDictionary:#{ #"DeviceKey": #"DeviceKey", #"DeviceName": #"DeviceName", #"Password": #"Password", #"Username": #"Username"}];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping
objectClass:[LoginRequest class]
rootKeyPath:nil];
RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[LoginResponse class]];
responseMapping.forceCollectionMapping = YES;
[responseMapping addAttributeMappingsFromDictionary:#{#"TotalBalance":#"TotalBalance",#"FirstName":#"FirstName"}];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping
pathPattern:#"Login"
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:#"http://api.test.com/account/"]];
[manager addRequestDescriptor:requestDescriptor];
[manager addResponseDescriptor:responseDescriptor];
manager.requestSerializationMIMEType = RKMIMETypeJSON;
LoginRequest *request = [[LoginRequest alloc] init];
request.DeviceKey = #"xxxxxxx";
request.DeviceName = #"iPhone";
request.Username = #"mike";
request.Password = #"******";
[manager postObject:request path:#"Login" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
NSArray * array = [result array];
NSDictionary * dictionary = [result dictionary];
NSObject * obj = [result firstObject];
NSLog(#"We object mapped the response with the following result: %#", result);
// It ends up in the success callback but all of these are EMPTY :(
} failure:^(RKObjectRequestOperation *operation, NSError *err){
NSLog(#"We had a problemo");
}];
LogonResponse.h (the .m simply synthisizes them properties)
#import <Foundation/Foundation.h>
#interface LoginResponse : NSObject
#property(nonatomic,assign) double TotalBalance;
#property(nonatomic,retain) NSString * FirstName;
#end
The JSON:
{
"TotalBalance":22.34,
"FirstName":"Mike"
........ other stuff but this shouldn't matter
}
The console is showing:
2013-06-26 14:03:07.173 Tests.com[1666:907] I restkit.support:RKMIMETypeSerialization.m:115 JSON Serialization class 'RKNSJSONSerialization' detected: Registering for MIME Type 'application/json
2013-06-26 14:03:07.181 Tests.com[1666:3907] T restkit.network:RKHTTPRequestOperation.m:139 POST 'http://api.test.com/account/Login':
request.headers={
Accept = "application/json";
"Accept-Language" = "en-GB, en, fr, de, ja, nl, it, es, pt, pt-PT, da, fi, nb, sv, ko, zh-Hans, zh-Hant, ru, pl, tr, uk, ar, hr, cs, el, he, ro, sk, th, id, ms, ca, hu, vi, en-us;q=0.8";
"Content-Type" = "application/json; charset=utf-8";
"User-Agent" = "Tests.com/2.10.31_dev (iPad; iOS 6.1.3; Scale/1.00)";
}
request.body={"DeviceKey":"xxxxxxx","DeviceName":"iPhone","Password":"******","Username":"mike"}
2013-06-26 14:03:07.297 Tests.com[1666:162f] D restkit.network:RKHTTPRequestOperation.m:191 Received authentication challenge
2013-06-26 14:03:08.016 Tests.com[1666:162f] T restkit.network:RKHTTPRequestOperation.m:156 POST 'http://api.test.com/account/Login' (200):
response.headers={
"Content-Length" = 1172;
"Content-Type" = "application/json; charset=utf-8";
Date = "Wed, 26 Jun 2013 04:03:04 GMT";
Server = "Microsoft-IIS/7.5";
Vary = "Accept-Encoding";
"X-Powered-By" = "ASP.NET";
}
response.body={"CustomerReference":"50713881","FirstName":"Mike","TotalBalance":22.25,"ErrorInfo":null,"Success":true}
2013-06-26 14:03:08.021 Tests.com[1666:3b13] W restkit.object_mapping:RKMapperOperation.m:76 Adding mapping error: Cannot map a collection of objects onto a non-mutable collection. Unexpected destination object type 'LoginRequest'
(lldb)
Why is it going on about LoginRequest?? I'm so lost!!
Any help would be very much appreciated.
When you make a post request with RestKit, I believe the mapper tries to map the response to the same object type that was sent. In this case, because a LoginRequest was sent it wants to map the response to a LoginRequest object.
A solution to this might be to create a temporary LoginResponse object and post that with a dictionary containing your login request fields (username, password, etc.). That way, RestKit will be able to map the response into the temporary object that you created.
Upgrading to v0.20.3 fixed this issue.
I'm trying to use RestKit 0.20-pre3 together with RKXMLReaderSerialization and XMLReader in order to map a XML response from a WebService like this:
<ArrayOfAddressBookItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<AddressBookItem>
<CommonName>xxxxxxxxxx</CommonName>
<OU>xxxxxx</OU>
<Name>xxxxxx</Name>
<LastName>xxxxxxxxxx</LastName>
<Service>xxxxxxxxxx</Service>
<Email>xxxxxxxxxxxx</Email>
<InternalPhoneNumber>xxxxxxxxxxx</InternalPhoneNumber>
<ExternalPhoneNumber>xxxxxxxxxxx</ExternalPhoneNumber>
<Mobile>xxxxxxxxxxx</Mobile>
<Street>xxxxxxxxxxx</Street>
<PostalCode>xxxxxxxxxxx</PostalCode>
<City>xxxxxxx</City>
<County>xxxxxxxxx</County>
<SupervisorCommonName>
xxxxxxxxxxxxx
</SupervisorCommonName>
<SupervisorLastName>xxxxxxxxxx</SupervisorLastName>
</AddressBookItem>
<AddressBookItem>
<CommonName>yyyyyyyyyyyy</CommonName>
<OU>
yyyyyyyyyyyyy
</OU>
<Name>yyyyyyyyy</Name>
<LastName>yyyyyyyy</LastName>
<Service>yyyyyyyyyy</Service>
<Email>yyyyyyyyyy</Email>
<InternalPhoneNumber>yyyyyyyyy</InternalPhoneNumber>
<ExternalPhoneNumber>yyyyyyyy</ExternalPhoneNumber>
<Street>yyyyyyyyyyy</Street>
<PostalCode>yyyyyy</PostalCode>
<City>yyyyyy</City>
<County>yyyyyyyy</County>
<SupervisorCommonName>
yyyyyyyyyyy
</SupervisorCommonName>
<SupervisorLastName>yyyyyy</SupervisorLastName>
</AddressBookItem>
<AddressBookItem>
....
</AddressBookItem>
<AddressBookItem>
</ArrayOfAddressBookItem>
In the App Delegation code:
[RKMIMETypeSerialization registerClass:[RKXMLReaderSerialization class] forMIMEType:#"application/xml"];
AFHTTPClient *httpClient = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:#"http://thehostaddress/mywebserviceurl/"]];
httpClient.parameterEncoding = AFFormURLParameterEncoding;
RKObjectManager *objManager = [[RKObjectManager alloc] initWithHTTPClient:httpClient];
[objManager setAcceptHeaderWithMIMEType:RKMIMETypeTextXML];
objManager.requestSerializationMIMEType = RKMIMETypeTextXML;
RKObjectMapping *personMapping = [RKObjectMapping mappingForClass:[PersonItem class]];
[personMapping addAttributeMappingsFromDictionary:#{#"CommonName" : #"commonName", #"OU" : #"ou", #"Name" : #"name", #"LastName" : #"lastName", #"Service" : #"service", #"Email" : #"eMail", #"InternalPhoneNumber" : #"internalPhoneNumber", #"ExternalPhoneNumber" : #"externalPhoneNumber", #"Mobile" : #"mobilePhoneNumber", #"Street" : #"street", #"PostalCode" : #"postalCode", #"City" : #"city", #"County" : #"county", #"SupervisorCommonName" : #"supervisorCommonName", #"SupervisorLastName" : #"supervisorLastName"}];
RKResponseDescriptor *peopleResponse = [RKResponseDescriptor responseDescriptorWithMapping:personMapping pathPattern:#"/mywebserviceurl/" keyPath:#"ArrayOfAddressBookItem" statusCodes:[NSIndexSet indexSetWithIndex:200]];
[objManager addResponseDescriptor:peopleResponse];
later, when I want to get the objects:
[objManager getObjectsAtPath:#"/mywebserviceurl/" parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"SUCCESS: %#", mappingResult);
_items = [[mappingResult array] mutableCopy];
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"ERROR: %#", error);
}];
I can see that the mapper gets the correct number of the Array elements, but for each field of the object, I cannot retrieve the values:
2012-12-10 19:02:53.370 GenPeople2[14240:1703] T restkit.object_mapping:RKMappingOperation.m:341 Mapping attribute value keyPath 'CommonName' to 'commonName'
2012-12-10 19:02:53.370 GenPeople2[14240:1703] T restkit.object_mapping:RKMappingOperation.m:228 Found transformable value at keyPath 'CommonName'. Transforming from type '__NSDictionaryM' to 'NSString'
2012-12-10 19:02:53.371 GenPeople2[14240:1703] T restkit.object_mapping:RKMappingOperation.m:360 Skipped mapping of attribute value from keyPath 'CommonName to keyPath 'commonName' -- value is unchanged ((null))
and the result in my objects are null values.
I saw that the XML parser gives me back this:
2012-12-10 19:02:53.371 GenPeople2[14240:1703] D restkit.object_mapping:RKMapperOperation.m:218 Asked to map source
object {
City = {
text = thecity;
};
CommonName = {
text = thename;
};
County = {
text = thecounty;
};
and so on....
How to map correctly the values in order to permit RestKit to retrieve the values in the NSDictionary for each field ?
Thank Richard for your feedback, but it didn't work as I would like.
Really simpler: using nested keypaths in source object to map, worked as a charm:
RKObjectMapping *abItemMapping = [RKObjectMapping mappingForClass:[AddressBookItem class]];
[abItemMapping addAttributeMappingsFromDictionary:#{#"CommonName.text" : #"commonName", #"OU.text" : #"ou", #"Name.text" : #"name", #"LastName.text" : #"lastName", #"Service.text" : #"service", #"Email.text" : #"email"}];
I map the child nodes of an element as their own objects. So OU for example would be represented by a mapping and relationship of it's own:
RKObjectMapping *baseValueMapping = [RKObjectMapping mappingForClass:[CHRValue class]];
[baseValueMapping addAttributeMappingsFromDictionary:#{#"text" : #"value"}];
RKRelationshipMapping *ouRelation = [RKRelationshipMapping relationshipMappingFromKeyPath:#"OU" toKeyPath:#"ou" withMapping:baseValueMapping];
RKRelationshipMapping *nameRelation = [RKRelationshipMapping relationshipMappingFromKeyPath:#"Name" toKeyPath:#"name" withMapping:baseValueMapping];
[addressBookMapping addPropertyMapping:ouRelation];
[addressBookMapping addPropertyMapping:nameRelation];
Where CHRValue has a property named "value" which is an NSString. Note you need to use "text" to refer to the value of a node.