This is my JSON fetched from the API:
{
categories = (
{
icon = {
prefix = "https://ss3.4sqi.net/img/categories_v2/food/italian_";
suffix = ".png";
};
id = 4bf58dd8d48988d110941735;
name = "Italian Restaurant";
pluralName = "Italian Restaurants";
primary = 1;
shortName = Italian;
}
);
hasPerk = 0;
id = 4b5bed2ef964a520971d29e3;
location = {
address = "HS-5";
cc = IN;
city = "New Delhi";
country = India;
crossStreet = "Kailash Colony Market";
distance = 4061;
formattedAddress = (
"HS-5 (Kailash Colony Market)",
"New Delhi 110024",
Delhi,
India
);
labeledLatLngs = (
{
label = display;
lat = "28.55272788981442";
lng = "77.24192322690806";
}
);
lat = "28.55272788981442";
lng = "77.24192322690806";
postalCode = 110024;
state = Delhi;
};
name = "The Big Chill Cafe";
referralId = "v-1546605733";
}
And here is my model class:
@interface LocationModel : JSONModel
@property (nonatomic) NSInteger distance;
@property (nonatomic) NSInteger postalCode;
@property (nonatomic) NSString *address;
@property (nonatomic) NSString *cc;
@property (nonatomic) NSString *city;
@property (nonatomic) NSString *country;
@property (nonatomic) NSString *crossStreet;
@property (nonatomic) NSString *lat;
@property (nonatomic) NSString *lng;
@property (nonatomic) NSString *state;
@property (nonatomic) NSArray *formattedAddress;
@property (nonatomic) NSArray *labeledLatLngs;
@end
@protocol VenueModel;
@interface VenueModel : JSONModel
@property (nonatomic) NSArray *categories;
@property (nonatomic) BOOL hasPerk;
@property (nonatomic) NSString *id;
@property (nonatomic) LocationModel *location;
@property (nonatomic) NSString *name;
@property (nonatomic) NSString *referralId;
@end
@interface Restaurant : JSONModel
@property (nonatomic) NSInteger confident;
@property (nonatomic) NSArray <VenueModel*> *venues;
@end
Now, I am trying to get the values like this:
restaurant = [[Restaurant alloc] initWithDictionary
[NSJSONSerialization JSONObjectWithData:JSON
options:NSJSONReadingAllowFragments error:nil][@"response"] error:&error];
VenueModel *obj = [restaurant.venues firstObject];
LocationModel *locationObj = obj.location;
The values are coming fine till the VenueModel object, after that when I am trying to access the LocationModel object, i.e
LocationModel *locationObj = obj.location
, its throwing the following error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryI location]: unrecognized selector sent to instance 0x600001b82880
Somebody please help me out, I need the location object.
NSJSONSerialization will produce NSDictionaries, NSArrays, NSStrings, NSNumbers and a few other basic types from a JSON string.
Your idea to initialize a custom object ([[Restaurant alloc] initWithDictionary...
) is the right idea, but that idea must be applied to nested structures as well. So, for example, the Restaurant
initializer must apply that idea to its venues
array.
Otherwise, you'll get the crash you're getting, treating one of the venue objects as if its a VenueModel
instead of what it really is (an NSDictionary).
You didn't post initWithDictionary
, but it needs to look something like this, especially the part where the objects it contains are initialized...
- (id)initWithDictionary:(NSDictionary *)dictionary {
self = [super init];
// ...
self.venues = [NSMutableArray array];
if (self) {
for (NSDictionary *venueDictionary in dictionary[@"venues"]) {
VenueModel *venue = [[VenueModel alloc] initWithDictionary:venueDictionary];
[self.venues addObject:venue];
}
}
// and so on, for every other object type nested in dictionary
return self;
}
Moreover, as you can see, VenueModel
must also follow this practice, turning the location data into a LocationModel
, and so on...