zoukankan      html  css  js  c++  java
  • IOS解析JSON

    JSON建构有两种结构:
    json简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组2种结构,通过这两种结构可以表示各种复杂的结构
    1、对象:对象在js中表示为“{}”扩起来的内容,数据结构为 {key:value,key:value,...}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为 对象.key 获取属性值,这个属性值的类型可以是 数字、字符串、数组、对象几种。
    2、数组:数组在js中是中括号“[]”扩起来的内容,数据结构为 ["java","javascript","vb",...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种。
    经过对象、数组2种结构就可以组合成复杂的数据结构了。
     

    常用的方法,有下面几个:

    - (id)objectFromJSONString; - (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags; - (id)objectFromJSONData; - (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
    
    
    1 NSString *json = @"{"a":123, "b":"abc"}";
    NSString *json = @"{"a":123, "b":"abc"}";
      NSDictionary *data = [json objectFromJSONString];
      NSLog(@"json.a:%@", [data objectForKey:@"a"]);
      NSLog(@"json.b:%@", [data objectForKey:@"b"]);
      [json release];
    2 NSDictionary *data = [json objectFromJSONString];
    3 NSLog(@"json.a:%@", [data objectForKey:@"a"]);
    4 NSLog(@"json.b:%@", [data objectForKey:@"b"]);
    5 [json release];

    如果json有嵌套,即value里有array、object,如果再使用objectFromJSONString,程序可能会报错(我的测试结果:使用由网络得到的php/json_encode生成的json时报错,但使用NSString定义的json字符串时,解析成功),最好使用objectFromJSONStringWithParseOptions 
    NSString *json = @"{"a":123, "b":"abc", "c":[134, "hello"],
      "d":{"name":"张三","age":23}}";
      NSLog(@"json:%@", json);
      NSDictionary *data = [json objectFromJSONStringWithParseOptions:JKParseOptionLooseUnicode];
      NSLog(@"json.c:%@", [data objectForKey:@"c"]);
      NSLog(@"json.d:%@", [[data objectForKey:@"d"]objectForKey:@"name"]);
      [json release];
    1 NSString *json = @"{"a":123, "b":"abc", "c":[134, "hello"],
    2 "d":{"name":"张三","age":23}}";
    3 NSLog(@"json:%@", json);
    4 NSDictionary *data = [json objectFromJSONStringWithParseOptions:JKParseOptionLooseUnicode];
    5 NSLog(@"json.c:%@", [data objectForKey:@"c"]);
    6 NSLog(@"json.d:%@", [[data objectForKey:@"d"]objectForKey:@"name"]);
    7 [json release];


    结果:
    2012-07-09 18:48:07.255 Ate-Goods[17113:207] json.c:(
    134,
    hello
    )
    2012-07-09 18:48:07.256 Ate-Goods[17113:207] json.d:张三 
    从上面的写法可以看出,json与objece-c的数据对应关系如下:
    Number -> NSNumber
    String -> NSString
    Array -> NSArray
    Object -> NSDictionary
    另外:
    null -> NNSNull
    true and false -> NNSNumber 
     
     

    表示数组

    当需要表示一组值时,JSON 不但能够提高可读性,而且可以减少复杂性。例如,假设您希望表示一个人名列表。在 XML 中,需要许多开始标记和结束标记;如果使用典型的名称 / 值对(就像在本系列前面文章中看到的那种名称 / 值对),那么必须建立一种专有的数据格式,或者将键名称修改为 person1-firstName这样的形式。
    如果使用 JSON,就只需将多个带花括号的记录分组在一起:
    { "people": [
    { "firstName": "Brett", "lastName":"McLaughlin", "email": "aaaa" },
    { "firstName": "Jason", "lastName":"Hunter", "email": "bbbb"},
    { "firstName": "Elliotte", "lastName":"Harold", "email": "cccc" }
    ]}
    这不难理解。在这个示例中,只有一个名为 people的变量,值是包含三个条目的数组,每个条目是一个人的记录,其中包含名、姓和电子邮件地址。上面的示例演示如何用括号将记录组合成一个值。当然,可以使用相同的语法表示多个值(每个值包含多个记录):
    { "programmers": [
    { "firstName": "Brett", "lastName":"McLaughlin", "email": "aaaa" },
    { "firstName": "Jason", "lastName":"Hunter", "email": "bbbb" },
    { "firstName": "Elliotte", "lastName":"Harold", "email": "cccc" }
    ],
    "authors": [
    { "firstName": "Isaac", "lastName": "Asimov", "genre": "science fiction" },
    { "firstName": "Tad", "lastName": "Williams", "genre": "fantasy" },
    { "firstName": "Frank", "lastName": "Peretti", "genre": "christian fiction" }
    ],
    "musicians": [
    { "firstName": "Eric", "lastName": "Clapton", "instrument": "guitar" },
    { "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" }
    ] }
    这里最值得注意的是,能够表示多个值,每个值进而包含多个值。但是还应该注意,在不同的主条目(programmers、authors 和 musicians)之间,记录中实际的名称 / 值对可以不一样。JSON 是完全动态的,允许在 JSON 结构的中间改变表示数据的方式。
    在处理 JSON 格式的数据时,没有需要遵守的预定义的约束。所以,在同样的数据结构中,可以改变表示数据的方式,甚至可以以不同方式表示同一事物。
     
     
     

    作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式。

    有的json代码格式比较混乱,可以使用此“http://www.bejson.com/”网站来进行JSON格式化校验(点击打开链接)。此网站不仅可以检测Json代码中的错误,而且可以以视图形式显示json中的数据内容,很是方便。

    从IOS5开始,APPLE提供了对json的原生支持(NSJSONSerialization),但是为了兼容以前的ios版本,可以使用第三方库来解析Json。

    本文将介绍TouchJson、 SBJson 、JSONKit 和 iOS5所支持的原生的json方法,解析国家气象局API,TouchJson和SBJson需要下载他们的库

    TouchJson包下载: http://download.csdn.net/detail/enuola/4523169

    SBJson 包下载: http://download.csdn.net/detail/enuola/4523177

    JSONKit包下载:http://download.csdn.net/detail/enuola/4523160

    下面的完整程序源码包下载:http://download.csdn.net/detail/enuola/4523223

    PS:

    国家气象局提供的天气预报接口

    接口地址有三个:

    http://www.weather.com.cn/data/sk/101010100.html

    http://www.weather.com.cn/data/cityinfo/101010100.html

    http://m.weather.com.cn/data/101010100.html

    第三接口信息较为详细,提供的是6天的天气,关于API所返回的信息请见开源免费天气预报接口API以及全国所有地区代码!!(国家气象局提供),全国各城市对应这一个id号,根据改变id好我们就可以解析出来各个城市对应天气;

    下面介绍四种方法解析JSON:

    首先建立一个新的工程,(注意不要选择ARC机制)添加如下控件:

    如上图所示。下面展出程序代码:

    文件 ViewController.h 中:

    1. #import <UIKit/UIKit.h>
    2. @interface ViewController : UIViewController
    3. @property (retain, nonatomic) IBOutlet UITextView *txtView;
    4. - (IBAction)btnPressTouchJson:(id)sender;
    5. - (IBAction)btnPressSBJson:(id)sender;
    6. - (IBAction)btnPressIOS5Json:(id)sender;
    7. - (IBAction)btnPressJsonKit:(id)sender;
    8. @end
    文件ViewController.m中主要代码:

    (1)使用TouchJSon解析方法:(需导入包:#import "TouchJson/JSON/CJSONDeserializer.h")

    1. //使用TouchJson来解析北京的天气
    2. - (IBAction)btnPressTouchJson:(id)sender {
    3. //获取API接口
    4. NSURL *url = [NSURL URLWithString:@"http://m.weather.com.cn/data/101010100.html"];
    5. //定义一个NSError对象,用于捕获错误信息
    6. NSError *error;
    7. NSString *jsonString = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
    8. NSLog(@"jsonString--->%@",jsonString);
    9. //将解析得到的内容存放字典中,编码格式为UTF8,防止取值的时候发生乱码
    10. NSDictionary *rootDic = [[CJSONDeserializer deserializer] deserialize:[jsonString dataUsingEncoding:NSUTF8StringEncoding] error:&error];
    11. //因为返回的Json文件有两层,去第二层内容放到字典中去
    12. NSDictionary *weatherInfo = [rootDic objectForKey:@"weatherinfo"];
    13. NSLog(@"weatherInfo--->%@",weatherInfo);
    14. //取值打印
    15. txtView.text = [NSString stringWithFormat:@"今天是 %@ %@ %@ 的天气状况是:%@ %@ ",[weatherInfo objectForKey:@"date_y"],[weatherInfo objectForKey:@"week"],[weatherInfo objectForKey:@"city"], [weatherInfo objectForKey:@"weather1"], [weatherInfo objectForKey:@"temp1"]];
    16. }
    (2)使用SBJson解析方法:(需导入包:#import "SBJson/SBJson.h")
    1. //使用SBJson解析南阳的天气
    2. - (IBAction)btnPressSBJson:(id)sender {
    3. NSURL *url = [NSURL URLWithString:@"http://m.weather.com.cn/data/101180701.html"];
    4. NSError *error = nil;
    5. NSString *jsonString = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
    6. SBJsonParser *parser = [[SBJsonParser alloc] init];
    7. NSDictionary *rootDic = [parser objectWithString:jsonString error:&error];
    8. NSDictionary *weatherInfo = [rootDic objectForKey:@"weatherinfo"];
    9. txtView.text = [NSString stringWithFormat:@"今天是 %@ %@ %@ 的天气状况是:%@ %@ ",[weatherInfo objectForKey:@"date_y"],[weatherInfo objectForKey:@"week"],[weatherInfo objectForKey:@"city"], [weatherInfo objectForKey:@"weather1"], [weatherInfo objectForKey:@"temp1"]];
    10. }
    (3)使用IOS5自带解析类NSJSONSerialization方法解析:(无需导入包,IOS5支持,低版本IOS不支持)
    1. - (IBAction)btnPressIOS5Json:(id)sender {
    2. NSError *error;
    3. //加载一个NSURL对象
    4. NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://m.weather.com.cn/data/101180601.html"]];
    5. //将请求的url数据放到NSData对象中
    6. NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    7. //IOS5自带解析类NSJSONSerialization从response中解析出数据放到字典中
    8. NSDictionary *weatherDic = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:&error];
    9. NSDictionary *weatherInfo = [weatherDic objectForKey:@"weatherinfo"];
    10. txtView.text = [NSString stringWithFormat:@"今天是 %@ %@ %@ 的天气状况是:%@ %@ ",[weatherInfo objectForKey:@"date_y"],[weatherInfo objectForKey:@"week"],[weatherInfo objectForKey:@"city"], [weatherInfo objectForKey:@"weather1"], [weatherInfo objectForKey:@"temp1"]];
    11. NSLog(@"weatherInfo字典里面的内容为--》%@", weatherDic );
    12. }
    (4)使用JSONKit的解析方法:(需导入包:#import "JSONKit/JSONKit.h")
    1. - (IBAction)btnPressJsonKit:(id)sender {
    2. //如果json是“单层”的,即value都是字符串、数字,可以使用objectFromJSONString
    3. NSString *json1 = @"{"a":123, "b":"abc"}";
    4. NSLog(@"json1:%@",json1);
    5. NSDictionary *data1 = [json1 objectFromJSONString];
    6. NSLog(@"json1.a:%@",[data1 objectForKey:@"a"]);
    7. NSLog(@"json1.b:%@",[data1 objectForKey:@"b"]);
    8. [json1 release];
    9. //如果json有嵌套,即value里有array、object,如果再使用objectFromJSONString,程序可能会报错(测试结果表明:使用由网络或得到的php/json_encode生成的json时会报错,但使用NSString定义的json字符串时,解析成功),最好使用objectFromJSONStringWithParseOptions:
    10. NSString *json2 = @"{"a":123, "b":"abc", "c":[456, "hello"], "d":{"name":"张三", "age":"32"}}";
    11. NSLog(@"json2:%@", json2);
    12. NSDictionary *data2 = [json2 objectFromJSONStringWithParseOptions:JKParseOptionLooseUnicode];
    13. NSLog(@"json2.c:%@", [data2 objectForKey:@"c"]);
    14. NSLog(@"json2.d:%@", [data2 objectForKey:@"d"]);
    15. [json2 release];
    16. }

    另外,由于iOS5新增了JSON解析的API,我们将其和其他五个开源的JSON解析库进行了解析速度的测试,下面是测试的结果。

    我们选择的测试对象包含下面的这几个框架,其中NSJSONSerialization是iOS5系统新增的JSON解析的API,需要iOS5的环境,如果您在更低的版本进行测试,应该屏蔽相应的代码调用。

    - [SBJSON (json-framework)](http://code.google.com/p/json-framework/)

    - [TouchJSON (from touchcode)](http://code.google.com/p/touchcode/)

    - [YAJL (objective-C bindings)](http://github.com/gabriel/yajl-objc)

    - [JSONKit](https://github.com/johnezang/JSONKit)

    - [NextiveJson](https://github.com/nextive/NextiveJson)

    -[NSJSONSerialization](http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40010946)

    我们选择了四个包含json格式的数据的文件进行测试。每一个文件进行100的解析动作,对解析的时间进行比较。

    .....

    测试的结果显示,系统的API的解析速度最快,我们在工程项目中选择使用,也是应用较为广泛的SBJSON的解析速度为倒数第二差,令我大跌眼镜。

    与系统API较为接近的应该是JSONKit。

    这里没有对API的开放接口和使用方式进行比较,若单纯基于以上解析速度的测试:

    1:iOS5应该选择系统的API进行

    2:不能使用系统API的应该选择JSONKit

  • 相关阅读:
    转场动画3-手势返回
    UITableViewCell的选中时的颜色设置
    git的使用
    MarkDown语法学习笔记
    移动作业
    移动开发音乐播放器
    python循环删除list中的元素
    Linux权限管理
    Linux用户和用户组
    数据库常用基础操作
  • 原文地址:https://www.cnblogs.com/Sucri/p/4642048.html
Copyright © 2011-2022 走看看