My JSON looks like this:
[ [value1, value2, value3], [value1, value2, value3]]
I want to iterate over the external array, and map each internal array to an object such as:
#interface MyObject : NSObject
#property (nonatomic, copy) NSString* key1;
#property (nonatomic, copy) NSString* key2;
#property (nonatomic, copy) NSString* key3;
#end
For the sample JSON, I should get two mapped objects, e.g. MyObject1, MyObject2, where MyObject1 is mapped to the first internal array, and MyObject2 is mapped to the second internal array. Each having their properties mapped to corresponding values in the array i.e. key1 == value1, key2==value2 and key3==value3.
Any ideas hot to do such a mapping?
The way I ended up handling it was to add an array property to my object, and map the whole array to that property (a transformable property incase of a NSManagedObject subclass)
RKEntityMapping *responseMapping = [RKEntityMapping mappingForEntityForName:#"MyObject" inManagedObjectStore:managedObjectStore];
[responseMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:nil toKeyPath:#"values"]];
After mapping is complete, I assign rest of the values in the completion block:
^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[mappingResult.array enumerateObjectsUsingBlock:^(MyObject *obj, NSUInteger idx, BOOL *stop) {
obj.key1 = obj.values[0];
obj.key2 = obj.values[1];
obj.key3 = obj.values[2];
}];
Related
How can I post an array of objects to my server with RESTKit?
I have a custom object called Contact which have some properties like name, phone etc. I would like to send an array of these Contact objects to the server.
The method I know for this is postObject:path:parameters:success:failure, but what object I put here? If I put Contact - how will it know it is an array? and if I put NSArray, how will it know it is a Contact?
My Contact object header file is:
#interface Contact : NSObject
#property (strong, nonatomic) NSString *name;
#property (strong, nonatomic) NSString *phone;
#property (nonatomic) NSInteger order;
#property (strong, nonatomic) NSString *firstName;
#property (strong, nonatomic) NSString *lastName;
#end
my response mapping is:
RKObjectMapping *personMapping = [RKObjectMapping mappingForClass:[Contact class]];
[personMapping addAttributeMappingsFromDictionary:#{
#"username": #"name",
#"firstname" : #"firstName",
#"lastname" : #"lastName",
}];
my response descriptor is:
RKResponseDescriptor *personResponseDescriptorForArrayOfPhones =
[RKResponseDescriptor responseDescriptorWithMapping:personMapping
method:RKRequestMethodANY
pathPattern:#"getUsersInfoByPhones"
keyPath:nil
statusCodes:[NSIndexSet indexSetWithIndex:200]];
my request mapping is:
RKObjectMapping *personRequestMapping = [RKObjectMapping requestMapping ];
[personRequestMapping addAttributeMappingsFromDictionary:#{
#"name": #"username",
#"firstName" : #"firstName",
#"lastName" : #"lastName",
#"phone" : #"usernames"
}];
my request descriptor is:
RKRequestDescriptor *personRequestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:personRequestMapping
objectClass:[Contact class]
rootKeyPath:nil
method:RKRequestMethodAny];
Does this implementation looks good?
Also, this array I want to send to the server could be very big, around 200-1000 objects. Is that possible with RESTKit?
Update: Actually, I would prefer to send an array of strings (which would be phone numbers), and get from the server the Contact objects I have. How can I set RESTKit to post the array of strings and to expect a response of an array of Contact objects?
The json I need to send looks like this:
{
"usernames":["11","22"]
}
the json I expect to get is:
[
{
"_id" : "53e23a54e811310000955f70",
"profileUpdatesCounter" : 3,
"lastname" : "SMITH",
"firstname" : "BOB",
"username" : "11"
}
]
This question already has an answer here:
Restkit request not sending parameters
(1 answer)
Closed 8 years ago.
I have the following two entities
#interface MEContactInfo : NSObject
#property (nonatomic,strong) NSString* phone ;
#property (nonatomic,strong) NSString* email;
#end
#interface MEContact : NSObject
#property (nonatomic,strong) NSString* _id ;
#property (nonatomic,strong) NSString* lastName;
#property (nonatomic,strong) NSString* firstName;
#property (nonatomic,strong) NSString* data ;
#property (nonatomic,strong) NSMutableArray* contactInfos ;
#end
The second entity contact contains the array of contact infos. Now I want to post this to my server but I am not able to do so. My mappings are as following:
RKObjectMapping* contactMapping = [RKObjectMapping mappingForClass:[MEContact class]];
[contactMapping addAttributeMappingsFromArray:#[#"_id",#"lastName",#"firstName",#"data"]];
RKObjectMapping* contactInfosMapping = [RKObjectMapping mappingForClass:[MEContactInfo class]];
[contactInfosMapping addAttributeMappingsFromArray:#[#"email",#"phone"]];
[contactMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"contactInfos" toKeyPath:#"contactInfos" withMapping:contactInfosMapping]];
My request descriptor is as following:
requestDescriptor = [RKRequestDescriptor
requestDescriptorWithMapping:[contactMapping inverseMapping]
objectClass: [MEContact class]
rootKeyPath:nil method:RKRequestMethodAny];
Now when I post something like this:
{ firstName:”abc”,
lastName:”xyz”,
contactInfos: [{
email:”test#test.com”,
phone:”9999999999”
}]
}
I receive
{
firstName:”abc”,
lastName:”xyz”,
contactInfos: [ ”test#test.com”,”9999999999”]
}
If I have multiple entries in the contactInfos array, they all are appended to the contactInfos array I receive on the server side. Basically the contactInfo object is flattening in an array. Can you please let me know how I can fix this.
I got it to work. Everything above was correct. The problem was that data was not going as JSON to the server. The solution was that I had to set request serialization MimeType which can be done by doing this
[objectManger setRequestSerializationMIMEType:RKMIMETypeJSON];
Thanks
I am receiving more data than needed: I only want to map first object of an array of objects.
Using RestKit 0.22, how to map the following Json:
{ "name": "foobar",
"tags": ["tag1", "tag2", "tag3"] }
With the following model:
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSString *firstTag;
To map name, I have this code:
RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:#"MyObjectModel" inManagedObjectStore:[RKManagedObjectStore defaultStore]];
[mapping addAttributeMappingsFromDictionary:#{#"name": #"name"}];
To map firstObject of tags to firstTag, I do not know how to proceed. Note: MyObjectModel is an NSManagedObject, so firstTag is #dynamic.
The tried and tested approach is to create a method on the managed object which takes the full array. That method extracts the first item and saves it to the actual NSString property. Then your mapping is as standard as all of the data types match.
I have been using RestKit for sometime but some APIs have changed in the latest version and I'm no longer able to parse simple JSON.
Here's the payload I have:
{
"result":true,
"items":[
{
"id":"1",
"receiver":"11011101"
},
{
"id":"2",
"receiver":"11011101"
}
]
}
How can I parse the contents of the "items" dictionary as instances of the object Conversation I have created?
Using the code below doesn't work (objects are never mapped):
RKObjectMapping* conversationMapping = [RKObjectMapping mappingForClass:[Conversation class]];
[conversationMapping mapKeyPath:#"id" toAttribute:#"id"];
[conversationMapping mapKeyPath:#"receiver" toAttribute:#"receiver"];
[[RKObjectManager sharedManager].mappingProvider setMapping:conversationMapping forKeyPath:#"items"];
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:#"/getConversations" delegate:self];
Conversation class
#interface Conversation : NSObject {
NSString *id;
NSString *receiver; }
+ (void)objectMapping;
#property (nonatomic, strong) NSString *id; #property (nonatomic, strong) NSString *receiver;
#end
#implementation Conversation
#synthesize id;
#synthesize receiver;
+ (void)objectMapping {
RKObjectMapping* conversationMapping = [RKObjectMapping mappingForClass:[Conversation class]];
[conversationMapping mapKeyPath:#"id" toAttribute:#"id"];
[conversationMapping mapKeyPath:#"receiver" toAttribute:#"receiver"];
[[RKObjectManager sharedManager].mappingProvider setMapping:conversationMapping forKeyPath:#"items"];
}
#end
How is your root object defined (the one that holds "result" and your Conversation "items")? That should look something like this:
#interface MyResponse
#property (nonatomic, strong) NSArray* items;
#property (nonatomic, assign) BOOL result;
with the appropriate mapping for that as well.
I solved the problem. It was something totally not related to RestKit. The content type of the response coming back from the server was not set to JSON, after fixing that object mapping worked fine.
please help so here is the problem i got a rails app that sends a json image data base64. The json sends but when i try to access the data value in ios app it comes back as null. Here is my rails code,code
{
"profile_pic": "<%= Base64.encode64(File.read('/Users/rui_y/connect_Me2/public'+
#user.avatar_photo_url(:thumb)).gsub("\n", '')) %>",
}
the json comes back as
[{"profile_pic": "/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcH......
....... many more lines etc etc...................................................
+p/Ob9Xrf6D8po/hOhI4U5SSm4Es8vUE/riYmJj2B0iefbkz/2Q==" }]
the Restkit is mapped like this
[userMapping mapKeyPath:#"profile_pic" toAttribute:#"profilePic"];
NSLog(#"people id %#",[[objects objectAtIndex:0]profilePic ]);
//and it comes back as null
2012-02-09 20:08:48.073 ConnecTest[78232:207] profile_pic (null)
all the other values when i nslog is accessable so im wondering how to map this data.
You can map this as you do for all strings.
I take this in my code, but I map a list of key/value object :
Mapping :
listMapping = [RKObjectMapping mappingForClass:[VOKeyValue class]];
[listMapping mapKeyPath:#"value" toAttribute:#"value"];
[listMapping mapKeyPath:#"key" toAttribute:#"key"];
[[RKObjectManager sharedManager].mappingProvider setMapping:listMapping forKeyPath:#"list"];
Value Object :
#interface VOKeyValue : NSObject
{
NSString * key;
NSString * value;
}
#property (nonatomic, retain) NSString * key;
#property (nonatomic, retain) NSString * value;
#end
Request :
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:#"yourResourceURL..." delegate:self];
In my CallBack function :
VOKeyValue*img=[objects objectAtIndex:0];
if (![img.key isEqualToString:#"image"]) {
img=[objects objectAtIndex:1];
}
Finally I can map this Json :
{"list":[{"key":"image","value":"/9j/4AATSkZJRgABAgIAAAAAAAAAAAD/wAARCADwAUADASEAAhEBAxEB/....YFJCPAP/ZAAA="},{"key":"other","value":"xxxx..."}]}
I hope my exemple can help you.