繁体   English   中英

如何使用JSON框架和Objective-C / iPhone / Xcode解析嵌套的JSON对象?

[英]How to parse nested JSON objects with JSON framework and Objective-C/iPhone/Xcode?

我正在使用JSON框架编写iPhone本机应用程序。

我的应用程序正在使用JSON访问Web服务。 我们发送的JSON数据有嵌套对象,下面是提供的数据示例:

{
    "model": {
        "JSONRESPONSE": {
            "authenticationFlag": true,
            "sessionId": "3C4AA754D77BFBE33E0D66EBE306B8CA",
            "statusMessage": "Successful Login.",
            "locId": 1,
            "userName": "Joe Schmoe"
        }
    }
}

我使用objectForKey和valueForKey NSDictionary方法解析时遇到问题。 我不断收到invalidArgumentException运行时错误。

例如,我想查询“authenticationFlag”元素的响应数据。

谢谢,迈克西雅图

没有更多细节(例如你正在使用的JSON解析代码)很难分辨,但有两件事情让我感到害怕:

  1. 你没有用完整的路径查询。 在上面的例子中,您需要首先获取封闭模型,json响应,然后才向json响应字典询问authenticationFlag值:

    [[[jsonDict objectForKey:@"model"] objectForKey:@"JSONRESPONSE"] objectForKey:@"authenticationFlag"]

  2. 也许你正在使用c-strings( "" )而不是NSStrings( @"" )作为键(虽然这可能会崩溃或只是不能编译)。 密钥应该是可以转换为id的东西。

尽管可能,两者都可能是假的,所以请包含更多细节。

以下内容直接来自Dan Grigsby的教程 - http://mobileorchard.com/tutorial-json-over-http-on-the-iphone/ - 请属性,窃取是不好的业力。

通过HTTP获取JSON

我们将使用Cocoa的NSURLConnection发出HTTP请求并检索JSON数据。

Cocoa提供了用于发出HTTP请求的同步和异步选项。 从应用程序的主runloop运行的同步请求导致应用程序在等待响应时停止。 异步请求使用回调来避免阻塞并且使用起来很简单。 我们将使用异步请求。

我们需要做的第一件事是更新我们的视图控制器的接口,以包含一个NSMutableData来保存响应数据。 我们在界面中声明了这个(而不是在方法内部),因为响应以串联的形式串联回来,而不是在一个完整的单元中。

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController {
    IBOutlet UILabel *label;
    NSMutableData *responseData;
}

为了简单起见,我们将从viewDidLoad启动HTTP请求。

替换内容:

#import "JSON/JSON.h"

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    responseData = [[NSMutableData data] retain];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"XYZ.json"]];
    [[NSURLConnection alloc] initWithRequest:request delegate:self];
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    [responseData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [responseData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    label.text = [NSString stringWithFormat:@"Connection failed: %@", [error description]];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [connection release];
}

- (void)dealloc {
    [super dealloc];
}

@end

这主要是样板代码初始化responseData变量以准备保存数据并启动viewDidload中的连接; 它收集了didReceiveData中的碎片; 并且空的connectionDidFinishLoading随时准备对结果做一些事情。 使用JSON数据

接下来,我们将充实connectionDidFinishLoading方法以使用在最后一步中检索的JSON数据。

更新connectionDidFinishLoading方法:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [connection release];

    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
    [responseData release];

    NSArray *luckyNumbers = [responseString JSONValue];

    NSMutableString *text = [NSMutableString stringWithString:@"Lucky numbers:\n"];

    for (int i = 0; i < [luckyNumbers count]; i++)
        [text appendFormat:@"%@\n", [luckyNumbers objectAtIndex:i]];

    label.text =  text;
}

它创建了一个NSArray。 解析器非常灵活,并返回对象 - 包括嵌套对象 - 使JSON数据类型与Objective-C数据类型相匹配。 更好的错误处理

到目前为止,我们一直在使用NSString方法解析JSON的方便,高级扩展。 我们这样做是有充分理由的:将JSONValue消息简单地发送到字符串以访问解析的JSON值非常方便。

不幸的是,使用这种方法会使错误处理变得困难。 如果JSON解析器因任何原因失败,它只返回一个nil值。 但是,如果您在发生这种情况时查看控制台日志,您将看到描述导致解析器失败的确切原因的消息。

能够将这些错误细节传递给用户真是太好了。 为此,我们将切换到JSON SDK支持的第二种面向对象方法。

更新connectionDidFinishLoading方法:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [connection release];

    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
    [responseData release];

    NSError *error;
    SBJSON *json = [[SBJSON new] autorelease];
    NSArray *luckyNumbers = [json objectWithString:responseString error:&error];
    [responseString release];   

    if (luckyNumbers == nil)
        label.text = [NSString stringWithFormat:@"JSON parsing failed: %@", [error localizedDescription]];
    else {
        NSMutableString *text = [NSMutableString stringWithString:@"Lucky numbers:\n"];

        for (int i = 0; i < [luckyNumbers count]; i++)
            [text appendFormat:@"%@\n", [viewcontroller objectAtIndex:i]];

        label.text =  text;
    }
}

使用此方法为我们提供了指向底层JSON解析器的错误对象的指针,我们可以使用它来进行更有用的错误处理。

结论:

JSON SDK和Cocoa对HTTP的内置支持使得向iPhone应用程序直接添加JSON Web服务。

    NSString* aStr;
    aStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    NSDictionary *dictionary = [aStr JSONValue];
    NSArray *keys = [dictionary allKeys];

    // values in foreach loop
    for (NSString *key in keys) {
    NSArray *items = (NSArray *) [dictionary objectForKey:key];  

        for (id *item in items) {  


            NSString* aStrs=  item;
            NSLog(@" test %@", aStrs);

            NSDictionary *dict = aStrs;
            NSArray *k = [dict allKeys];

        for (id *it in k) {  
                            NSLog(@"the  child item: %@", [NSString stringWithFormat:@"Child Item -> %@ value %@", (NSDictionary *) it,[dict objectForKey:it]]);                
                        }

现在,Objective c已经在JSON Parsing的构建类中引入。

 NSError *myError = nil;
 NSDictionary *resultDictionary = [NSJSONSerialization JSONObjectWithData:self.responseData options:NSJSONReadingMutableLeaves error:&myError];

http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html

所以利用这个类,让你的应用程序没有错误...... :)

暂无
暂无

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

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