iOS - JSON 數據解析


前言

	NS_CLASS_AVAILABLE(10_7, 5_0) @interface NSJSONSerialization : NSObject
	@available(iOS 5.0, *)		   public class NSJSONSerialization : NSObject

1、JSON 數據

  • JSON(JavaScript Object Notation)是一種輕量級的數據交換格式。它基於 ECMAScript 的一個子集。JSON 采用完全獨立於語言的文本格式,但是也使用了類似於 C 語言家族的習慣(包括 C、C++、 C#、Java、JavaScript、Perl、Python 等)。這些特性使 JSON 成為理想的數據交換語言。易於人閱讀和編寫,同時也易於機器解析和生成(一般用於提升網絡傳輸速率)。

1.1 JSON 語法規則

  • JSON 語法是 JavaScript 對象表示語法的子集。
    • 數據在鍵值對中
    • 數據由逗號分隔
    • 花括號保存對象
    • 方括號保存數組

1.2 JSON 基礎結構

  • JSON 結構有兩種,JSON 簡單說就是 javascript 中的對象和數組,所以這兩種結構就是對象和數組兩種結構,通過這兩種結構可以表示各種復雜的結構。

    • 1、對象:對象在 JSON 中表示為 “{}” 括起來的內容,數據結構為 {key:value, key:value, ...} 的鍵值對的結構,在面向對象的語言中,key 為對象的屬性,value 為對應的屬性值,所以很容易理解,取值方法為 對象[key] 獲取屬性值,這個屬性值的類型可以是數字、字符串、數組、對象幾種。
    • 2、數組:數組在 JSON 中表示為 “[]” 括起來的內容,數據結構為 ["java", "javascript", "vb", ...],取值方式和所有語言中一樣,使用索引獲取。字段值的類型可以是 數字、字符串、數組、對象幾種。

1.3 JSON 名稱/值對

  • JSON 數據的書寫格式是:名稱/值對。
  • 名稱/值對組合中的名稱寫在前面(在雙引號中),值對寫在后面(同樣在雙引號中),中間用冒號隔開:"firstName":"John"

1.4 JSON 值

  • JSON 值可以是:
    • 數字(整數或浮點數)
    • 字符串(在雙引號中)
    • 邏輯值(true 或 false)
    • 數組(在方括號中)
    • 對象(在花括號中)
    • null

1.5 JSON 基礎示例

  • 簡單地說,JSON 可以將 JavaScript 對象中表示的一組數據轉換為字符串,然后就可以在函數之間輕松地傳遞這個字符串,或者在異步應用程序中將字符串從 Web 客戶機傳遞給服務器端程序。這個字符串看起來有點兒古怪,但是 JavaScript 很容易解釋它,而且 JSON 可以表示比 "名稱/值對" 更復雜的結構。例如,可以表示數組和復雜的對象,而不僅僅是鍵和值的簡單列表。

  • 1、表示名稱/值對:

    • 按照最簡單的形式,可以用下面這樣的 JSON 表示 "名稱/值對":

      {"firstName":"Brett"}
      
    • 這個示例非常基本,而且實際上比等效的純文本 "名稱/值對" 占用更多的空間:

      	firstName=Brett
      
    • 但是,當將多個 "名稱/值對" 串在一起時,JSON 就會體現出它的價值了。首先,可以創建包含多個 "名稱/值對" 的記錄,比如:

      	{"firstName":"Brett", "lastName":"McLaughlin", "email":"aaaa"}
      
    • 從語法方面來看,這與 "名稱/值對" 相比並沒有很大的優勢,但是在這種情況下 JSON 更容易使用,而且可讀性更好。例如,它明確地表示以上三個值都是同一記錄的一部分;花括號使這些值有了某種聯系。

  • 2、表示數組

    • 當需要表示一組值時,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": "sciencefiction"},
                    	{"firstName": "Tad", "lastName": "Williams", "genre": "fantasy"},
                    	{"firstName": "Frank", "lastName": "Peretti", "genre": "christianfiction"
                    	}
                    	],
      
          	"musicians":[
                      	{"firstName": "Eric", "lastName": "Clapton", "instrument": "guitar"},
                       	{"firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano"
                       	}
                       	]
      	}
      
    • 這里最值得注意的是,能夠表示多個值,每個值進而包含多個值。但是還應該注意,在不同的主條目(programmers、authors 和 musicians)之間,記錄中實際的 "名稱/值對" 可以不一樣。JSON 是完全動態的,允許在 JSON 結構的中間改變表示數據的方式。在處理 JSON 格式的數據時,沒有需要遵守的預定義的約束。所以,在同樣的數據結構中,可以改變表示數據的方式,甚至可以以不同方式表示同一事物。

1.6 JSON 具體形式

  • 1、對象是一個無序的 “名稱/值對” 集合

    • 1)一個對象以 “{” 左括號開始,“}” 右括號結束。

    • 2)每個 “名稱” 后跟一個 “:” 冒號;

    • 3)“名稱/值對” 之間使用 “,” 逗號分隔。

    • 例子:表示人的一個對象:

      	{
          	"姓名":"大憨",
          	"年齡":24
      	}
      
  • 2、數組是值(value)的有序集合

    • 1)一個數組以 “[” 左中括號開始,“]” 右中括號結束。

    • 2)值之間使用 “,” 逗號分隔。

    • 例子:一組學生

      	{
          	"學生": [{"姓名":"小明","年齡":23}, {"姓名":"大憨","年齡":24}]
      	}
      	
      	說明:此 Json 對象包括了一個學生數組,而學生數組中的值又是兩個 Json 對象。
      
  • 3、值(value)可以是雙引號括起來的字符串(string)、數值(number)、true、false、 null、對象(object)或者數組(array)。這些結構可以嵌套。

  • 4、字符串(string)是由雙引號包圍的任意數量 Unicode 字符的集合,使用反斜線轉義。一個字符(character)即一個單獨的字符串(character string)。 字符串(string)與 C 或者 Java 的字符串非常相似。

  • 5、數值(number)也與 C 或者 Java 的數值非常相似。除去未曾使用的八進制與十六進制格式。除去一些編碼細節。

1.7 JSON 和 XML 的比較

  • 可讀性

    • JSON 和 XML 的可讀性可謂不相上下,一邊是簡易的語法,一邊是規范的標簽形式,很難分出勝負。
  • 可擴展性

    • XML 天生有很好的擴展性,JSON 當然也有,沒有什么是 XML 可以擴展而 JSON 卻不能擴展的。不過 JSON 在 Javascript 主場作戰,可以存儲 Javascript 復合對象,有着 XML 不可比擬的優勢。
  • 編碼難度

    • XML 有豐富的編碼工具,比如 Dom4j、JDom 等,JSON 也有提供的工具。無工具的情況下,相信熟練的開發人員一樣能很快的寫出想要的 XML 文檔和 JSON 字符串,不過,XML 文檔要多很多結構上的字符。
  • 解碼難度

    • XML 的解析方式有兩種:

      • 一是通過文檔模型解析,也就是通過父標簽索引出一組標記。例如:xmlData.getElementsByTagName("tagName"),但是這樣是要在預先知道文檔結構的情況下使用,無法進行通用的封裝。
      • 另外一種方法是遍歷節點(document 以及 childNodes)。這個可以通過遞歸來實現,不過解析出來的數據仍舊是形式各異,往往也不能滿足預先的要求。
      • 凡是這樣可擴展的結構數據解析起來一定都很困難。
    • JSON 也同樣如此:

      • 如果預先知道 JSON 結構的情況下,使用 JSON進 行數據傳遞簡直是太美妙了,可以寫出很實用美觀可讀性強的代碼。如果你是純粹的前台開發人員,一定會非常喜歡 JSON。但是如果你是一個應用開發人員,就不是那么喜歡了,畢竟 XML 才是真正的結構化標記語言,用於進行數據傳遞。
      • 而如果不知道 JSON 的結構而去解析 JSON 的話,那簡直是噩夢。費時費力不說,代碼也會變得冗余拖沓,得到的結果也不盡人意。但是這樣也不影響眾多前台開發人員選擇 JSON。因為 json.js 中的 toJSONString() 就可以看到 JSON 的字符串結構。當然不是使用這個字符串,這樣仍舊是噩夢。常用 JSON 的人看到這個字符串之后,就對 JSON 的結構很明了了,就更容易的操作 JSON。
    • 以上是在 Javascript 中僅對於數據傳遞的 XML 與 JSON 的解析。在 Javascript 地盤內,JSON 畢竟是主場作戰,其優勢當然要遠遠優越於 XML。如果 JSON 中存儲 Javascript 復合對象,而且不知道其結構的話,我相信很多程序員也一樣是哭着解析 JSON 的。

    • 除了上述之外,JSON 和 XML 還有另外一個很大的區別在於有效數據率。JSON 作為數據包格式傳輸的時候具有更高的效率,這是因為 JSON 不像 XML 那樣需要有嚴格的閉合標簽,這就讓有效數據量與總數據包比大大提升,從而減少同等數據流量的情況下,網絡的傳輸壓力 。

1.8 iOS JSON 解析第三方框架

  • JSON 解析常用的第三方框架有:JSONKit、SBJson、TouchJSON,其性從左到右依次降低。

  • JSONKit 已經在 2012 年停止更新,官方說 JSONKit 比蘋果原生的 NSJSONSerialization 解析速度快,實測其實蘋果原生的 NSJSONSerialization 解析速度更快。

  • 由於 NSJSONSerialization 在 iOS 5.0 之后才出現,NSJSONSerialization 適用於 iOS 5.0+ 版本的 iOS 開發。JSONKit 框架適用於 iOS 4.0 及以前版本的 iOS 開發。

2、系統方式 JSON 數據解析

  • Objective-C

    • 解析 json 數據

      	/*
          	反序列化:將從服務器接收到的二進制數據轉換成 NSDictionary / NSArray 的過程,簡化程序開發,便於后續的字典轉模型。
          	數據必須符合 json 格式,用來接收的容器必須和 json 的最外層保持一致。
       
          	NSJSONReadingMutableContainers  = (1UL << 0),  // 容器可變,NSMutableDictionary 或 NSMutableArray。
          	NSJSONReadingMutableLeaves      = (1UL << 1),  // 葉子可變,返回的 JSON 對象中字符串的值為 NSMutableString。
          	NSJSONReadingAllowFragments     = (1UL << 2)   // 允許 JSON 字符串最外層既不是 NSArray 也不是 NSDictionary,
          	                                                  但必須是有效的 JSON 片段
       
          		反序列化中的可變不可變,實際用處不大,后續緊接着就是字典轉模型。因此輸入 0 效率最好。如果今后看到 ** 類型的參數,
          	又不想獲取對應的內容,傳遞 NULL 即可。傳入 nil 不會抱錯。
       	*/
      
      	// 從本地文件中讀取數據
      	NSData *jsonData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"JsonDataFile" ofType:@"txt"]];
      
      	// 解析 json 數據
      	id result = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:NULL];
      
    • 生成 json 數據

      	/*
          	序列化:將字典或者數組發送給服務器之前,轉換成二進制數據,方便網絡傳輸。
      
          	生成 json 數據的對象必須滿足以下條件:
              	對象最外層必須是 NSArray 或者 NSDictionary。
              	容器內的所有數據必須是 NSString, NSNumber, NSArray, NSDictionary, 或者 NSNull 類型。
              	字典的所有 key 都是 NSString 格式。
              	NSNumber 不能是 NaN(非數值) 或者 infinity(無限大)。
       
          	NSJSONWritingOptions:
              	NSJSONWritingPrettyPrinted = (1UL << 0)             漂亮的格式打印
       
              	使用 0 時,生成的數據格式如下,將 JSON 數據發送給服務器時可以使用該種格式。
       
                 	{"age":8,"score":99,"add":"beijing","name":"xiaoxin"}
       
              	使用 1 時,生成的數據格式如下,將 JSON 數據保存到本地時可以使用該種格式。
       
                 	{
                     	"age" : 8,
                     	"score" : 99,
                     	"add" : "beijing",
                     	"name" : "xiaoxin"
                 	}
      	*/
      
      	// Foundation object
      	NSDictionary *dicitionary = @{@"name":@"xiaoxin", @"age":@8, @"score":@99, @"add":@"beijing"};
      
      	// 判斷 Foundation 對象是否可以生成 json 數據
      	BOOL isValid = [NSJSONSerialization isValidJSONObject:dicitionary];
         	
      	// 生成 json 數據
      	NSData *jData = [NSJSONSerialization dataWithJSONObject:dicitionary options:0 error:NULL];
      
  • Swift

    • 解析 json 數據

      	/*
          	反序列化:將從服務器接收到的二進制數據轉換成 NSDictionary / NSArray 的過程,簡化程序開發,便於后續的字典轉模型。
          	數據必須符合 json 格式,用來接收的容器必須和 json 的最外層保持一致。
       
          	MutableContainers  // 容器可變,NSMutableDictionary 或 NSMutableArray。
          	MutableLeaves      // 葉子可變,返回的 JSON 對象中字符串的值為 NSMutableString。
          	AllowFragments     // 允許 JSON 字符串最外層既不是 NSArray 也不是 NSDictionary,但必須是有效的 JSON 片段
       
          		反序列化中的可變不可變,實際用處不大,后續緊接着就是字典轉模型。因此輸入 0 效率最好。如果今后看到 ** 類型的參數,
          	又不想獲取對應的內容,傳遞 NULL 即可。傳入 nil 不會抱錯。
       	*/
      
      	// 解析 json 數據
      	let jsonDataDic: AnyObject? = try? NSJSONSerialization.JSONObjectWithData(jsonData!, options: .MutableContainers)
      
    • 生成 json 數據

      	/*
          	序列化:將字典或者數組發送給服務器之前,轉換成二進制數據,方便網絡傳輸。
      
          	生成 json 數據的對象必須滿足以下條件:
      
              	對象最外層必須是 NSArray 或者 NSDictionary。
              	容器內的所有數據必須是 NSString, NSNumber, NSArray, NSDictionary, 或者 NSNull 類型。
              	字典的所有 key 都是 NSString 格式。
              	NSNumber 不能是 NaN(非數值) 或者 infinity(無限大)。
       	*/
      
      	// Foundation object
      	let dicitionary:[String:AnyObject] = ["name":"xiaoxin", "age":8, "score":99, "add":"beijing"]
      
      	// 判斷 Foundation 對象是否可以生成 json 數據
      	let isValid:Bool = NSJSONSerialization.isValidJSONObject(dicitionary)
         	
      	// 生成 json 數據
      	let jData:NSData? = try? NSJSONSerialization.dataWithJSONObject(dicitionary, options: .PrettyPrinted)
      

3、JSONKit 方式 JSON 數據解析

3.1 添加 JSONKit

  • GitHub 網址:https://github.com/johnezang/JSONKit

  • JSONKit 使用 MRC

  • Objective-C

    	// 添加第三方庫文件
    	JSONKit
    
    	// 在 TARGETS -> Build Phases -> Compile Sources -> ...in .../JSONKit 后添加
    	-fno-objc-arc
    
    	// 包含頭文件
    	#import "JSONKit.h"
    
  • Swift

    	// 添加第三方庫文件
    	JSONKit
     
    	// 在 TARGETS -> Build Phases -> Compile Sources -> ...in .../JSONKit 后添加
    	-fno-objc-arc
    
    	// 創建名為 “項目名-Bridging-Header.h” 的橋接頭文件,如:
    	SwiftJSON-Bridging-Header.h
     
    	// 在 TARGETS -> Build Setting -> Swift Compiler - Code generation -> Objective-C Bridging Header 中
    	// 添加 “項目名/項目名-Bridging-Header.h” 路徑,如:
    	SwiftJSON/SwiftJSON-Bridging-Header.h
     
    	// 在創建的橋接頭文件中包含頭文件
    	#import "JSONKit.h"
    

3.2 JSONKit 數據解析

  • Objective-C

    • JSONDecoder 方式解析

      	// 從本地文件中讀取數據
      	NSData *jsonData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"JsonDataFile" ofType:@"txt"]];
      
      	id result = [[JSONDecoder decoder] objectWithData:jsonData];
      
      	NSLog(@"%@ %@", result, [result class]);
      
    • JSONString 解析

      	// 單層 JSONString 解析
      	/*
      		如果 json 是 “單層” 的,即 value 都是字符串、數字,可以使用 objectFromJSONString
       	*/
       	
       		// 單層 JSONString 數據
      		NSString *jsonStr1 = @"{\"a\":123, \"b\":\"abc\"}";
      
          	// 返回可變結果使用 mutableObjectFromJSONString 方法
          	NSDictionary *jsonStrDic1 = [jsonStr1 objectFromJSONString];
          	
      	// 嵌套 JSONString 解析
      	/*
      			如果 json 有嵌套,即 value 里有 array、object,如果再使用 objectFromJSONString,程序可能會報錯,
      		測試結果表明:使用由網絡或得到的 php/json_encode 生成的 json 時會報錯,但使用 NSString 定義的 json 字符串時,
      		解析成功,最好使用 objectFromJSONStringWithParseOptions:
       	*/
      
      		// 嵌套 JSONString 數據
      		NSString *jsonStr2 = @"{\"a\":123, \"b\":\"abc\", \"c\":[456, \"hello\"], \"d\":{\"name\":\"張三\", \"age\":\"32\"}}";
         	
          	// 返回可變結果使用 mutableObjectFromJSONStringWithParseOptions 方法
          	NSDictionary *jsonStrDic2 = [jsonStr2 objectFromJSONStringWithParseOptions:JKParseOptionLooseUnicode];
      
    • JSONData 解析

      	// 單層 JSONData 解析
      
          	NSData *jsonData1 = [@"{\"a\":123, \"b\":\"abc\"}" dataUsingEncoding:NSUTF8StringEncoding];
      
      		// 返回可變結果使用 mutableObjectFromJSONData 方法
          	NSDictionary *jsonDataDic1 = [jsonData1 objectFromJSONData];
      
      	// 嵌套 JSONData 解析
      
      		// 從本地文件中讀取數據
          	NSData *jsonData2 = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"JsonDataFile" ofType:@"txt"]];
      
      		// 返回可變結果使用 mutableObjectFromJSONStringWithParseOptions 方法
          	NSDictionary *jsonDataDic2 = [jsonData2 objectFromJSONDataWithParseOptions:JKParseOptionLooseUnicode];
      
    • 生成 JSONString 數據

      	// NSString -> JSONString
      
          	NSString *str1 = @"{a\":123, \"b\":\"abc\"}";
      
      		// 默認參數為 JKSerializeOptionNone,includeQuotes 為 YES
          	NSString *jsonStrFromStr1 = [str1 JSONString];
      
      		// includeQuotes 為 NO 時,編碼后的數據最外層不含引號
          	NSString *jsonStrFromStr2 = [str1 JSONStringWithOptions:JKSerializeOptionNone includeQuotes:NO error:nil];
      
      	// NSArray/NSDictionary -> JSONString
      
          	NSDictionary *dic1 = @{@"name":@"xiaoxin", @"age":@8, @"Info":@{@"score":@99, @"add":@"beijing"}};
      
      		// 默認參數為 JKSerializeOptionNone
          	NSString *jsonStrFromDic1 = [dic1 JSONString];
      
          	NSString *jsonStrFromDic2 = [dic1 JSONStringWithOptions:JKSerializeOptionEscapeUnicode error:nil];
      
    • 生成 JSONData 數據

      	// NSString -> JSONData
      
          	NSString *str2 = @"{a\":123, \"b\":\"abc\"}";
          
          	// 默認參數為 JKSerializeOptionNone,includeQuotes 為 YES
          	NSData *jsonDataFromStr1 = [str2 JSONData];
          
          	NSData *jsonDataFromStr2 = [str2 JSONDataWithOptions:JKSerializeOptionNone includeQuotes:NO error:nil];
         	
      	// NSArray/NSDictionary -> JSONData
      
          	NSDictionary *dic2 = @{@"name":@"xiaoxin", @"age":@8, @"Info":@{@"score":@99, @"add":@"beijing"}};
          
          	// 默認參數為 JKSerializeOptionNone
          	NSData *jsonDataFromDic1 = [dic2 JSONData];
          
          	NSData *jsonDataFromDic2 = [dic2 JSONDataWithOptions:JKSerializeOptionEscapeUnicode error:nil];
      
  • Swift

    • JSONDecoder 方式解析

      	// 從本地文件中讀取數據
      	let jsonData:NSData = NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("JsonDataFile", ofType: "txt")!)!
      
      	let result:AnyObject = JSONDecoder.decoder().objectWithData(jsonData)
      
      	print(result);
      
    • JSONString 解析

      	// 單層 JSONString 解析
      	/*
       		如果 json 是 “單層” 的,即 value 都是字符串、數字,可以使用 objectFromJSONString
      	*/
        
          	// 單層 JSONString 數據
          	let jsonStr1:String = "{\"a\":123, \"b\":\"abc\"}"
      
      		// 返回可變結果使用 mutableObjectFromJSONString 方法
          	let jsonStrDic1:AnyObject = jsonStr1.objectFromJSONString()
      	
      	// 嵌套 JSONString 解析
      	/*
      			如果 json 有嵌套,即 value 里有 array、object,如果再使用 objectFromJSONString,程序可能會報錯,
      		測試結果表明:使用由網絡或得到的 php/json_encode 生成的 json 時會報錯,但使用NSString 定義的 json 字符串時,
      		解析成功,最好使用 objectFromJSONStringWithParseOptions:
      	*/
          
          	// 嵌套 JSONString 數據
          	let jsonStr2:String = "{\"a\":123, \"b\":\"abc\", \"c\":[456, \"hello\"], \"d\":{\"name\":\"張三\", \"age\":\"32\"}}"
          	
          	// 返回可變結果使用 mutableObjectFromJSONStringWithParseOptions 方法
          	let jsonStrDic2:AnyObject = jsonStr2.objectFromJSONStringWithParseOptions(UInt(JKParseOptionLooseUnicode))
      
    • JSONData 解析

      	// 單層 JSONData 解析
      
          	let jsonData1:NSData = "{\"a\":123, \"b\":\"abc\"}".dataUsingEncoding(NSUTF8StringEncoding)!
          	
          	// 返回可變結果使用 mutableObjectFromJSONData 方法
          	let jsonDataDic1:AnyObject = jsonData1.objectFromJSONData()
      	
      	// 嵌套 JSONData 解析
      
      		// 從本地文件中讀取數據
          	let jsonData2:NSData = NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("JsonDataFile", ofType: "txt")!)!
      
      		// 返回可變結果使用 mutableObjectFromJSONDataWithParseOptions 方法
          	let jsonDataDic2:AnyObject = jsonData2.objectFromJSONDataWithParseOptions(UInt(JKParseOptionLooseUnicode))
      
    • 生成 JSONString 數據

      	// String -> JSONString
      
          	let str1:String = "{a\":123, \"b\":\"abc\"}"
      
      		// 默認參數為 JKSerializeOptionNone,includeQuotes 為 YES
          	let jsonStrFromStr1:String = str1.JSONString()
          
          	// includeQuotes 為 NO 時,編碼后的數據最外層不含引號
          	let jsonStrFromStr2:String = try! str1.JSONStringWithOptions(UInt(JKSerializeOptionNone), includeQuotes:false)
      
      	// NSArray/NSDictionary -> JSONString
      
          	let dic1:NSDictionary = ["name":"xiaoxin", "age":8, "Info":["score":99, "add":"beijing"]]
      
      		// 默認參數為 JKSerializeOptionNone
          	let jsonStrFromDic1:String = dic1.JSONString()
      
          	let jsonStrFromDic2:String = try! dic1.JSONStringWithOptions(UInt(JKSerializeOptionEscapeUnicode))
      
    • 生成 JSONData 數據

      	// String -> JSONData
      
          	let str2:String = "{a\":123, \"b\":\"abc\"}"
          
          	// 默認參數為 JKSerializeOptionNone,includeQuotes 為 YES
          	let jsonDataFromStr1:NSData = str2.JSONData()
          
          	// includeQuotes 為 NO 時,編碼后的數據最外層不含引號
          	let jsonDataFromStr2:NSData = try! str2.JSONDataWithOptions(UInt(JKSerializeOptionNone), includeQuotes:false)
      
      	// NSArray/NSDictionary -> JSONData
      
          	let dic2:NSDictionary = ["name":"xiaoxin", "age":8, "Info":["score":99, "add":"beijing"]]
      
      		// 默認參數為 JKSerializeOptionNone
          	let jsonDataFromDic1:NSData = dic2.JSONData()
          
          	let jsonDataFromDic2:NSData = try! dic2.JSONDataWithOptions(UInt(JKSerializeOptionEscapeUnicode))
      

4、JSONKit 與 NSJSONSerialization 對比測試

	static int largeNumber = 100 * 1000;
	
	// JSONKit 解析
    
		NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://192.168.88.200/demo.json"]];

		NSLog(@"JSONKit start");
		CFAbsoluteTime start1 = CFAbsoluteTimeGetCurrent();
		for (int i = 0; i < largeNumber; ++i) {
		 	[[JSONDecoder decoder] objectWithData:jsonData];
		}
		NSLog(@"JSONKit end: %f \n", CFAbsoluteTimeGetCurrent() - start1);
	
	// NSJSONSerialization 解析
    
		NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://192.168.88.200/demo.json"]];
		    
		NSLog(@"NSJSONSerialization start");
		CFAbsoluteTime start2 = CFAbsoluteTimeGetCurrent();
		for (int i = 0; i < largeNumber; ++i) {
		 	[NSJSONSerialization JSONObjectWithData:jsonData options:0 error:NULL];
		}
		NSLog(@"NSJSONSerialization end: %f", CFAbsoluteTimeGetCurrent() - start2);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM