如何将JSON转换为Object

理想评*_*论学派 10 iphone objective-c ios

我定义了一些自定义类,例如Teacher,Student...现在我从远程服务器接收教师信息(JSON字符串).

如何将JSON字符串转换为Teacher对象.

在Java中,很容易为所有类(Teacher,Student...)实现一个通用方法reflect.

但是在iOS上的Objective-C中,我能找到的最好的方法是使用具有setValue:forKey方法的核心数据实体.首先我将JSON字符串转换为NSDictionary,将设备中的键值对设置为Entry.

有没有更好的方法?

(我来自中国,也许我的英语很差,对不起!)

Nad*_*vN7 6

首先,你使用JSON Parser吗?(如果没有,我建议使用SBJson).

其次,为什么不在自定义类中创建一个返回self对象的initWithDictionary init方法呢?

  • 如果你使用iOS 5使用NSJSONSerialization类中的构建,如果不使用JSONKit,它的速度比SBJSON快. (3认同)

Adr*_*uez 5

这些都是JSON解析字典或其他原语的好框架,但是如果你想避免做大量的重复性工作,请查看http://restkit.org.具体来说,请查看https://github.com/RestKit/RestKit/blob/master/Docs/Object%20Mapping.md这是对象映射的示例,您可以在其中定义Teacher类的映射,并将json自动转换为使用KVC的教师对象.如果你使用RestKit的网络调用,这个过程都是透明和简单的,但我已经进行了网络调用,我需要的是将我的json响应文本转换为User对象(在你的情况下是教师),我终于想通了怎么样.如果这就是你需要的,发表评论我会与RestKit分享如何做到这一点.

注意:我将假设使用映射约定输出json {"teacher": { "id" : 45, "name" : "Teacher McTeacher"}}.如果它不是这样,而是像这样,{"id" : 45, "name" : "Teacher McTeacher"}那么不要担心...链接中的对象映射设计文档向您展示了如何执行此操作...一些额外的步骤,但也不是太糟糕.

这是我从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);
}
Run Code Online (Sandbox Code Playgroud)

你可以明显地重构它以使它更清洁,但现在解决了我所有的问题..不再解析...只是响应 - >魔术 - >对象