您的位置:首页 > 移动开发 > IOS开发

iOS 4种JSON数据解析方法详解

2013-04-17 22:01 721 查看
在网络中数据的传输很多格式都是JSON或是XML,之前的博文已经介绍过XML,这篇介绍JSON数据。

在对JSON数据进行解析过程中大致有四种方法可供选择,包括原生的NSJSONSerialization,TouchJson,JSONKit,SBJon;其中后三种方法都要导入第三方类库。(在使用第三方类库过程中,如果项目是支持ARC的话,而这些类库文件不支持ARC特性的话,就会遇到ARC问题保错,所以就要添加arc特性,即添加-fno-objc-arc就解决)

附:

TouchJson包下载: http://download.csdn.net/detail/enuola/4523169 SBJson 包下载: http://download.csdn.net/detail/enuola/4523177 JSONKit包下载:https://github.com/TouchCode/TouchJSON


一、原生的NSJSONSerialization用法详解。

You use the NSJSONSerialization class to convert JSON to Foundation objects and convert Foundation objects to JSON.
An object that may be converted to JSON must have the following properties://但是转换成JSON的对象必须具有如下属性:
The top level object is an NSArray or NSDictionary.//顶层对象必须是NSArray或者NSDictionary

All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull.//所有的对象必须是NSString、NSNumber、NSArray、NSDictionary、NSNull的实例

All dictionary keys are instances of NSString.//所有NSDictionary的key必须是NSString类型

Numbers are not NaN or infinity.//数字对象不能是非数值或无穷

Other rules may apply. Calling isValidJSONObject: or attempting a conversion are the definitive ways to tell if a given object can be converted to JSON data.

这是NSJSONSerialization官方文档的开头一段话,介绍的是NSJSONSerialization可以将JSON对象转换成Foundation对象,也可以将Foundation对象转换成JSON对象。但是将Foundation对象转换成JSON对象时就有了上面的要求了。要注意的是The
top level object is an NSArray or NSDictionary。


这个类对应的方法有:

Creating a JSON Object
+ JSONObjectWithData:options:error:
+ JSONObjectWithStream:options:error:
Creating JSON Data
+ dataWithJSONObject:options:error:
+ writeJSONObject:toStream:options:error:
+ isValidJSONObject:
其中红色标记的方法是常用的方法,下面分别贴出其用法,注意每个方法使用过程中的参数类型。
Returns a Foundation object from given JSON data.
+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error
其中的NSJSONReadingOptions包括:
NSJSONReadingMutableContainers
Specifies that arrays and dictionaries are created as mutable objects.
NSJSONReadingMutableLeaves
Specifies that leaf strings in the JSON object graph are created as instances of NSMutableString.
NSJSONReadingAllowFragments
Specifies that the parser should allow top-level objects that are not an instance of NSArray or NSDictionary.
Returns a Boolean value that indicates whether a given object can be converted to JSON data.
+ (BOOL)isValidJSONObject:(id)obj
Returns JSON data from a Foundation object.
+ (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error
其中NSJSONWritingOptions包括

NSJSONWritingPrettyPrinted
Specifies that the JSON data should be generated with whitespace designed to make the output more readable. If this option is not set, the most compact possible JSON representation is generated.


下面通过一个简单的程序例子展示一下这个过程。

NSDictionary *jsonDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"value1",@"key1",@"value2",@"key2", nil];
NSError *error;
NSData *jsonData;
if ([NSJSONSerialization isValidJSONObject:jsonDictionary]) {
NSLog(@"yes");
jsonData = [NSJSONSerialization dataWithJSONObject:jsonDictionary options:NSJSONWritingPrettyPrinted error:&error];
}
else {
NSLog(@"error :%@",error.localizedDescription);
}
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:&error];
NSLog(@"key1: %@",[dictionary objectForKey:@"key1"]);
二、JSONKit用法详解

(个人目前用到较多的是使用JSONKit来对json格式的字符串进行解析)

使用JSONKit需要在项目中导入JSONKit类库文件,可以从上面的链接中下载。

使用JSONKit对数据解析过程中常用的方法(都是实例方法)就是:

- (id)objectFromJSONString;
- (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
- (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
- (id)mutableObjectFromJSONString;
- (id)mutableObjectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
- (id)mutableObjectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;

- (id)objectFromJSONData;
- (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
- (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
- (id)mutableObjectFromJSONData;
- (id)mutableObjectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags;
- (id)mutableObjectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error;
常用的分别是前三个。
其中的JKParseOptionFlags包括:

  JKSerializeOptionNone                 = 0,

  JKSerializeOptionPretty               = (1 << 0),

  JKSerializeOptionEscapeUnicode        = (1 << 1),

  JKSerializeOptionEscapeForwardSlashes = (1 << 4),

  JKSerializeOptionValidFlags           = (JKSerializeOptionPretty | JKSerializeOptionEscapeUnicode | JKSerializeOptionEscapeForwardSlashes),

下面代码实例演示解析字符串JSON格式:

NSString *jsonString =@"[{\"precision\": \"zip\",\"Latitude\":  37.7668,\"Longitude\": -122.3959,\"Address\":   \"\",\"City\":      \"SAN FRANCISCO\",\"State\":     \"CA\",\"Zip\":       \"94107\",\"Country\":   \"US\"},{\"precision\": \"zip\",\"Latitude\":  37.371991,\"Longitude\": -122.026020,\"Address\":   \"\",\"City\":      \"SUNNYVALE\",\"State\":     \"CA\",\"Zip\":       \"94085\",\"Country\":   \"US\"}]";
NSArray *jsonArray = [jsonString objectFromJSONString];
for(NSDictionary *dictionary in jsonArray) {
NSLog(@"City :%@",[dictionary objectForKey:@"City"]);
}
其中的jsonString是如下内容(有两个dictionary,所以我们可以用一个数组来装载,然后再用字典来分别装载里面内容):

[
{
\"precision\": \"zip\",
\"Latitude\": 37.7668,
\"Longitude\": -122.3959,
\"Address\": \"\",
\"City\": \"SANFRANCISCO\",
\"State\": \"CA\",
\"Zip\": \"94107\",
\"Country\": \"US\"
},
{
\"precision\": \"zip\",
\"Latitude\": 37.371991,
\"Longitude\": -122.026020,
\"Address\": \"\",
\"City\": \"SUNNYVALE\",
\"State\": \"CA\",
\"Zip\": \"94085\",
\"Country\": \"US\"
}
]


三、TouchJson用法详解

首先根据上面给出的下载链接下载这个库,解压后在项目导入Source文件夹。使用时要如下import相关文件。

#import "Source/JSON/CJSONDeserializer.h"
#import "Source/JSON/CJSONSerializer.h"
提示:如果是ARC项目,在target中关于TouchJson的所有文件请添加arc:-fno-objc-arc。

由上面的import的语句可知,使用这个库,既可以反序列化操作,即将JSON数据转换成其他对象,也可以序列化操作,即将某个对象转换成JSON数据。

1、下面看看序列化操作对应的方法吧!在CJSONSerializer.h文件中可以找到。

+ (CJSONSerializer *)serializer;
- (BOOL)isValidJSONObject:(id)inObject;
/// Take any JSON compatible object (generally NSNull, NSNumber, NSString, NSArray and NSDictionary) and produce an NSData containing the serialized JSON.
- (NSData *)serializeObject:(id)inObject error:(NSError **)outError;
- (NSData *)serializeNull:(NSNull *)inNull error:(NSError **)outError;
- (NSData *)serializeNumber:(NSNumber *)inNumber error:(NSError **)outError;
- (NSData *)serializeString:(NSString *)inString error:(NSError **)outError;
- (NSData *)serializeArray:(NSArray *)inArray error:(NSError **)outError;
- (NSData *)serializeDictionary:(NSDictionary *)inDictionary error:(NSError **)outError;
上面的方法中常用的是前三个,而且注意:Take any JSON compatible object (generally NSNull, NSNumber, NSString, NSArray and NSDictionary) and produce an NSData containing the serialized JSON.下面看看实例代码吧!

NSError *error;
NSString *jsonString =@"{\"key1\":{\"precision\": \"zip\",\"Latitude\":  37.7668,\"Longitude\": -122.3959,\"Address\":   \"\",\"City\":      \"SAN FRANCISCO\",\"State\":     \"CA\",\"Zip\":       \"94107\",\"Country\":   \"US\"},\"key2\":{\"precision\": \"zip\",\"Latitude\":  37.371991,\"Longitude\": -122.026020,\"Address\":   \"\",\"City\":      \"SUNNYVALE\",\"State\":     \"CA\",\"Zip\":       \"94085\",\"Country\":   \"US\"}}";

CJSONSerializer *serial = [CJSONSerializer serializer];  //creat an object of CJSONSerializer
if ([serial isValidJSONObject:jsonString]) {
NSLog(@"yes");
NSData *jsonData = [serial serializeString:jsonString error:&error];
}
}


2、接着就是反序列化操作(通常说的数据解析),在CJSONDeserializer.h文件中我们可看到相应的方法。

+ (CJSONDeserializer *)deserializer;
- (id)deserialize:(NSData *)inData error:(NSError **)outError;
- (id)deserializeAsDictionary:(NSData *)inData error:(NSError **)outError;
- (id)deserializeAsArray:(NSData *)inData error:(NSError **)outError;
都比较容易理解,常用的还是前两个。看看实例代码吧!

NSString *jsonString =@"{\"key1\":{\"precision\": \"zip\",\"Latitude\":  37.7668,\"Longitude\": -122.3959,\"Address\":   \"\",\"City\":      \"SAN FRANCISCO\",\"State\":     \"CA\",\"Zip\":       \"94107\",\"Country\":   \"US\"},\"key2\":{\"precision\": \"zip\",\"Latitude\":  37.371991,\"Longitude\": -122.026020,\"Address\":   \"\",\"City\":      \"SUNNYVALE\",\"State\":     \"CA\",\"Zip\":       \"94085\",\"Country\":   \"US\"}}";
NSError *error;
NSArray *array = [[CJSONDeserializer deserializer] deserialize:[jsonString dataUsingEncoding:NSUTF8StringEncoding] error:&error];
for(NSDictionary *dic in array) {
NSLog(@"City :%@",[dic objectForKey:@"City"]);
}
上面是将一个json字符串编码成jsona格式,然后对其进行解析也即反序列化。

四、SBJson用法详解

在使用SBJson对数据进行解析时,要导入相应的文件,并#import "SBJson/SBJsonParser.h",主要使用的方法有:

- (id)objectWithData:(NSData*)data;
- (id)objectWithString:(NSString *)repr;
- (id)objectWithString:(NSString*)jsonText
error:(NSError**)error;


下面实例演示如何使用SBJson对数据进行解析。

NSString *jsonString =@"{\"key1\":{\"precision\": \"zip\",\"Latitude\":  37.7668,\"Longitude\": -122.3959,\"Address\":   \"\",\"City\":      \"SAN FRANCISCO\",\"State\":     \"CA\",\"Zip\":       \"94107\",\"Country\":   \"US\"},\"key2\":{\"precision\": \"zip\",\"Latitude\":  37.371991,\"Longitude\": -122.026020,\"Address\":   \"\",\"City\":      \"SUNNYVALE\",\"State\":     \"CA\",\"Zip\":       \"94085\",\"Country\":   \"US\"}}";
NSError *error;
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSDictionary *dictionary= [parser objectWithString:jsonString error:&error];
NSLog(@"%@",dictionary);
NSLog(@"%@",[[dictionary objectForKey:@"key1"] objectForKey:@"City"]);


解释一下,这里的jsonString和前面使用的有一点区别,待会看输出就知道了(为两个dictionary添加了key1和key2)。

首先要创建一个SBJsonParser对象,然后调用方法进行解析。

{
key1 =     {
Address = "";
City = "SAN FRANCISCO";
Country = US;
Latitude = "37.7668";
Longitude = "-122.3959";
State = CA;
Zip = 94107;
precision = zip;
};
key2 =     {
Address = "";
City = SUNNYVALE;
Country = US;
Latitude = "37.371991";
Longitude = "-122.02602";
State = CA;
Zip = 94085;
precision = zip;
};
}


有测试结果显示,系统原生的API的解析速度最快,所以在项目工程中应该作为首选,而其中的SBJson解析速度较差,与原生API较为接近的是JSONKit。

结束介绍!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: