Mapping array in restkit v.20 - ios

I Read From Google Places API
{
"html_attributions" : [
"Listings by \u003ca href=\"http://www.yellowpages.com.au/\"\u003eYellow Pages\u003c/a\u003e"
],
"results" : [
{
"geometry" : {
"location" : {
"lat" : -33.870540,
"lng" : 151.1988150
}
},
"icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/cafe-71.png",
"id" : "c71365287e7606bd21a3311d21fda087830b7813",
"name" : "Pancakes on the Rocks",
"opening_hours" : {
"open_now" : true
},
"photos" : [
{
"height" : 1224,
"html_attributions" : [
"\u003ca href=\"https://plus.google.com/105663944571530352563\"\u003eJoshua Gilmore\u003c/a\u003e"
],
"photo_reference" : "CnRoAAAADF1JoE-joT2BSN4NEYn2luUF2kdIRjflFvETx0SbCnPyRp0TZz8_x7OlHCpAz2rrNXtQZyp5wd-JEjZh2FSpkM2bDGs_DqmktsClrnYkkirkCOHlnBHxedJf_Etv0DV8y9vnIbFnLJ9995Fk2u98SBIQxjojXwmV45p-9b4SurLQhxoUtErGJpwFe-k0hfgVGapK1FYjnWw",
"width" : 1632
}
],
"price_level" : 2,
"rating" : 3.90,
"reference" : "CoQBcgAAAFakUaktwUsNCr--KIaYu_hS9cbO8uMAwNE2W7xSMEZimIjc6EhMStq2LpVteXf6jy4UqeHGJh0QhDSpKMGK065jlnha2F6bG1zoLDRHtYTqV3PIOMMa8KsjJgmLUU-7GDojLvb6MHVctzMbMeTGtAOq_mm5lS_oymzDtJJsehSkEhCZ-KMMyl3qmYNHkCJ919FRGhSlbP1fVPQ_mLamjx9ELIBulb4ACg",
"types" : [ "cafe", "restaurant", "food", "establishment" ],
"vicinity" : "Harbourside Shopping Centre,Darling Harbour/227 & 229-230 Darling Drive, Sydney"
},
And i have Classes As Flow
Place Class:
#interface Place : NSObject
#property (nonatomic,strong) Geometry * geometry;
#property (nonatomic,strong) NSString * icon;
#property (nonatomic,strong) NSString * placeID;
#property (nonatomic,strong) NSString * name;
#property (nonatomic,strong) OpeningHours * opening_hours;
#property (nonatomic,strong) NSString * price_level;
#property (nonatomic,strong) NSString * rating;
#property (nonatomic,strong) NSString * vicinity;
#property (nonatomic,strong) NSSet *photos;
#property (nonatomic,strong) NSString *reference;
#end
And Photos Class:
#interface Photos : NSObject
#property (nonatomic,strong) NSNumber *height;
#property (nonatomic,strong) NSString *html_attributions;
#property (nonatomic,strong) NSString *photo_reference;
#property (nonatomic,strong) NSNumber *width;
#end
and i map With Follwoing:
RKObjectMapping *placeMapping = [RKObjectMapping mappingForClass:[Place class]];
[placeMapping addAttributeMappingsFromDictionary:#{
#"icon" : #"icon",
#"id" : #"placeID",
#"name" : #"name",
#"reference" : #"reference",
#"price_level" : #"price_level",
#"rating" : #"rating",
#"vicinity" : #"vicinity",
}];
// Create our new Author mapping
RKObjectMapping* geomtryMapping = [RKObjectMapping mappingForClass:[Geometry class]];
RKObjectMapping* locationMapping = [RKObjectMapping mappingForClass:[Location class]];
[locationMapping addAttributeMappingsFromArray:#[ #"lat", #"lng" ]];
[geomtryMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"location"
toKeyPath:#"location"
withMapping:locationMapping]];
[placeMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"geometry"
toKeyPath:#"geometry"
withMapping:geomtryMapping]];
RKObjectMapping* openingHoursMapping = [RKObjectMapping mappingForClass:[OpeningHours class]];
[openingHoursMapping addAttributeMappingsFromArray:#[#"open_now"]];
[placeMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"opening_hours" toKeyPath:#"opening_hours" withMapping:openingHoursMapping]];
RKObjectMapping* photosMapping = [RKObjectMapping mappingForClass:[Photos class]];
[photosMapping addAttributeMappingsFromArray:#[#"height",#"photo_reference",#"html_attributions",#"width"]];
[photosMapping setForceCollectionMapping:YES];
[placeMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"photos"
toKeyPath:#"photos"
withMapping:photosMapping]];
RKResponseDescriptor * responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:placeMapping
pathPattern:nil
keyPath:#""
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:responseDescriptor];
first Question
I Photos Alawys have value Nil.
Second Question How I get "html_attributions" in the beginning of json.

keyPaths is the bit you're missing. When you say Photos is always nil, I guess you don't really get any meaningful data? To get the places you need to specify the keyPath of #"results" on your responseDescriptor.
In a similar way, you can get the html_attributions by using it as the keyPath on another set of mappings and response descriptor.

Related

Unable to map nested array json with restkit

How can i map this json
{
"json": [{
"json_department": [{
"department": {
"id": 1,
"inst_id": 1,
"dept_name": "Department",
"description": "test"
},
"needDelete": true
}],
"json_subjects": [{
"subjects": [{
"id": 1,
"department_id": 1,
"subject_name": "Sub 1"
}, {
"id": 2,
"department_id": 1,
"subject_name": "Sub 2"
}],
"needDelete": true
}]
}]
}
#interface class_department : NSObject
#property(nonatomic, assign) NSInteger dept_id;
#property(nonatomic, assign) NSInteger inst_id;
#property(nonatomic, strong) NSString *dept_name;
#property(nonatomic, strong) NSString *description_;
#end
_
#interface class_department_list : NSObject
#property(nonatomic, strong) class_department *department;
#property(nonatomic, assign) BOOL needDelete;
#end
-
#interface sync_json : NSObject
#property(nonatomic, strong) NSMutableArray *json_department;
#property(nonatomic, strong) NSMutableArray *json_subjects;
#end
-
-(RKResponseDescriptor *)getResponseDescriptor
{
RKObjectMapping *class_department_mapping = [RKObjectMapping mappingForClass:[class_department class]];
[class_department_mapping addAttributeMappingsFromDictionary:#{
#"id":#"dept_id",
#"inst_id":#"inst_id",
#"dept_name":#"dept_name"
#"description":#"description_",
}];
RKObjectMapping *class_department_list_mapping = [RKObjectMapping mappingForClass:[class_department_list class]];
[class_department_list_mapping addAttributeMappingsFromDictionary:#{
#"needDelete":#"needDelete"
}];
[class_department_list_mapping addPropertyMapping:[RKRelationshipMapping
relationshipMappingFromKeyPath:#"json_department.department"
toKeyPath:#"department"
withMapping:class_department_mapping]];
RKObjectMapping *json_mapping = [RKObjectMapping mappingForClass:[sync_json class]];
[json_mapping addPropertyMapping:[RKRelationshipMapping
relationshipMappingFromKeyPath:#"json_department"
toKeyPath:#"json_department"
withMapping:class_department_list_mapping]];
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:json_mapping
method:RKRequestMethodGET
pathPattern:nil
keyPath:#"json"
statusCodes:statusCodes];
return responseDescriptor;
}
OKay this is code i'm using for mapping the json. i got the result for 'needDelete' but mapping to class_department is not happen. Please give me a way to done this.
Thank you.
Shinurag KR
Sorry, but try to forget this ugly implementation. Mantle do everythig pretty easy for you. Project: https://github.com/Mantle/Mantle Example: http://www.objc.at/mantle

Mapping nested object with RESTKIT

I'm trying to map a object through the following JSON:
{
"main_email": {"id": 1, "address": "mainemail#email.com"},
"id": 1,
"first_name": "first name",
"last_name": "last name",
}
I have a object called User with the properties:
#property (nonatomic, assign) NSInteger userID;
#property (nonatomic, copy) NSString *firstName;
#property (nonatomic, copy) NSString *lastName;
#property (nonatomic, strong) Email *mainEmail;
And the object Email have the properties:
#property (nonatomic, assign) NSInteger emailID;
#property (nonatomic, copy) NSString *emailAddress;
Now i'm mapping in the User like bellow:
RKObjectMapping *userMapping = [RKObjectMapping mappingForClass:[User class]];
[userMapping addAttributeMappingsFromDictionary:#{#"id": #"userID",
#"first_name": #"firstName",
#"last_name": #"lastName"}];
RKObjectMapping *emailMapping = [RKObjectMapping mappingForClass:[Email class]];
[emailMapping addAttributeMappingsFromDictionary:#{#"main_email.id": #"emailID",
#"main_email.address": #"emailAddress"}];
[userMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"mainEmail"
toKeyPath:#"mainEmail"
withMapping:emailMapping]];
This code keeps returning a empty Email object in User.mainEmail
First off your property mapping should be fromKeyPath:#"main_email" toKeyPath:#"mainEmail" the fromKeyPath is the key path in the JSON and the toKeyPath is the attribute/relationship in CoreData.
Second in your email mapping you don't need to prefix each key path with "main_email." when RestKit does nested mapping it will handle this for you (assuming your property mapping is set up properly)
Here is your example with those changes:
RKObjectMapping *userMapping = [RKObjectMapping mappingForClass:[User class];
[userMapping addAttributeMappingsFromDictionary:#{#"id": #"userID",
#"first_name": #"firstName",
#"last_name": #"lastName"}];
RKObjectMapping *emailMapping = [RKObjectMapping mappingForClass:[Email class]];
[emailMapping addAttributeMappingsFromDictionary:#{#"id": #"emailID",
#"address": #"emailAddress"}];
[userMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"main_email"
toKeyPath:#"mainEmail"
withMapping:emailMapping]];

RestKit POST-Mapping issue

I've got a problem with a POST-Mappping in RestKit. Basically my application needs to send a JSON-file to a server which expects the JSON to look exactly like the following example:
{
"ddata": {
"mLoad": {
"value": 13,
"unit": "%"
},
"cLoad": {
"value": 25,
"unit": "%"
}
},
"dm": "0815",
"vin": "VAPP",
"ts": "2014-09-24"
}
Unfortunately I'm not able to create a Mapping with RestKit which generates me a JSON that matches this format. Here's how the JSON looks at the moment:
{
"ddata" : [
{
"mLoad" : {
"unit" : "%",
"value" : "25"
}
},
{
"cLoad" : {
"unit" : "%",
"value" : "37"
}
}
],
"ts" : "2014-09-24",
"vin" : "VAPP",
"dm" : "0815"
}
As you can see in the result the ddata stuff is written as an array. Furthermore the outer { } of each "object" is too much.
Following my classes and the Mapping:
Mapping Class
#interface TopMapping : NSObject
#property NSString *dm;
#property NSString *vin;
#property NSString *ts;
#property NSSet *ddata;
#end
SubMapping Class
#interface SubMapping : NSObject
#property NSString *object;
#property NSString *value;
#property NSString *unit;
#end
Actual mapping
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[TopMapping class]];
[mapping addAttributeMappingsFromDictionary:#{
#"dm": #"dm",
#"vin": #"vin",
#"ts": #"ts"
}];
RKObjectMapping *subMapping = [RKObjectMapping mappingForClass:[SubMapping class]];
[subMapping setForceCollectionMapping:YES];
[subMapping addAttributeMappingFromKeyOfRepresentationToAttribute:#"object"];
[subMapping addAttributeMappingsFromDictionary:#{
#"(object).value" : #"value",
#"(object).unit" : #"unit"
}];
[mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"ddata" toKeyPath:#"ddata" withMapping:subMapping]];
Can anyone tell me what I need to change in order to get the desired result? Thanks in advance. (I've been struggling with this issue for days)
Check NSSet manual
You need to use NSDictionary instead of NSSet.

RESTKit - post a large array of objects to server

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"
}
]

RestKit mapping object without object class

I have this issue, that i'm mapping all object properly, but the properties that are inside the root object, for some reason I cannot map.
This is the JSON:
{
"responseError": null,
"responseIsRegisteredServices": {
"registeredToServiceAntiVirus": true,
"registeredToServiceCloud": true,
"registeredToServiceMusic": true,
"registeredToServiceSong": true,
"registeredToServiceTv": true
},
"responseRegisteredServicesCloud": null,
"responseRegisteredServicesMusic": [
{
"ID": null,
"Name": null,
"AlbumPic": "110_110.png",
"ArtistName": "Rihanna"
},
{
"ID": null,
"Name": null,
"AlbumPic": "110_110.png",
"ArtistName": "Rihanna"
},
{
"ID": null,
"Name": null,
"AlbumPic": "110_110.png",
"ArtistName": "Steve Angello"
}
]
}
This is the RegisteredServices class:
#interface RegisteredServices : NSObject
#property (nonatomic) ResponseError *responseError;
#property (nonatomic) NSNumber *registeredToServiceAntiVirus;
#property (nonatomic) NSNumber *registeredToServiceCloud;
#property (nonatomic) NSNumber *registeredToServiceMusic;
#property (nonatomic) NSNumber *registeredToServiceSong;
#property (nonatomic) NSNumber *registeredToServiceTv;
#property (nonatomic) CloudServices *responseRegisteredServicesCloud;
#property (nonatomic) NSArray *responseRegisteredServicesMusix;
#end
This is the 'CloudServices' class:
#interface CloudServices : NSObject
#property (nonatomic) NSString *capacityType;
#property (nonatomic) NSNumber *currentCapacity;
#property (nonatomic) NSString *lastBackupDate;
#property (nonatomic) NSNumber *percentage;
#property (nonatomic) NSNumber *totalCapacity;
#end
This is the 'MusicServices' class:
#interface MusicServices : NSObject
#property (nonatomic) NSNumber *idNum;
#property (nonatomic) NSString *name;
#property (nonatomic) NSString *albumPic;
#property (nonatomic) NSString *artistName;
#end
This is the mapping itself:
RKObjectMapping *musixMapping = [RKObjectMapping mappingForClass:[MusicServices class]];
[musicMapping addAttributeMappingsFromDictionary:#{ #"ID" : #"idNum",
#"Name" : #"name",
#"AlbumPic" : #"albumPic",
#"ArtistName" : #"artistName" }];
RKObjectMapping *cloudMapping = [RKObjectMapping mappingForClass:[CloudServices class]];
[cloudMapping addAttributeMappingsFromDictionary:#{#"capacityType": #"capacityType",
#"currentCapacity": #"currentCapacity",
#"lastBackupDate": #"lastBackupDate",
#"percentage": #"percentage",
#"totalCapacity": #"totalCapacity" }];
RKObjectMapping *registeredServicesMapping = [RKObjectMapping mappingForClass:[RegisteredServices class]];
[registeredServicesMapping addAttributeMappingsFromDictionary:#{ #"registeredToServiceAntiVirus" : #"registeredToServiceAntiVirus",
#"registeredToServiceCloud" : #"registeredToServiceCloud",
#"registeredToServiceMusic" : #"registeredToServiceMusic",
#"registeredToServiceSong" : #"registeredToServiceSong",
#"registeredToServiceTv" : #"registeredToServiceTv", }];
[registeredServicesMapping addRelationshipMappingWithSourceKeyPath:#"responseRegisteredServicesMusic" mapping:musixMapping];
[registeredServicesMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"responseError"
toKeyPath:#"responseError"
withMapping:errorMapping]];
[registeredServicesMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"responseRegisteredServicesCloud"
toKeyPath:#"responseRegisteredServicesCloud"
withMapping:cloudMapping]];
[[RKObjectManager sharedManager] addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:registeredServicesMapping
method:RKRequestMethodGET
pathPattern:#"registeredServices"
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]];
Can't figure out what seems to be the problem. When I add responseIsRegisteredServices into the keyPath: of the RKResponseDescriptor than the MusicServices array is null.
Thanks in advance.
So i've found the answer, in this line:
[registeredServicesMapping addAttributeMappingsFromDictionary:#{ #"registeredToServiceAntiVirus" : #"registeredToServiceAntiVirus",
#"registeredToServiceCloud" : #"registeredToServiceCloud",
#"registeredToServiceMusic" : #"registeredToServiceMusic",
#"registeredToServiceSong" : #"registeredToServiceSong",
#"registeredToServiceTv" : #"registeredToServiceTv", }];
I needed to change it from registeredToServiceAntiVirus to responseIsRegisteredServices .registeredToServiceAntiVirus and than it worked perfectly. This is how it looks:
[registeredServicesMapping addAttributeMappingsFromDictionary:#{ #"responseIsRegisteredServices.registeredToServiceAntiVirus" : #"registeredToServiceAntiVirus",
#"responseIsRegisteredServices.registeredToServiceCloud" : #"registeredToServiceCloud",
#"responseIsRegisteredServices.registeredToServiceMusic" : #"registeredToServiceMusic",
#"responseIsRegisteredServices.registeredToServiceSong" : #"registeredToServiceSong",
#"responseIsRegisteredServices.registeredToServiceTv" : #"registeredToServiceTv", }];
Enjoy.

Resources