在網路中資料的傳輸很多格式都是JSON或是XML,之前的博文已經介紹過XML,這篇介紹JSON資料。
在對JSON資料進行解析過程中大致有四種方法可供選擇,包括原生的NSJSONSerialization,TouchJson,JSONKit,SBJon;其中後三種方法都要匯入第三方類庫。(在使用第三方類庫過程中,如果項目是支援ARC的話,而這些類庫檔案不支援ARC特性的話,就會遇到ARC問題保錯,所以就要添加arc特性,即添加-fno-objc-arc就解決)
附:
TouchJson包下載: http://download.csdn.net/detail/enuola/4523169SBJson 包下載: http://download.csdn.net/detail/enuola/4523177JSONKit包下載: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包括:
NSJSONReadingMutableContainersSpecifies that arrays and dictionaries are created as mutable objects.NSJSONReadingMutableLeavesSpecifies that leaf strings in the JSON object graph are created as instances of NSMutableString.NSJSONReadingAllowFragmentsSpecifies 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包括
NSJSONWritingPrettyPrintedSpecifies 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。
結束介紹!