简体   繁体   English

如何将JSON转换为Object

[英]How to convert JSON to Object

I defined some custom classes, such as Teacher , Student ... Now I receive teacher info (JSON string) from remote server. 我定义了一些自定义类,例如TeacherStudent ...现在我从远程服务器接收教师信息(JSON字符串)。

How can I convert the JSON string to Teacher object. 如何将JSON字符串转换为Teacher对象。

In Java, it's easy to implement a common method for all class ( Teacher , Student ...) with reflect . 在Java中,使用reflect可以很容易地为所有类( TeacherStudent ...)实现一个通用方法。

But in Objective-C on iOS, the best way I can find is to use Entity of Core Data, which has setValue:forKey method. 但是在iOS上的Objective-C中,我能找到的最好的方法是使用具有setValue:forKey方法的核心数据实体。 First I convert the JSON string to NSDictionary , the set the key-value pair in the disctionary to the Entry . 首先,我将JSON字符串转换为NSDictionary ,将dectionary中的键值对设置为Entry

Is there any better ways? 有没有更好的方法?

(I'm from China, so maybe my English is poor, sorry!) (我来自中国,也许我的英语很差,对不起!)

First, do you use JSON Parser? 首先,你使用JSON Parser吗? (if not, i'd recommend using SBJson). (如果没有,我建议使用SBJson)。

Second, why not create an initWithDictionary init method in your custom class that returns self object? 其次,为什么不在自定义类中创建一个返回self对象的initWithDictionary init方法呢?

These are all good frameworks for JSON parsing to dictionaries or other primitives, but if you're looking to avoid doing a lot of repetitive work, check out http://restkit.org . 这些都是JSON解析字典或其他原语的好框架,但是如果你想避免做大量的重复性工作,请查看http://restkit.org Specifically, check out https://github.com/RestKit/RestKit/blob/master/Docs/Object%20Mapping.md This is the example on Object mapping where you define mapping for your Teacher class and the json is automagically converted to a Teacher object by using KVC. 具体来说,请查看https://github.com/RestKit/RestKit/blob/master/Docs/Object%20Mapping.md这是对象映射的示例,您可以在其中定义Teacher类的映射,并将json自动转换为使用KVC的教师对象。 If you use RestKit's network calls, the process is all transparent and simple, but I already had my network calls in place and what I needed was to convert my json response text to a User object (Teacher in your case) and I finally figured out how. 如果你使用RestKit的网络调用,这个过程都是透明和简单的,但我已经进行了网络调用,我需要的是将我的json响应文本转换为User对象(你的教师),我终于想通了怎么样。 If that's what you need, post a comment and I'll share how to do it with RestKit. 如果这就是你需要的,发表评论我会与RestKit分享如何做到这一点。

Note: I will assume the json is output using the mapped convention {"teacher": { "id" : 45, "name" : "Teacher McTeacher"}} . 注意:我将假设使用映射约定输出json {"teacher": { "id" : 45, "name" : "Teacher McTeacher"}} If it's not this way, but instead like this {"id" : 45, "name" : "Teacher McTeacher"} then don't worry ... object mapping design doc in the link shows you how to do this...a few extra steps, but not too bad. 如果不是这样,而是像这样{"id" : 45, "name" : "Teacher McTeacher"}然后不要担心...链接中的对象映射设计doc告诉你如何做到这一点......一些额外的步骤,但不是太糟糕。

This is my callback from ASIHTTPRequest 这是我从ASIHTTPRequest回调的

- (void)requestFinished:(ASIHTTPRequest *)request {
    id<RKParser> parser = [[RKParserRegistry sharedRegistry] parserForMIMEType:[request.responseHeaders valueForKey:@"Content-Type"]]; // i'm assuming your response Content-Type is application/json
    NSError *error;
    NSDictionary *parsedData = [parser objectFromString:apiResponse error:&error];
    if (parsedData == nil) {
        NSLog(@"ERROR parsing api response with RestKit...%@", error);
        return;
    }

    [RKObjectMapping addDefaultDateFormatterForString:@"yyyy-MM-dd'T'HH:mm:ssZ" inTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; // This is handy in case you return dates with different formats that aren't understood by the date parser

    RKObjectMappingProvider *provider = [RKObjectMappingProvider new];

    // This is the error mapping provider that RestKit understands natively (I copied this verbatim from the RestKit internals ... so just go with it
    // This also shows how to map without blocks
    RKObjectMapping* errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]];
    [errorMapping mapKeyPath:@"" toAttribute:@"errorMessage"];
    [provider setMapping:errorMapping forKeyPath:@"error"];
    [provider setMapping:errorMapping forKeyPath:@"errors"];

    // This shows you how to map with blocks
    RKObjectMapping *teacherMapping = [RKObjectMapping mappingForClass:[Teacher class] block:^(RKObjectMapping *mapping) {
        [mapping mapKeyPath:@"id" toAttribute:@"objectId"];
        [mapping mapKeyPath:@"name" toAttribute:@"name"];
    }];

    [provider setMapping:teacherMapping forKeyPath:@"teacher"];

    RKObjectMapper *mapper = [RKObjectMapper mapperWithObject:parsedData mappingProvider:provider];
    Teacher *teacher = nil;
    RKObjectMappingResult *mappingResult = [mapper performMapping];
    teacher = [mappingResult asObject];

    NSLog(@"Teacher is %@ with id %lld and name %@", teacher, teacher.objectId, teacher.name);
}

You can obviously refactor this to make it cleaner, but that now solves all my problems.. no more parsing... just response -> magic -> Object 你可以明显地重构它以使它更清洁,但现在解决了我所有的问题..不再解析...只是响应 - >魔术 - >对象

具体来说,请查看https://github.com/fanpyi/jsontooc/blob/master/README.md这是将JSON数据转换为Objective-C模型的示例,使用nodejs。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM