I'm trying to parse data received from a service using the framework Mantle. The json has nested data and I am having problems to parse it. The json is like the following:
{
"sections": [
{
"title": "title1",
"level": 1,
"content": [
{
"type": "type1",
"text": "text1"
}
],
"images": []
},
{
"title": "title2",
"level": 2,
"content": [
{
"type": "type2",
"text": "text2"
},
{
"type": "type9",
"text": "text9"
},
{
"type": "type4",
"text": "text4"
},
{
"type": "type6",
"text": "text6"
}
],
"images": [
{
"src": "http://cvbcvcv",
"caption": "caption"
}
]
}]
}
The class that I am using is:
// MainObject.h
#interface MainObject : MTLModel <MTLJSONSerializing>
#property (strong, nonatomic) NSArray *sectionsArray;
+ (NSValueTransformer *)sectionsArrayJSONTransformer;
#end
#interface Section : MTLModel <MTLJSONSerializing>
#property (strong, nonatomic) NSString *title;
#property (assign, nonatomic) NSString *level;
#property (strong, nonatomic) NSArray *content;
#property (strong, nonatomic) NSArray *images;
+ (NSValueTransformer *)contentJSONTransformer;
+ (NSValueTransformer *)imagesJSONTransformer;
#end
#interface Content : MTLModel <MTLJSONSerializing>
#property (strong, nonatomic) NSString *type;
#property (strong, nonatomic) NSString *text;
#end
#interface Image : MTLModel <MTLJSONSerializing>
#property (strong, nonatomic) NSString *src;
#property (strong, nonatomic) NSString *caption;
#end
and
//MainObject.m
#implementation MainObject
+ (NSDictionary *)JSONKeyPathsByPropertyKey
{
return #{
#"sectionsArray" : #"sections",};
}
+ (NSValueTransformer *)sectionsArrayJSONTransformer
{
return [MTLJSONAdapter dictionaryTransformerWithModelClass:[Section class]];
}
#end
#implementation Section
+ (NSDictionary *)JSONKeyPathsByPropertyKey
{
return #{
#"title" : #"title",
#"level" : #"level",
#"content" : #"content",
#"images" : #"images",};
}
+ (NSValueTransformer *)contentJSONTransformer
{
return [MTLJSONAdapter arrayTransformerWithModelClass:[Content class]];
}
+ (NSValueTransformer *)imagesJSONTransformer
{
return [MTLJSONAdapter arrayTransformerWithModelClass:[Image class]];
}
#end
#implementation Content
+ (NSDictionary *)JSONKeyPathsByPropertyKey
{
return #{
#"type" : #"type",
#"text" : #"text",};
}
#end
#implementation Image
+ (NSDictionary *)JSONKeyPathsByPropertyKey
{
return #{
#"src" : #"src",
#"caption" : #"caption",};
}
#end
Then, when I make the call to the service and try to parse the json with the following code, being responseObject the data obtained from server, the data appears nil:
for (NSArray *array in [responseObject valueForKey:#"sections"]) {
NSArray *seccionArray = [MTLJSONAdapter modelsOfClass:[Section class] fromJSONArray:array error:nil];
}
I have tried a lot of ways to parse this data well, but the app always crashes or returns nil. I hope you can help me to solve this
Why can't just one line using NSJSONSerialization?
NSMutableDictionary *yourArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
Then you fetch what you want from your array...
Lets say I have this Model.
#protocol ProductModel
#end
#interface ProductModel : JSONModel
#property (assign, nonatomic) int id;
#property (strong, nonatomic) NSString* name;
#property (assign, nonatomic) float price;
#end
#implementation ProductModel
#end
#interface OrderModel : JSONModel
#property (assign, nonatomic) int order_id;
#property (assign, nonatomic) float total_price;
#property (strong, nonatomic) NSArray<ProductModel>* products;
#end
#implementation OrderModel
#end
Questions:
How I can add products in this array?
Then how I can produce the following JSON.
"products" : [
{
"id": "123",
"name": "Product #1",
"price": 12.95
},
{
"id": "137",
"name": "Product #2",
"price": 82.95
}
]
or the whole object.
{
"order_id": 104,
"total_price": 103.45,
"products" : [
{
"id": "123",
"name": "Product #1",
"price": 12.95
},
{
"id": "137",
"name": "Product #2",
"price": 82.95
}
]
}
I think BWJSONMatcher can help you out in a extremely neat way:
ProductModel *productModel1 = [[ProductModel alloc] init];
productModel1.id = 123;
productModel1.name = #"Product #1";
productModel1.price = 12.95;
ProductModel *productModel2 = [[ProductModel alloc] init];
productModel2.id = 137;
productModel2.name = #"Product #2";
productModel2.price = 82.95;
OrderModel *orderModel = [[OrderModel alloc] init];
orderModel.order_id = 104;
orderModel.total_price = 103.45;
orderModel.products = #[productModel1, productModel2];
NSString *producedJSON = [orderModel toJSONString];
I'm working with JSONModel to parse Instagram info from JSON to a model in my iOS app. I have tried many ways to achieve it but I can't. Three main parts of the response are data, meta and pagination. I have created the model and the model is always NULL. I'm going to attach the response I'm trying to parse, my models and how I'm processing the response. I think it could be a problem with the structure but I don't know what I'm doing wrong. Thanks for your help.
Response from Instagram
{
"data": [
{
"attribution": null,
"caption": {
"created_time": "1387987595",
"from": {
"full_name": "Camilo Sacanamboy",
"id": "268167404",
"profile_picture": "http://images.ak.instagram.com/profiles/profile_268167404_75sq_1386784112.jpg",
"username": "csacanam"
},
"id": "618807262892627401",
"text": "Navidad :)"
},
"comments": {
"count": 2,
"data": [
{
"created_time": "1387987956",
"from": {
"full_name": "Luisa Bellydancer",
"id": "548519361",
"profile_picture": "http://images.ak.instagram.com/profiles/profile_548519361_75sq_1398196543.jpg",
"username": "luisacantillo"
},
"id": "618810289837938356",
"text": "Te amo beb\u00e9"
},
{
"created_time": "1403666639",
"from": {
"full_name": "Camilo Sacanamboy",
"id": "268167404",
"profile_picture": "http://images.ak.instagram.com/profiles/profile_268167404_75sq_1386784112.jpg",
"username": "csacanam"
},
"id": "750332614214522476",
"text": "#sacanamboy"
}
]
},
"created_time": "1387987595",
"filter": "Walden",
"id": "618807262548694878_268167404",
"images": {
"low_resolution": {
"height": 306,
"url": "http://scontent-b.cdninstagram.com/hphotos-xpf1/t51.2885-15/1515365_559830227444878_1414305160_a.jpg",
"width": 306
},
"standard_resolution": {
"height": 640,
"url": "http://scontent-b.cdninstagram.com/hphotos-xpf1/t51.2885-15/1515365_559830227444878_1414305160_n.jpg",
"width": 640
},
"thumbnail": {
"height": 150,
"url": "http://scontent-b.cdninstagram.com/hphotos-xpf1/t51.2885-15/1515365_559830227444878_1414305160_s.jpg",
"width": 150
}
},
"likes": {
"count": 2,
"data": [
{
"full_name": "Luisa Bellydancer",
"id": "548519361",
"profile_picture": "http://images.ak.instagram.com/profiles/profile_548519361_75sq_1398196543.jpg",
"username": "luisacantillo"
},
{
"full_name": "Steven Zambrano",
"id": "198842014",
"profile_picture": "http://photos-d.ak.instagram.com/hphotos-ak-xpa1/10354559_1419915091614315_879045002_a.jpg",
"username": "steven_zambrano"
}
]
},
"link": "http://instagram.com/p/iWce08pZde/",
"location": null,
"tags": [
"sacanamboy"
],
"type": "image",
"user": {
"bio": "",
"full_name": "Camilo Sacanamboy",
"id": "268167404",
"profile_picture": "http://images.ak.instagram.com/profiles/profile_268167404_75sq_1386784112.jpg",
"username": "csacanam",
"website": ""
},
"users_in_photo": [
{
"position": {
"x": 0.39722222,
"y": 0.15416667
},
"user": {
"full_name": "Luisa Bellydancer",
"id": "548519361",
"profile_picture": "http://images.ak.instagram.com/profiles/profile_548519361_75sq_1398196543.jpg",
"username": "luisacantillo"
}
},
{
"position": {
"x": 0.55138886,
"y": 0.09583333
},
"user": {
"full_name": "Camilo Sacanamboy",
"id": "268167404",
"profile_picture": "http://images.ak.instagram.com/profiles/profile_268167404_75sq_1386784112.jpg",
"username": "csacanam"
}
}
]
},
{
"attribution": null,
"caption": {
"created_time": "1391910835",
"from": {
"full_name": "Camilo Sacanamboy",
"id": "268167404",
"profile_picture": "http://images.ak.instagram.com/profiles/profile_268167404_75sq_1386784112.jpg",
"username": "csacanam"
},
"id": "651717783438333290",
"text": "Vista de Bogot\u00e1"
},
"comments": {
"count": 1,
"data": [
{
"created_time": "1403665438",
"from": {
"full_name": "Camilo Sacanamboy",
"id": "268167404",
"profile_picture": "http://images.ak.instagram.com/profiles/profile_268167404_75sq_1386784112.jpg",
"username": "csacanam"
},
"id": "750322542532990878",
"text": "#sacanamboy"
}
]
},
"created_time": "1391910835",
"filter": "Hudson",
"id": "651717782742079012_268167404",
"images": {
"low_resolution": {
"height": 306,
"url": "http://scontent-b.cdninstagram.com/hphotos-xfp1/t51.2885-15/1889287_611340528913277_403885343_a.jpg",
"width": 306
},
"standard_resolution": {
"height": 640,
"url": "http://scontent-b.cdninstagram.com/hphotos-xfp1/t51.2885-15/1889287_611340528913277_403885343_n.jpg",
"width": 640
},
"thumbnail": {
"height": 150,
"url": "http://scontent-b.cdninstagram.com/hphotos-xfp1/t51.2885-15/1889287_611340528913277_403885343_s.jpg",
"width": 150
}
},
"likes": {
"count": 3,
"data": [
{
"full_name": "Luisa Bellydancer",
"id": "548519361",
"profile_picture": "http://images.ak.instagram.com/profiles/profile_548519361_75sq_1398196543.jpg",
"username": "luisacantillo"
},
{
"full_name": "Stiven Sepulveda Casta\u00f1o",
"id": "270408040",
"profile_picture": "http://photos-a.ak.instagram.com/hphotos-ak-xfp1/10354393_1459814907595448_1770710968_a.jpg",
"username": "johntato"
},
{
"full_name": "Julian Garcia",
"id": "318551590",
"profile_picture": "http://photos-e.ak.instagram.com/hphotos-ak-xaf1/10413240_284995708339980_626057267_a.jpg",
"username": "juliangarcia20"
}
]
},
"link": "http://instagram.com/p/kLXd7WJZYk/",
"location": {
"id": 1187760,
"latitude": 4.67413252,
"longitude": -74.037993338,
"name": "Mirador de La Calera, Bogota"
},
"tags": [
"sacanamboy"
],
"type": "image",
"user": {
"bio": "",
"full_name": "Camilo Sacanamboy",
"id": "268167404",
"profile_picture": "http://images.ak.instagram.com/profiles/profile_268167404_75sq_1386784112.jpg",
"username": "csacanam",
"website": ""
},
"users_in_photo": [
{
"position": {
"x": 0.3625,
"y": 0.54444444
},
"user": {
"full_name": "Luisa Bellydancer",
"id": "548519361",
"profile_picture": "http://images.ak.instagram.com/profiles/profile_548519361_75sq_1398196543.jpg",
"username": "luisacantillo"
}
},
{
"position": {
"x": 0.60694444,
"y": 0.42222223
},
"user": {
"full_name": "Camilo Sacanamboy",
"id": "268167404",
"profile_picture": "http://images.ak.instagram.com/profiles/profile_268167404_75sq_1386784112.jpg",
"username": "csacanam"
}
}
]
}
],
"meta": {
"code": 200
},
"pagination": {
"deprecation_warning": "next_max_id and min_id are deprecated for this endpoint; use min_tag_id and max_tag_id instead",
"min_tag_id": "1403666639684031",
"next_min_id": "1403666639684031"
}
}
Models
#interface TagPicturesInstagram : JSONModel
#property (strong,nonatomic) NSArray<PictureInstagram> *data;
#property (strong,nonatomic) MetaInstagram *meta;
#property (strong,nonatomic) PaginationInstagram *pagination;
#end
#protocol PictureInstagram
#end
#interface PictureInstagram : JSONModel
#property (strong,nonatomic) NSString<Optional> *attribution;
#property (strong,nonatomic) CaptionInstagram *caption;
#property (strong,nonatomic) CommentsInstagram *comments;
#property (strong,nonatomic) NSString *created_time;
#property (strong,nonatomic) NSString *filter;
#property (strong,nonatomic) NSString *id;
#property (strong,nonatomic) ImagesInstagram *images;
#property (strong,nonatomic) LikesInstagram *likes;
#property (strong,nonatomic) NSString *link;
#property (strong,nonatomic) LocationInstagram<Optional> *location;
#property (strong,nonatomic) NSArray<Optional> *tags;
#property (strong,nonatomic) NSString *type;
#property (strong,nonatomic) UserInstagram *user;
#property (strong,nonatomic) NSArray<UserInPhoto> *users_in_photo;
//#property (assign,nonatomic) BOOL user_has_liked;
//#property (strong,nonatomic) NSString<Optional> *website;
#end
#interface MetaInstagram : JSONModel
#property (assign,nonatomic) int code;
#property (strong,nonatomic) NSString<Optional> *error_type;
#property (strong,nonatomic) NSString<Optional> *error_message;
#end
#interface PaginationInstagram : JSONModel
#property (strong,nonatomic) NSString<Optional> *next_max_tag_id;
#property (strong,nonatomic) NSString<Optional> *deprecation_warning;
#property (strong,nonatomic) NSString<Optional> *next_max_id;
#property (strong,nonatomic) NSString<Optional> *next_min_id;
#property (strong,nonatomic) NSString<Optional> *min_tag_id;
#property (strong,nonatomic) NSString<Optional> *next_url;
#end
#interface CaptionInstagram : JSONModel
#property (strong,nonatomic) NSString *created_time;
#property (strong,nonatomic) FromInstagram *from;
#property (strong,nonatomic) NSString *id;
#property (strong,nonatomic) NSString<Optional> *text;
#end
#interface CommentsInstagram : JSONModel
#property (assign,nonatomic) int count;
#property (strong,nonatomic) NSArray<CommentInstagram> *data;
#end
#interface ImagesInstagram : JSONModel
#property (strong,nonatomic) ImgInstagram *low_resolution;
#property (strong,nonatomic) ImgInstagram *standard_resolution;
#property (strong,nonatomic) ImgInstagram *thumbnail;
#end
#interface LikesInstagram : JSONModel
#property (assign,nonatomic) int count;
#property (strong,nonatomic) NSArray<FromInstagram> *data;
#end
#interface LocationInstagram : JSONModel
#property (assign,nonatomic) int id;
#property (assign,nonatomic) double latitude;
#property (assign,nonatomic) double longitude;
#property (strong,nonatomic) NSString *name;
#end
#interface UserInstagram : JSONModel
#property (strong,nonatomic) NSString<Optional> *bio;
#property (strong,nonatomic) NSString *full_name;
#property (strong,nonatomic) NSString *id;
#property (strong,nonatomic) NSString *profile_picture;
#property (strong,nonatomic) NSString *username;
#property (strong,nonatomic) NSString<Optional> *website;
#end
#interface UserInPhoto : JSONModel
#property (strong,nonatomic) PositionTagInstagram *position;
#property (strong,nonatomic) FromInstagram *user;
#end
#protocol FromInstagram
#end
#interface FromInstagram : JSONModel
#property (strong,nonatomic) NSString *full_name;
#property (strong,nonatomic) NSString *id;
#property (strong,nonatomic) NSString *profile_picture;
#property (strong,nonatomic) NSString *username;
#end
#protocol CommentInstagram
#end
#interface CommentInstagram : JSONModel
#property (strong,nonatomic) NSString *created_time;
#property (strong,nonatomic) FromInstagram *from;
#property (strong,nonatomic) NSString *id;
#property (strong,nonatomic) NSString *text;
#end
#protocol ImgInstagram
#end
#interface ImgInstagram : JSONModel
#property (assign,nonatomic) double height;
#property (strong,nonatomic) NSString *url;
#property (assign,nonatomic) double width;
#end
#interface PositionTagInstagram : JSONModel
#property (assign,nonatomic) double x;
#property (assign,nonatomic) double y;
#end
Getting response with AFNetworking
-(void) loadInstagramInfo
{
//1. Create request
NSString *string = [NSString stringWithFormat:#"%#", BaseURLString];
NSURL *url = [NSURL URLWithString:string];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//2. Do request with AFNetworking
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *json = [responseObject description];
NSError *err = nil;
self.pictures = [[TagPicturesInstagram alloc]initWithString:json error:&err];
} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error cargando fotos");
/*
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error Retrieving Weather"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];*/
}];
[operation start];
}
I created one .txt file with your json response and then fetch data that you required.
NSMutableArray *arrayData = [[NSMutableArray alloc]init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"json.txt"];
// NSString *content = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL];
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(#"json = %#",json);
for (NSDictionary* dic in [json objectForKey:#"data"]) {
[arrayData addObject:dic];
}
NSLog(#"array data = %#",arrayData);
NSLog(#"meta code = %#",[[json valueForKey:#"meta"] valueForKey:#"code"]);
NSLog(#"pagination deprecation_warning = %#",[[json valueForKey:#"pagination"] valueForKey:#"deprecation_warning"]);
NSLog(#"pagination min_tag_id = %#",[[json valueForKey:#"pagination"] valueForKey:#"min_tag_id"]);
NSLog(#"pagination next_min_id = %#",[[json valueForKey:#"pagination"] valueForKey:#"next_min_id"]);
follow above code and do changes in your model. Hope this will help you.
This is a response string.
meta code = 200
pagination deprecation_warning = next_max_id and min_id are deprecated for this endpoint; use min_tag_id and max_tag_id instead
pagination deprecation_warning = 1403666639684031
pagination deprecation_warning = 1403666639684031
So, I have this result from the service:
{
"CustomerPromotions": [
{
"BottomTitle": "Thank you",
"IconURL": "",
"MiddleText": "399$",
"PromotionID": "123B456",
"SortOrder": 0,
"TopTitle": "Welcome to"
}
],
"CustomerStatus": 1,
"CustomerVoucherIcon": "",
"CustomerVoucherText": "",
"CustomerVoucherTitle": "",
"ErrorID": 0,
"ErrorMessage": "",
"FeedbackIndicator": false,
"FeedbackLowerText": "",
"FeedbackTitle": "",
"HPTopTitle": "Hello world",
"LocalCurrencySign": "$",
"LocalCurrencyValue": "3.30",
"LocalTime": "20:30",
"LocalWeather": "-5",
"PopUpTopTitle": ""
}
But for some reason I can't map CustomerPromotions it into an array, this is how my 2 objects looks like:
This is CustomerLogin.h:
#interface CustomerLogin : NSObject
#property (nonatomic) NSArray *customerPromotions;
#property (strong, nonatomic) NSNumber *customerStatus;
#property (strong, nonatomic) NSString *customerVoucherIcon;
#property (strong, nonatomic) NSString *customerVoucherText;
#property (strong, nonatomic) NSString *customerVoucherTitle;
#property (strong, nonatomic) NSNumber *errorID;
#property (strong, nonatomic) NSString *errorMessage;
#property (strong, nonatomic) NSNumber *feedbackIndicator;
#property (strong, nonatomic) NSString *feedbackLowerText;
#property (strong, nonatomic) NSString *feedbackTitle;
#property (strong, nonatomic) NSString *hpTopTitle;
#property (strong, nonatomic) NSString *localCurrencySign;
#property (strong, nonatomic) NSString *localCurrencyValue;
#property (strong, nonatomic) NSString *localTime;
#property (strong, nonatomic) NSString *localWeather;
#property (strong, nonatomic) NSString *popUpTopTitle;
#end
This is 'CustomerPromotions`:
#interface CustomerPromotions : NSObject
#property (strong, nonatomic) NSString *bottomTitle;
#property (strong, nonatomic) NSString *iconURL;
#property (strong, nonatomic) NSString *middleText;
#property (strong, nonatomic) NSString *promotionID;
#property (strong, nonatomic) NSNumber *sortOrder;
#property (strong, nonatomic) NSString *topTitle;
#end
This is the mapping:
RKObjectMapping *customerLoginMapping = [RKObjectMapping mappingForClass:[CustomerLogin class]];
[customerLoginMapping addAttributeMappingsFromDictionary:#{ #"CustomerStatus" : #"customerStatus",
#"CustomerVoucherIcon" : #"customerVoucherIcon",
#"CustomerVoucherText" : #"customerVoucherText",
#"CustomerVoucherTitle" : #"customerVoucherTitle",
#"ErrorID" : #"errorID",
#"ErrorMessage" : #"errorMessage",
#"FeedbackIndicator" : #"feedbackIndicator",
#"FeedbackLowerText" : #"feedbackLowerText",
#"FeedbackTitle" : #"feedbackTitle",
#"HPTopTitle" : #"hpTopTitle",
#"LocalCurrencySign" : #"localCurrencySign",
#"LocalCurrencyValue" : #"localCurrencyValue",
#"LocalTime" : #"localTime",
#"LocalWeather" : #"localWeather",
#"PopUpTopTitle" : #"popUpTopTitle" }];
RKObjectMapping *customerPromotionsMapping = [RKObjectMapping mappingForClass:[CustomerPromotions class]];
[customerPromotionsMapping addAttributeMappingsFromDictionary:#{ #"BottomTitle" : #"bottomTitle",
#"IconURL" : #"iconURL",
#"MiddleText" : #"middleText",
#"PromotionID" : #"promotionID",
#"SortOrder" : #"sortOrder",
#"TopTitle" : #"topTitle" }];
[customerLoginMapping addRelationshipMappingWithSourceKeyPath:#"customerPromotions" mapping:customerPromotionsMapping];
[[RKObjectManager sharedManager] addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:customerLoginMapping
method:RKRequestMethodPOST
pathPattern:#"CustomerLogin"
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]];
This is the POST request:
NSDictionary *params = #{ #"AppID" : #"1",
#"AppPassword" : #"String content",
#"Password" : #"password",
#"UserName" : #"username" };
[[RKObjectManager sharedManager] postObject:[[CustomerLogin alloc] init]
path:#"CustomerLogin"
parameters:params
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(#"%#", operation.HTTPRequestOperation.responseString);
NSLog(#"%#", mappingResult.array);
CustomerLogin *customer = [mappingResult.array lastObject];
NSLog(#"%#", customer.customerPromotions);
NSLog(#"%#", customer.hpTopTitle);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(#"%#", error.localizedDescription);
}];
It just looks like your key name is wrong. You use a source key only, which means the source and destination should match but they don't actually match. Try:
RKRelationshipMapping *relationMapping = [RKRelationshipMapping relationshipMappingFromKeyPath:#"CustomerPromotions" toKeyPath:#"customerPromotions" withMapping:customerPromotionsMapping];
[customerLoginMapping addPropertyMapping:relationMapping];
I'm not able to map the Images from my JSON response correctly, and I can't figure out why.
Here is error: "W restkit.object_mapping:RKObjectMappingOperation.m:244 Failed transformation of value at keyPath 'images'. No strategy for transforming from '__NSArrayM' to 'Images'"
Here is JSON:
{
"timestamp": "2013-05-10T03:09:39Z",
"feed": [{
"headline": "Head text",
"links": {
"api": {
"news": {
"href": "http://api.website.com/v1/91"
},
"self": {
"href": "http://api.website.com/v1/91"
}
},
"web": {
"href": "http://website.com/the/story"
},
"mobile": {
"href": "http://m.website.com/wireless/story?storyId=9254113"
}
},
"source": "Associated Press",
"description": "Description text.",
"images": [{
"height": 324,
"alt": "",
"width": 576,
"name": "Name text",
"caption": "Caption text.",
"url": "http://a.website.com/media/2013/0508.jpg"
}],
Feed.h
#property (nonatomic, strong) Links *links;
#property (nonatomic, strong) Images *images;
#property (nonatomic, strong) Video *video;
#property (nonatomic, strong) NSString *headline;
#property (nonatomic, strong) NSString *source;
#property (nonatomic, strong) NSDate *published;
#property (nonatomic, strong) NSString *description;
#property (nonatomic, strong) NSString *premium;
+ (RKObjectMapping *) mapping;
Feed.m
+ (RKObjectMapping *)mapping {
RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:[self class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapKeyPathsToAttributes:
#"headline", #"headline",
#"source", #"source",
#"published", #"published",
#"description", #"description",
#"premium", #"premium",
nil];
[mapping hasOne:#"links" withMapping:[Links mapping]];
[mapping hasOne:#"images" withMapping:[Images mapping]];
//[mapping hasMany:#"images" withMapping:[Images mapping]];
[mapping hasOne:#"video" withMapping:[Video mapping]];
}];
return objectMapping;
}
Images.h
#property (nonatomic, strong) NSNumber *height;
#property (nonatomic, strong) NSNumber *width;
#property (nonatomic, strong) NSString *caption;
#property (nonatomic, strong) NSURL *url;
+ (RKObjectMapping *) mapping;
Images.m
+ (RKObjectMapping *)mapping {
RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:[self class] usingBlock:^(RKObjectMapping *mapping) {
[mapping mapKeyPathsToAttributes:
#"height", #"height",
#"width", #"width",
#"caption", #"caption",
#"url", #"url",
nil];
}];
return objectMapping;
}
Everything else is mapping correctly except images. I don't know if it has to do with it being an Array but it only having one result, so its not necessarily an array? And if its not, then how I would write that... I'm just not totally clear on why its not mapping.
As you can see I tried both hasMany: and hasOne: mapping and neither worked, I got the same error.
I tried using NSLog(#"url image: %#", feedLocal.images.url);' but get(null). Even though I thought it would work becauseNSLog(#"href web: %#", feedLocal.links.web.href);` works perfectly for my links href.
Any help would be greatly appreciated, thanks so much!
In Feed.h you need to change your images property to be:
#property (nonatomic, strong) NSArray *images;
And you should set the mapping to hasMany:.