[英]Parsing nested JSON objects with JSON Framework for Objective-C
[英]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解析代码)很难分辨,但有两件事情让我感到害怕:
你没有用完整的路径查询。 在上面的例子中,您需要首先获取封闭模型,json响应,然后才向json响应字典询问authenticationFlag值:
[[[jsonDict objectForKey:@"model"] objectForKey:@"JSONRESPONSE"] objectForKey:@"authenticationFlag"]
也许你正在使用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];
所以利用这个类,让你的应用程序没有错误...... :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.