Почему мой класс JSONModel рассматривается как NSDictionary?

Это мой JSON, полученный из 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";
} 

А вот и мой модельный класс:

@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

Теперь я пытаюсь получить такие значения:

restaurant = [[Restaurant alloc] initWithDictionary

 [NSJSONSerialization JSONObjectWithData:JSON            
options:NSJSONReadingAllowFragments error:nil][@"response"] error:&error];

VenueModel *obj = [restaurant.venues firstObject];
LocationModel *locationObj = obj.location;

Значения поступают нормально до объекта VenueModel, после этого, когда я пытаюсь получить доступ к объекту LocationModel, т.е.

LocationModel *locationObj = obj.location

, бросая следующую ошибку:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSDictionaryI location]: unrecognized selector sent to instance 0x600001b82880

Кто-нибудь, пожалуйста, помогите мне, мне нужен объект местоположения.

1 ответ

Решение

NSJSONSerialization создаст NSDictionaries, NSArrays, NSStrings, NSNumbers и несколько других основных типов из строки JSON.

Ваша идея инициализировать пользовательский объект ([[Restaurant alloc] initWithDictionary...) является правильной идеей, но эта идея должна применяться и к вложенным структурам. Так, например, Restaurant инициализатор должен применить эту идею к его venues массив.

В противном случае вы получите аварийное завершение, рассматривая один из объектов объекта, как если бы VenueModel вместо того, что это на самом деле (NSDictionary).

Вы не опубликовали initWithDictionary, но он должен выглядеть примерно так, особенно в той части, где объекты, которые он содержит, инициализируются...

- (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;
}

Более того, как вы можете видеть, VenueModel должны также следовать этой практике, превращая данные о местоположении в LocationModel, и так далее...

Другие вопросы по тегам