如何使用JSON对象数组初始化JSONModel? [英] How to init a JSONModel with an Array of json objects?

查看:114
本文介绍了如何使用JSON对象数组初始化JSONModel?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在目标c应用程序中有一个使用JSONModel的模型. JSONModel github 我正在尝试从服务器的响应中初始化我的模型.服务器的响应是这样的:

[ { "id":0, 名称":"Jhon" }, { "id":1 名称":迈克" }, { "id":2 名称":卢阿" }]

我的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];

但是我得到一个空模型.

我认为问题出在

之类的格式响应

[{}]

但是我不知道该如何转换.

是否可以从json对象数组中初始化JSONModel?

我该怎么做?

解决方案

您引用的库似乎仅与NSDictionary根Json对象兼容,而您具有NSArray根json对象.

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数据:尝试使用initWithDictionary:error初始化JSONModel对象,但dictionary参数不是'NSDictionary'.

您当前的服务器JSON响应:

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

有关JSONModel库能够解析的JSON的示例:

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

如果您无法在后端上修改服务器响应以使其返回NSDictionary作为根JSON对象,则可以对返回的数据进行预处理,以格式化为JSONModel lib期望的格式(NSDictionary根)./p>

这是我的意思的示例(具体地说,您将想使用jsonDataUsingYourCurrentArrayStructureWithPreProcessing:之类的东西来预处理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数组中进行自己的初始化,在People类中遵循以下几行内容:

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

I have a model using JSONModel in my objective c application. JSONModel github I am trying init my model from a response of server. The response of server is this:

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

My JSONModel is:

@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

And I'm trying init this then get the response from server like:

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

But I'm getting a null model.

I think that the problem is the format response like

[{ }]

But I don't know how to convert this.

is possible init a JSONModel from an array of json objects?

How can I do this?

解决方案

The library you reference appears to only be compatible with an NSDictionary root Json object, whereas you have an NSArray root json object.

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

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

If you check the error returned when attempting to initWithData, I'm sure it will have this error message:

Invalid JSON data: Attempt to initialize JSONModel object using initWithDictionary:error: but the dictionary parameter was not an 'NSDictionary'.

Your currently server JSON response:

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

An example of what the JSON would look like that the JSONModel lib would be able to parse:

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

If you're unable to modify your server response on the backend to have it return an NSDictionary as the root JSON object, you could pre-process the returned data to format for what JSONModel lib is expecting (NSDictionary root).

Here's an example of what I mean (specifically you'll want to use something like jsonDataUsingYourCurrentArrayStructureWithPreProcessing: to pre-process your JSON data:

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

Alternatively, you can just roll your own initialization from the JSON array, something along these lines in the People Class:

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

这篇关于如何使用JSON对象数组初始化JSONModel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆