Unable to map nested array json with restkit - ios

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

Related

RestKit using RKConnectionDescription to sideload data [duplicate]

I'm totally new to RestKit and am struggling somewhat.
JSON:
{
"teams": [
{
"id": 1,
"name": "Team A"
},
{
"id": 2,
"name": "Team B"
}
],
"users": [
{
"id": 1,
"name": "cameron",
"teamId": 1
},
{
"id": 2,
"name": "paul",
"teamId": 2
}
]
}
CoreData:
#interface Team : NSManagedObject
#property (nonatomic, retain) NSNumber * teamId;
#property (nonatomic, retain) NSString * name;
#end
#interface User : NSManagedObject
#property (nonatomic, retain) NSNumber * userId;
#property (nonatomic, retain) NSString * name;
#property (nonatomic, retain) Team * team;
#end
My application logic looks like this:
// team mapping
RKEntityMapping *teamMapping = [RKEntityMapping mappingForEntityForName:#"Team" inManagedObjectStore:[RKManagedObjectStore defaultStore]];
teamMapping.identificationAttributes = #[#"teamId"];
[teamMapping addAttributeMappingsFromDictionary:#{
#"id": #"teamId",
#"name": #"name"
}];
// Register our mappings with the provider
RKResponseDescriptor *teamResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:teamMapping
pathPattern:nil
keyPath:#"teams"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[self.objectManager addResponseDescriptor:teamResponseDescriptor];
// user mapping
RKEntityMapping *userMapping = [RKEntityMapping mappingForEntityForName:#"User" inManagedObjectStore:[RKManagedObjectStore defaultStore]];
userMapping.identificationAttributes = #[#"userId"];
[userMapping addAttributeMappingsFromDictionary:#{
#"id": #"userId",
#"name": #"name"
}];
// Register our mappings with the provider
RKResponseDescriptor *userResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:userMapping
pathPattern:nil
keyPath:#"users"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[self.objectManager addResponseDescriptor:userResponseDescriptor];
I can't for the life of me work out how to get RestKit to populate the team Property of the user objects.
I've look at so many posts but nothing I try works, is this not a usual use case?
Does anyone know how to do this, help would be very appreciated!
Thanks.
You need to add a transient attribute to your User entity which holds the associated teamId. This needs to be added to your userMapping.
Then, you need to add a relationship definition to your userMapping:
[userMapping addConnectionForRelationship:#"team" connectedBy:#{ #"teamId": #"teamId" }];
This gives RestKit the information it needs to make the connection and instructs it to make the connection as part of the mapping operation.

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.

restkit propertyname not showing

I'm having problems when posting to my server. Every value is being parsed expect the property-names of my array aren't.
My server is expecting something like this:
{
"location": 2,
"_id": "517808546b496658c10209",
"products": [
{
"amount": 3,
"total": 6.6,
"name": "Coke",
"price": 2.2
},{
"amount": 1,
"total": 4.0,
"name": "Water",
"price": 2
}
]
}
but my client is sending this:
{
"location": 2,
"_id": "517808546b496658c10209",
"products": [
3,
6.6,
"Coke",
2.2,
1,
4.0,
"Water",
2
]
}
Product:
#property (nonatomic) NSNumber *_id;
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSString *detail;
#property (nonatomic, assign) float price;
#property (nonatomic, strong) Category *category;
#property (nonatomic, assign) int amount;
#property (nonatomic, assign) float total;
my code:
RKObjectMapping *productMapping = [RKObjectMapping requestMapping];
[productMapping addAttributeMappingsFromDictionary:#{#"productId":#"_id",#"amount":#":amount",#"total":#"total",#"price":#"price",#"name":#"name"}];
RKObjectMapping *horecaMapping = [RKObjectMapping requestMapping];
[horecaMapping addAttributeMappingsFromDictionary:#{ #"Id": #"_Id",#"deliverySpotId":#"location"}];
[horecaMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:#"self.getBasketSet" toKeyPath:#"products" withMapping:productMapping]];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:horecaMapping objectClass:[Horeca class] rootKeyPath:nil];
[RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:#"text/plain"];
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:baseURL];
[manager addRequestDescriptor:requestDescriptor];
[manager postObject:sharedHoreca path:#"/orders" parameters:nil success:nil failure:nil];
--update 1--
I also tried to make an NSSET of my array but this still doesn't help me.
(nsarray to nsset restkit)
The self.getBasketSet key path is giving me pause -- what is that returning? If your sharedHoreca object returns an NSArray of objects responding to the key paths specified then it should do what you are expecting...

Foreign key relationship mapping with RestKit

I'm totally new to RestKit and am struggling somewhat.
JSON:
{
"teams": [
{
"id": 1,
"name": "Team A"
},
{
"id": 2,
"name": "Team B"
}
],
"users": [
{
"id": 1,
"name": "cameron",
"teamId": 1
},
{
"id": 2,
"name": "paul",
"teamId": 2
}
]
}
CoreData:
#interface Team : NSManagedObject
#property (nonatomic, retain) NSNumber * teamId;
#property (nonatomic, retain) NSString * name;
#end
#interface User : NSManagedObject
#property (nonatomic, retain) NSNumber * userId;
#property (nonatomic, retain) NSString * name;
#property (nonatomic, retain) Team * team;
#end
My application logic looks like this:
// team mapping
RKEntityMapping *teamMapping = [RKEntityMapping mappingForEntityForName:#"Team" inManagedObjectStore:[RKManagedObjectStore defaultStore]];
teamMapping.identificationAttributes = #[#"teamId"];
[teamMapping addAttributeMappingsFromDictionary:#{
#"id": #"teamId",
#"name": #"name"
}];
// Register our mappings with the provider
RKResponseDescriptor *teamResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:teamMapping
pathPattern:nil
keyPath:#"teams"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[self.objectManager addResponseDescriptor:teamResponseDescriptor];
// user mapping
RKEntityMapping *userMapping = [RKEntityMapping mappingForEntityForName:#"User" inManagedObjectStore:[RKManagedObjectStore defaultStore]];
userMapping.identificationAttributes = #[#"userId"];
[userMapping addAttributeMappingsFromDictionary:#{
#"id": #"userId",
#"name": #"name"
}];
// Register our mappings with the provider
RKResponseDescriptor *userResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:userMapping
pathPattern:nil
keyPath:#"users"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[self.objectManager addResponseDescriptor:userResponseDescriptor];
I can't for the life of me work out how to get RestKit to populate the team Property of the user objects.
I've look at so many posts but nothing I try works, is this not a usual use case?
Does anyone know how to do this, help would be very appreciated!
Thanks.
You need to add a transient attribute to your User entity which holds the associated teamId. This needs to be added to your userMapping.
Then, you need to add a relationship definition to your userMapping:
[userMapping addConnectionForRelationship:#"team" connectedBy:#{ #"teamId": #"teamId" }];
This gives RestKit the information it needs to make the connection and instructs it to make the connection as part of the mapping operation.

Mapping array in restkit v.20

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.

Resources