在Swift中優(yōu)雅地處理JSON
SwiftyJSON的使用十分的簡(jiǎn)單:
典型的NSURLSessionTask抓取Twitter的API將產(chǎn)生dataFromNetwork: NSData!:
你首先應(yīng)該做的事情是初始化JSONValue:
- let json = JSONValue(dataFromNetwork)
JSONValue是一個(gè)枚舉類(lèi)型表示一個(gè)典型的JSON數(shù)據(jù)結(jié)構(gòu)。
你能使用subscripts檢索不同的值從原始的JSONValue中,像這樣:
- let userName:JSONValue = json[0]["user"]["name"]
注意userName仍然是一個(gè)JSONValue。那怎樣得到一個(gè)字符串呢?
你能用.string屬性得到JSON數(shù)據(jù)表示的真正值。
- let userNameString = userName.string!
對(duì)每一種JSON類(lèi)型, JSONValue都提供了一種屬性檢索它:
- var string: String?
- var number: NSNumber?
- var bool: Bool?
- var array: Array<JSONValue>?
- var object: Dictionary<String, JSONValue>?
注意每一種屬性都是一個(gè)Optional值。這是因?yàn)镴SON數(shù)據(jù)能包含任何它定義的有效類(lèi)型。
因此,建議的方式是用Optional綁定檢索值:
- if let name = userName.string{
- //This could avoid lots of crashes caused by the unexpected data types
- }
- if let name = userName.number{
- //As the value of the userName is Not a number. It won't execute.
.number屬性產(chǎn)生一個(gè)NSNumber值,在Swift中這通常不是很有用。你能用.double或者.integer得到一個(gè)Double值或者一個(gè)Int值。
- if let intValue = numberValue.integer{
- count += intValue
- }
枚舉(Enumeration)
在Swift中JSONValue實(shí)際上是一個(gè)枚舉:
- enum JSONValue {
- case JNumber(NSNumber)
- case JString(String)
- case JBool(Bool)
- case JNull
- case JArray(Array<JSONValue>)
- case JObject(Dictionary<String,JSONValue>)
- case JInvalid(NSError)
- }
你可以使用一個(gè)switch子句去更有效地獲取值:
- let json = JSONValue(jsonObject)
- switch json["user_id"]{
- case .JString(let stringValue):
- let id = stringValue.toInt()
- case .JNumber(let numberValue):
- let id = numberValue.integerValue
- default:
- println("ooops!!! JSON Data is Unexpected or Broken")
下標(biāo)(Subscripts)
注意,在JSON中一個(gè)數(shù)組結(jié)構(gòu)被包裝成intoArray<JSONVlaue>,它意味著數(shù)組里的每一個(gè)元素都是一個(gè)JSONValue。甚至你從JSONValue中取出一個(gè)數(shù)組,你仍然可以使用基本的屬性去獲取元素的值:
- if let array = json["key_of_array"].array{
- if let string = array[0].string{
- //The array[0] is still a JSONValue!
- }
- }
對(duì)象也是一樣。因此,推薦的方式是訪(fǎng)問(wèn)每一個(gè)數(shù)組和對(duì)象時(shí)使用JSONValue的下標(biāo)。
- if let string = json["key_of_array"][0].string{
- }
實(shí)際上,你可以用下標(biāo)訪(fǎng)問(wèn)一個(gè)JSONValue,還不用擔(dān)心運(yùn)行時(shí)錯(cuò)誤導(dǎo)致的崩潰:
- let userName = json[99999]["wrong_key"]
如果你使用推薦的方式去取數(shù)據(jù),它是安全的:
- if let userName = json[99999]["wrong_key"]["name"].string{
- //It's always safe
- }
打印
JSONValue遵守Printable協(xié)議.所以很容易在原始字符串中得到JSON數(shù)據(jù):
- let json = JSONValue(dataFromNetwork)
- println(json)
- /*You can get a well printed human readable raw JSON string:
- {
- "url": {
- "urls": [
- {
- "expanded_url": null,
- "url": "http://bit.ly/oauth-dancer",
- "indices": [
- 0,
- 26
- ],
- "display_url": null
- }
- ]
- }
- */
如果你不想打印出來(lái),你可以使用.description屬性來(lái)得到上述字符串。
- let printableString = json.description
調(diào)試與錯(cuò)誤處理
要是JSON數(shù)據(jù)出錯(cuò)或者我們錯(cuò)誤地檢索數(shù)據(jù),那會(huì)怎么樣呢?你可以使用if語(yǔ)句來(lái)測(cè)試:
- let json = JSONValue(dataFromNetworking)["some_key"]["some_wrong_key"]["wrong_name"]
- if json{
- //JSONValue it self conforms to Protocol "LogicValue", with JSONValue.JInvalid stands for false and others stands true
- }
如果我們嘗試使用錯(cuò)誤的鍵值或索引來(lái)訪(fǎng)問(wèn)數(shù)據(jù),description屬性會(huì)高數(shù)你KeyPath在哪里出錯(cuò)了.
- let json = JSONValue(dataFromNetworking)["some_key"]["some_wrong_key"]["wrong_name"]
- if json{
- } else {
- println(json)
- //> JSON Keypath Error: Incorrect Keypath "some_wrong_key/wrong_name"
- //It always tells you where your key went wrong
- switch json{
- case .JInvalid(let error):
- //An NSError containing detailed error information
- }
- }
后記
SwiftyJSON的開(kāi)發(fā)將會(huì)發(fā)布在Github, 請(qǐng)持續(xù)關(guān)注后續(xù)版本。
本文鏈接:http://mobile.51cto.com/design-446157.htm