如何在iOS上正确读取JSON

时间:2014-04-20 20:56:44

标签: ios json nsurlconnection nsjsonserialization

我正在尝试从POST请求中读取JSON。问题是,我无法获得嵌套的词典。我试图保存json然后在我的mac上使用该文件,一切正常!我正在使用此方法从服务器获取JSON:

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        if (!connectionError) {
            if (![[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] isEqualToString:@"{\"response\":{\"status\":\"fail\",\"message\":\"Please use a POST request.\",\"code\":4012}}"]) {
                NSError *error;
                NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:@"/Users/David/Downloads/Test"] options:kNilOptions error:&error]; //This returns a other JSON than the JSON stored on my mac
                NSArray *array = [dict objectForKey:@"list"];
                NSMutableDictionary *mutableDict = [NSMutableDictionary new];
                for (NSInteger i = 0; array.count>i; i++) {
                    NSDictionary *listDictionary = [array objectAtIndex:i];
                    NSDictionary *defenition = [listDictionary objectForKey:@"definition"];
                    [mutableDict setObject:[defenition objectForKey:@"form"] forKey:[listDictionary objectForKey:@"term"]];
                }
                NSLog(@"%@",  mutableDict);
            }
        }
    }];

现在问题是,我必须使用另一种方法从NSURLConnection获取正确的JSON吗?

由于

修改

这是我下载的json以及我在mac上的内容:

{
  "response" : {
    "status" : "success",
    "code" : "200",
    "message" : "OK"
  },
  "list" : [
    {
      "term" : "Black",
      "context" : "",
      "created" : "2014-04-17 20:34:33",
      "updated" : "",
      "definition" : {
        "form" : "Schwarz",
        "fuzzy" : 0,
        "updated" : "2014-04-17 21:35:50"
      },
      "reference" : "",
      "tags" : []
    }
  ]
}

这是我从字典中得到的" dict":

{
  "response" : {
    "status" : "success",
    "code" : "200",
    "message" : "OK"
  },
  "list" : [
    {
      "term" : "Black",
      "context" : "",
      "created" : "2014-04-17 20:34:33",
      "updated" : "",
      "reference" : "",
      "tags" : []
    }
  ]
}

注意,字典"定义"不见了!

3 个答案:

答案 0 :(得分:2)

如果您可以将应用限制为iOS 5.0+,请转到NSJSONSerializationhttps://developer.apple.com/library/ios/documentation/foundation/reference/nsjsonserialization_class/Reference/Reference.html

如果你真的需要支持较旧的iOS版本,那么请回到我身边,我会挖掘那些黑暗日子常见的框架。 (我只是不记得它的名字)

答案 1 :(得分:0)

只是一个猜测(我总是需要深入研究文档以找出com协议):

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    if (!connectionError) {
        if (![[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] isEqualToString:@"{\"response\":{\"status\":\"fail\",\"message\":\"Please use a POST request.\",\"code\":4012}}"]) {  // This test is bogus but we'll leave it for now
            NSError *error;
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
            if (dict == nil) {
                NSLog(@"Error deserializing JSON: %@", error);
                // Do something
            }
            if (![dict isKindOfClass:[NSDictionary class]]) {
                NSLog(@"Did not receive dictionary as outer JSON: %@", dict);
                // Do something
            }
            NSArray *array = [dict objectForKey:@"list"];
            NSMutableDictionary *mutableDict = [NSMutableDictionary new];
            for (NSInteger i = 0; array.count>i; i++) {
                NSDictionary *listDictionary = [array objectAtIndex:i];
                NSDictionary *defenition = [listDictionary objectForKey:@"definition"];
                [mutableDict setObject:[defenition objectForKey:@"form"] forKey:[listDictionary objectForKey:@"term"]];
            }
            NSLog(@"%@",  mutableDict);
        }
        else {
            // Do something
        }
    }
    else {
        // Do something
    }
}];

答案 2 :(得分:0)

除非您需要发送自定义HTTP标头或其他内容,否则请勿使用NSURLConnection。而是使用NSData自己从URL加载的能力,如果您只想要基本的URL请求,它将获得所有HTTP标头和性能内容以及错误检查。我的示例代码显示了如何执行此操作,还显示了如何正确使用NSURLConnection自定义帖子数据/等(注释掉)。

另外,在这种情况下请勿使用sendAsynchronousRequest:。而是创建自己的异步代码块,以便您可以在后台线程上发送URL请求并解码JSON 。当您真正想要使用解码数据时,请回退到主线程。

NSURL *url = [NSURL URLWithString:@"http://example.com"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

  // basic get request:
  NSData *data = [NSData dataWithContentsOfURL:url];
  if (!data) {
    NSLog(@"http error");
    return;
  }

  // more complex get or post request, where you need to send parameters or custom headers or caching
  //NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
  //[request setHTTPMethod:@"POST"];
  //[request setHTTPBody:postData];
  //NSHTTPURLResponse *urlResponse = nil;
  //NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:NULL];
  //if (!data || [urlResponse statusCode] != 200) {
  //  NSLog(@"http error");
  //  return;
  //}

  // decode json
  NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
  if (!dict || ![dict isKindOfClass:[NSDictionary class]]) {
    NSLog(@"error parsing json");
    return;
  }

  // now drop back to the main thread and do whatever with your dictionary
  dispatch_async(dispatch_get_main_queue(), ^{
    NSLog(@"%@", dict);
  });
});