Как запустить JSONModel с массивом объектов json? - PullRequest
0 голосов
/ 20 мая 2019

У меня есть модель, использующая JSONModel в моей цели c приложением. JSONModel github Я пытаюсь инициировать мою модель из ответа сервера.Ответ сервера таков:

[{"id": 0, "name": "Jhon"}, {"id": 1, "name": "Mike"}, {"id": 2, "name": "Lua"}]

Мой JSONModel:

@protocol People @end

@interface People : JSONModel

@property (nonatomic, strong)  NSArray <Person> * peopleArray;

@end





@protocol Person @end

@interface Person : JSONModel

@property (nonatomic, strong)  NSNumber <Optional>  * id;

@property (nonatomic, strong)  NSString <Optional>  * name;

@end

И я пытаюсь инициализировать это, затем получить ответ от серверакак:

NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:responseData options:NSJSONWritingPrettyPrinted error:&error];
People *peoplemodel = [[People alloc] initWithData:jsonData error:&error];

Но я получаю нулевую модель.

Я думаю, что проблема заключается в ответе формата:

[{}]

Но я не знаю, как это преобразовать.

возможно ли инициировать JSONModel из массива объектов json?

Как я могу это сделать?

1 Ответ

0 голосов
/ 24 мая 2019

Библиотека, на которую вы ссылаетесь, кажется совместимой только с корневым объектом Json NSDictionary, тогда как у вас есть корневой объект json NSArray.

https://github.com/jsonmodel/jsonmodel/blob/master/JSONModel/JSONModel/JSONModel.m#L123

https://github.com/jsonmodel/jsonmodel/blob/master/JSONModel/JSONModel/JSONModel.m#L161

Если вы проверите ошибку, возвращаемую при попытке initWithData, я уверен, что у нее будет следующее сообщение об ошибке:

Неверные данные JSON: попытка инициализировать объект JSONModel с использованием initWithDictionary: error:, но словарьпараметр не был NSDictionary.

Ваш текущий ответ JSON сервера:

NSArray <NSDictionary *> *jsonArray = @[ @{ @"id": @(0), @"name": @"Jhon" }, @{ @"id": @(1), @"name": @"Mike" }, @{ @"id": @(2), @"name": @"Lua" } ];

Пример того, как будет выглядеть JSON, что библиотека JSONModel сможет анализировать:

NSDictionary <NSString *, NSArray <NSDictionary *> *> *jsonDictionary = @{ @"peopleArray": @[@{@"id": @(0), @"name": @"Jhon"}, @{ @"id": @(1), @"name": @"Mike" }, @{ @"id": @(2), @"name": @"Lua" }]};

Если вы не можете изменить ответ сервера на бэкэнде, чтобы он возвращал NSDictionary в качестве корневого объекта JSON, вы можете предварительно обработать возвращенные данные для форматирования для того, что является библиотекой JSONModelожидая (NSDictionary root).

Вот пример того, что я имею в виду (в частности, вы хотите использовать что-то вроде jsonDataUsingYourCurrentArrayStructureWithPreProcessing: для предварительной обработки yoданные JSON:

- (void)viewDidLoad {
    [super viewDidLoad];
    NSArray <NSDictionary *> *jsonArray = @[ @{ @"id": @(0), @"name": @"Jhon" }, @{ @"id": @(1), @"name": @"Mike" }, @{ @"id": @(2), @"name": @"Lua" } ];
    NSError *jsonSerializationError;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonArray options:0 error:&jsonSerializationError];
    if (jsonSerializationError) {
        NSLog(@"jsonSerializationError = %@", jsonSerializationError);
    }
    jsonData = [self jsonDataUsingYourCurrentArrayStructureWithPreProcessing:jsonData];
    NSError *jsonModelError;
    People *people = [[People alloc] initWithData:jsonData error:&jsonModelError];
    if (people) {
        [self printPeople:people];
    } else if (jsonModelError != nil) {
        NSLog(@"Error returned from jsonModel = %@", jsonModelError);
    }
}

- (void)printPeople:(People *)people {
    for (Person *person in people.peopleArray) {
        NSLog(@"person id = %li, name = %@", [person.id integerValue], person.name);
    }
}

- (NSData *)jsonDataUsingYourCurrentArrayStructureWithPreProcessing:(NSData *)jsonData {
    NSError *parsingError;
    id obj = [NSJSONSerialization JSONObjectWithData:jsonData
                                             options:0
                                               error:&parsingError];
    if ([obj isKindOfClass:[NSArray class]] && parsingError == nil) {
        NSArray <NSDictionary *> *jsonArray = (NSArray <NSDictionary *> *)obj;
        NSDictionary *jsonDictionary = [NSDictionary dictionaryWithObject:jsonArray forKey:@"peopleArray"];
        NSError *jsonSerializationError;
        NSData *jsonDictData = [NSJSONSerialization dataWithJSONObject:jsonDictionary options:0 error:&jsonSerializationError];
        if (jsonDictData && jsonSerializationError == nil) {
            return jsonDictData;
        } else {
            NSLog(@"jsonSerializationError = %@", jsonSerializationError);
            return nil;
        }
    } else {
        if (parsingError) {
            NSLog(@"Error parsing jsonData = %@", parsingError);
        }
        return nil;
    }
}

Кроме того, вы можете просто свернуть свою собственную инициализацию из массива JSON, что-то вроде этого в классе людей:

+ (instancetype)peopleWithJsonArray:(NSArray<NSDictionary *> *)jsonArray {
    People *people = [[People alloc] init];
    if (people) {
        [people setupPeopleArrayFromJsonArray:jsonArray];
    }
    return people;
}

- (void)setupPeopleArrayFromJsonArray:(NSArray <NSDictionary *> *)jsonArray {
    NSMutableArray <Person *> *people = [[NSMutableArray alloc] initWithCapacity:jsonArray.count];
    for (NSDictionary *personDictionary in jsonArray) {
        Person *person = [Person personWithID:[personDictionary objectForKey:@"id"] andName:[personDictionary objectForKey:@"name"]];
        [people addObject:person];
    }
    self.peopleArray = [NSArray arrayWithArray:people];
}
...