iOS中NSJSONSerialization解析JSON数据暨google地理信息处理案例

在iOS开发中,涉及到从网络取得json格式的数据处理工作时,我们会想到很多开源的第三方包,如SBJSON。在iOS5开始,也增加了对json格式数据的处理能力,增加的类是NSJSONSerialization。
使用NSJSONSerialization,可以分析各种复杂格式json数据。
使用的类方法是+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error。
根据不同data的结构,设置不同的option。这里option有三类:NSJSONReadingMutableContainers, NSJSONReadingMutableLeaves , NSJSONReadingAllowFragments。
apple文档对这三种方法做了说明。
1、NSJSONReadingMutableContainers
Specifies that arrays and dictionaries are created as mutable objects.
2、NSJSONReadingMutableLeaves
Specifies that leaf strings in the JSON object graph are created as instances of NSMutableString.
3、NSJSONReadingAllowFragments
Specifies that the parser should allow top-level objects that are not an instance of NSArray or NSDictionary.
Available in iOS 5.0 and later.

我就http://maps.googleapis.com/maps/api/geocode/json?address=nanjing&sensor=true这个链接做了测试。这是google的地理信息api,根据地点得到经纬度等信息。

这个url得到的json格式的结果如下所示:

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "南京",
               "short_name" : "南京",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "江苏省",
               "short_name" : "江苏省",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "中国",
               "short_name" : "CN",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "中国江苏省南京市",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 32.61436330,
                  "lng" : 119.23624250
               },
               "southwest" : {
                  "lat" : 31.22809770,
                  "lng" : 118.36337310
               }
            },
            "location" : {
               "lat" : 32.0602550,
               "lng" : 118.7968770
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 32.39401350,
                  "lng" : 119.0501690
               },
               "southwest" : {
                  "lat" : 31.80452470,
                  "lng" : 118.42533230
               }
            }
         },
         "types" : [ "locality", "political" ]
      }
   ],
   "status" : "OK"
}

这是一个复杂的json格式,json中包含了数组,数组中有包含了若干级的json数据。

先将URL转码为UTF8,基于它创建一个NSMutableURLRequest,再使用NSURLConnection的sendAsynchronousRequest的方法,将response数据放到block中分析,分析方法就是NSJSONSerialization的类方法+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error。
它的分析步骤如下:
第一步,根据json数据结构得到字典
NSDictionary *resultsDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
第二步,根据字典中组成,得到key为@"results"对应的对象是数组。
NSArray *resultsArr = [resultsDic objectForKey:@"results"];
第三步,使用for循环遍历这个数组
for (NSDictionary * resultDetailDic in resultsArr)
{
    NSDictionary * locationDic=[[resultDetailDic objectForKey:@"geometry"] objectForKey:@"location"];
    NSString * lat=[locationDic objectForKey:@"lat"];
    NSString * lng=[locationDic objectForKey:@"lng"];
    
    dispatch_async(dispatch_get_main_queue(), ^{
    NSLog(@"locationDic.lat 是--->%@\n",lat);
                        NSLog(@"locationDic.lng 是--->%@\n",lng);
    });// dispatch async main                               
}
第四步,根据for循环遍历的结果,得到每一个元素都是一个字典。
NSDictionary * locationDic=[[resultDetailDic objectForKey:@"geometry"] objectForKey:@"location"];

第五步,根据字典信息,得到每一个key对应的对象是一个字符串
这个字符串就是我们最终要的数据。

如果觉得这种数据分析对数据结构关联太密切,谓之曰不够强壮,你可以做一些isKindOfClass判断。

全部代码如下:
-(void)parseJson:(NSString *)addr
{    
    //The URL of JSON service    
    NSString *_urlString = @"http://maps.googleapis.com/maps/api/geocode/json?address=nanjing&sensor=true";    
    NSString *_dataString = [[NSString alloc] initWithData:[_urlString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES] encoding:NSASCIIStringEncoding];
    
    //_dataString=[NSString stringWithUTF8String:[_urlString UTF8String]];
    
    NSURL *_url = [NSURL URLWithString:_dataString];
    NSMutableURLRequest *_request = [NSMutableURLRequest requestWithURL:_url];
    [_request setValue:@"accept" forHTTPHeaderField:@"application/json"];
    [NSURLConnection sendAsynchronousRequest:_request
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse* response, NSData* data, NSError* error) {
                               //block define statment
                               NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
                               
                               int responseStatusCode = [httpResponse statusCode];
                               NSLog(@"response status code is %d",responseStatusCode);
                               
                               NSError *_errorJson = nil;
                               
                               NSDictionary *resultsDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];

                               if (_errorJson != nil) {
                                   NSLog(@"Error %@", [_errorJson localizedDescription]);
                               } else {                               
                                    NSString *resultStatus = [resultsDic objectForKey:@"status"];

                                    if ([resultStatus isEqualString:@"OK"])
                                        {
                                        NSArray *resultsArr = [resultsDic objectForKey:@"results"];
                               
                                        //Do something with returned array
                                        for (NSDictionary * resultDetailDic in resultsArr)
                                        {
                                            NSDictionary * locationDic=[[resultDetailDic objectForKey:@"geometry"] objectForKey:@"location"];
                                            NSString * lat=[locationDic objectForKey:@"lat"];
                                            NSString * lng=[locationDic objectForKey:@"lng"];
                                            
                                            dispatch_async(dispatch_get_main_queue(), ^{
                                            NSLog(@"locationDic.lat 是--->%@\n",lat);
                                            NSLog(@"locationDic.lng 是--->%@\n",lng);
                                            });// dispatch async main                               
                                       }
                               }
                               }
                           }];
}



通过这段代码,我们可以实现异步读取,json格式数据分析。这些操作都不需要调用任何第三方代码,仅仅使用了apple自身提供的功能。这样做的好处,便于维护和升级。


相关推荐

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

miki西游

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值