I am having difficulty mapping a object in Restkit which is nested. The response is as follows:
{
"status": "SUCCESS",
"message": "Newsfeeds loaded successfully",
"links": {
"self": ""
},
"newsfeeds": [
{
"type": "post",
"content": {
"id": "39ff4ea6-71d4-4d9c-872b-94d878ec54fd",
"owner_id": "75c72102-d7dc-44c6-bb62-c48b487897c4",
"owner_firstname": "Goran",
"owner_lastname": "Don",
"owner_profilephoto": "88f5930b-e779-47ac-86b7-4f31cd0d82aa.jpg",
"contents": [
{
"type": "text",
"content": "Being the richest man in the cemetery doesn't matter to me. Going to bed at night saying we've done something wonderful, that's what matters to me.\n Sometimes when you innovate, you make mistakes. It is best to admit them quickly, and get on with improving your other innovations"
},
{
"type": "url",
"content": {
"title": "Beautiful landscape view Of New Zealand and Australia is available here",
"position": "landscape",
"url": "39ff4ea6-71d4-4d9c-872b-94d878ec54fd/Img_62151fbd-119f-4a84-91a9-f37bfa6293db.jpg"
}
}
],
"postdatetime": "May 18 2016 12:18:54.442 UTC",
"selfLike": false,
"likes": 0,
"comments": 0,
"starred": "false"
}
},
{
"type": "post",
"content": {
"id": "7117d132-1811-4ac7-bfaf-bbb397eefb10",
"owner_id": "75c72102-d7dc-44c6-bb62-c48b487897c4",
"owner_firstname": "Goran",
"owner_lastname": "Don",
"owner_profilephoto": "88f5930b-e779-47ac-86b7-4f31cd0d82aa.jpg",
"contents": [
{
"type": "text",
"content": "Hi this is a test"
}
],
"postdatetime": "May 18 2016 11:42:24.978 UTC",
"selfLike": false,
"likes": 0,
"comments": 0,
"starred": "false"
}
},
{
"type": "post",
"content": {
"id": "fbeb20cf-c87b-40db-9753-9fa32aac921a",
"owner_id": "75c72102-d7dc-44c6-bb62-c48b487897c4",
"owner_firstname": "Goran",
"owner_lastname": "Don",
"owner_profilephoto": "88f5930b-e779-47ac-86b7-4f31cd0d82aa.jpg",
"contents": [
{
"type": "url",
"content": {
"title": "",
"position": "potrait",
"url": "fbeb20cf-c87b-40db-9753-9fa32aac921a/Img_23771f1c-bb22-4335-ae3f-4e83d97c5c3c.jpg"
}
},
{
"type": "url",
"content": {
"title": "",
"position": "landscape",
"url": "fbeb20cf-c87b-40db-9753-9fa32aac921a/Img_a77e8349-b531-4d9d-944e-88971298c6fa.jpg"
}
}
],
"postdatetime": "May 18 2016 07:39:07.937 UTC",
"selfLike": true,
"likes": 1,
"comments": 0,
"starred": "false"
}
},
{
"type": "post",
"content": {
"id": "71e005a1-71ec-4131-8131-bfd38337ec6a",
"owner_id": "75c72102-d7dc-44c6-bb62-c48b487897c4",
"owner_firstname": "Goran",
"owner_lastname": "Don",
"owner_profilephoto": "88f5930b-e779-47ac-86b7-4f31cd0d82aa.jpg",
"contents": [
{
"type": "url",
"content": {
"title": "",
"position": "potrait",
"url": "post/71e005a1-71ec-4131-8131-bfd38337ec6a/Img_600f6fd0-14f9-4bf3-af6e-f36b7ffedbc6.jpg"
}
}
],
"postdatetime": "May 18 2016 07:27:53.278 UTC",
"selfLike": false,
"likes": 0,
"comments": 0,
"starred": "false"
}
}
]
}
From the above, need to reach "content" within "contents" array. "content" sometimes return string and sometimes dictionary. I am trying to map as follows:
RKObjectMapping * newsFeedMappingObject = [RKObjectMapping mappingForClass:[NewsFeed class]];
[newsFeedMappingObject addAttributeMappingsFromDictionary:@{@"type" : @"type",}];
RKObjectMapping * responseMappingObject = [RKObjectMapping mappingForClass:[ResponseMessage class]];
[responseMappingObject addAttributeMappingsFromDictionary:@{uStatus: @"status",uMessage: @"message",}];
[responseMappingObject addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"newsfeeds"
toKeyPath:@"newsfeeds"
withMapping:newsFeedMappingObject]];
RKObjectMapping * contentMappingObject = [RKObjectMapping mappingForClass:[Content class]];
[contentMappingObject addAttributeMappingsFromDictionary:@{@"id": @"contentId"}];
[newsFeedMappingObject addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"content"
toKeyPath:@"cont"
withMapping:contentMappingObject]];
RKObjectMapping * postContentMappingObject = [RKObjectMapping mappingForClass:[PostContent class]];
[postContentMappingObject addAttributeMappingsFromDictionary:@{@"type": @"type",}];
[contentMappingObject addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"contents"
toKeyPath:@"contents"
withMapping:postContentMappingObject]];
RKObjectMapping * postMappingObject = [RKObjectMapping mappingForClass:[Post class]];
[postMappingObject addAttributeMappingsFromDictionary:@{@"title":@"title"}];
[postContentMappingObject addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"content"
toKeyPath:@"post"
withMapping:postMappingObject]];
When I run it the app crashes with log as:** * Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0x7fa302826d30> valueForUndefinedKey:]: this class is not key value coding-compliant for the key title.'
Trying my hands on dynamic mapping. But I think I'm doing it wrong:
RKObjectMapping * newsFeedMappingObject = [RKObjectMapping mappingForClass:[NewsFeed class]];
[newsFeedMappingObject addAttributeMappingsFromDictionary:@{
@"type" : @"type",
}];
RKObjectMapping * responseMappingObject = [RKObjectMapping mappingForClass:[ResponseMessage class]];
[responseMappingObject addAttributeMappingsFromDictionary:@{
uStatus: @"status",
uMessage: @"message",
}];
[responseMappingObject addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"newsfeeds"
toKeyPath:@"newsfeeds"
withMapping:newsFeedMappingObject]];
RKObjectMapping * contentMappingObject = [RKObjectMapping mappingForClass:[Content class]];
[contentMappingObject addAttributeMappingsFromDictionary:@{
@"id": @"contentId",
}];
[newsFeedMappingObject addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"content"
toKeyPath:@"cont"
withMapping:contentMappingObject]];
RKObjectMapping * postContentMappingObject = [RKObjectMapping mappingForClass:[PostContent class]];
[postContentMappingObject addAttributeMappingsFromDictionary:@{
@"type": @"type",
}];
[contentMappingObject addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"contents"
toKeyPath:@"contents"
withMapping:postContentMappingObject]];
RKObjectMapping * postMappingObject = [RKObjectMapping mappingForClass:[Post class]];
[postMappingObject addAttributeMappingsFromDictionary:@{
@"title" : @"title"
}];
RKDynamicMapping* dynamicMapping = [RKDynamicMapping new];
[postMappingObject addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"post" toKeyPath:@"content" withMapping:dynamicMapping]];
// Connect a response descriptor for our dynamic mapping
RKResponseDescriptor *dynamicResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:dynamicMapping method:RKRequestMethodAny pathPattern:nil keyPath:@"content" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[[RKObjectManager sharedManager] addResponseDescriptor:dynamicResponseDescriptor];
// Option 2: Configure the dynamic mapping via a block
[dynamicMapping setObjectMappingForRepresentationBlock:^RKObjectMapping *(id representation) {
if ([[representation valueForKey:@"content"] isKindOfClass:[NSDictionary class]]) {
return postMappingObject;
}
return nil;
}];
[postContentMappingObject addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"content"
toKeyPath:@"post"
withMapping:postMappingObject]];
NSString *urlString = [NSString stringWithFormat:@"%@%@%@&userId=%@&startDate=%@&count=%d&scanForward=%@",uServiceUrl,uGetNewsFeedsRequest,accountId,userId,startDate,count,isForward];
NSString* encodedUrl = [urlString stringByAddingPercentEncodingWithAllowedCharacters:
[NSCharacterSet URLQueryAllowedCharacterSet]];
NSURL *getNewsRequestUrl = [NSURL URLWithString:encodedUrl];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMappingObject method:RKRequestMethodAny pathPattern:nil keyPath:@"" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[self getWithUrlString:getNewsRequestUrl withMappingObject:responseMappingObject andResponseDescriptors:@[responseDescriptor, dynamicResponseDescriptor] withSuccess:successBlock withFail:failBlock];