因为Swift对于类型有非常严格的控制,它在处理JSON时是挺麻烦的,因为它天生就是隐式类型。SwiftyJSON是一个能帮助我们在Swift中使用JSON的开源类库。开始之前,让我们先看一下在Swift中处理JSON是多么痛苦。 
 
 在Swift中使用JSON的问题以Twitter API为例。使用Swift,从tweet中取得一个用户的“name”值应该非常简单。下面就是我们要处理的JSON: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27  | [
   {
     ......
     "text": "just another test",
     ......
     "user": {
       "name": "OAuth Dancer",
       "favourites_count": 7,
       "entities": {
         "url": {
           "urls": [
             {
               "expanded_url": null,
               "url": "http://bit.ly/oauth-dancer",
               "indices": [
                 0,
                 26
               ],
               "display_url": null
             }
           ]
         }
       ......
     },
     "in_reply_to_screen_name": null,
   },
   ......]
  |  
 在Swift中,你必须这样使用: 1 2 3 4 5 6 7 8 9 10 11  | let jsonObject : AnyObject! = NSJSONSerialization.JSONObjectWithData(dataFromTwitter, options: NSJSONReadingOptions.MutableContainers, error: nil)
 if let statusesArray = jsonObject as? NSArray{
     if let aStatus = statusesArray[0] as? NSDictionary{
         if let user = aStatus["user"] as? NSDictionary{
             if let userName = user["name"] as? NSDictionary{
                 //Finally We Got The Name
               }
         }
     }
 }
  |  
 或者,你可以用另外的一个方法,但这不易于阅读: 1 2 3 4  | let jsonObject : AnyObject! = NSJSONSerialization.JSONObjectWithData(dataFromTwitter, options: NSJSONReadingOptions.MutableContainers, error: nil)
 if let userName = (((jsonObject as? NSArray)?[0] as? NSDictionary)?["user"] as? NSDictionary)?["name"]{
   //What A disaster above
 }
  |  
 
 开始下载在这儿下载SwiftyJSON,或者直接在GitHub克隆它: 1  | git clone https://github.com/lingoer/SwiftyJSON.git
  |  
 基础用法SwiftyJSON的使用十分的简单: 典型的NSURLSessionTask抓取Twitter的API将产生dataFromNetwork: NSData!: 你首先应该做的事情是初始化JSONValue: 
 1  | let json = JSONValue(dataFromNetwork)
  |  
 JSONValue是一个枚举类型表示一个典型的JSON数据结构。 你能使用subscripts检索不同的值从原始的JSONValue中,像这样: 
 1  | let userName:JSONValue = json[0]["user"]["name"]
  |  
 注意userName仍然是一个JSONValue。那怎样得到一个字符串呢? 
  你能用.string属性得到JSON数据表示的真正值。 
 1  | let userNameString = userName.string!
  |  
 对每一种JSON类型, JSONValue都提供了一种属性检索它: 
  
 1 2 3 4 5  | var string: String?
 var number: NSNumber?
 var bool: Bool? 
 var array: Array<JSONValue>?
 var object: Dictionary<String, JSONValue>?
  |  
 注意每一种属性都是一个Optional值。这是因为JSON数据能包含任何它定义的有效类型。 
  因此,建议的方式是用Optional绑定检索值: 
 1 2 3 4 5 6 7  | 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属性产生一个NSNumber值,在Swift中这通常不是很有用。你能用.double或者.integer得到一个Double值或者一个Int值。 
  
 1 2 3  | if let intValue = numberValue.integer{
     count += intValue
 }
  |  
 
 枚举(Enumeration)
 在Swift中JSONValue实际上是一个枚举: 1 2 3 4 5 6 7 8 9 10 11  | 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)
   }
  |  
 你可以使用一个switch子句去更有效地获取值: 1 2 3 4 5 6 7 8  | 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")
  |  
 下标(Subscripts)注意,在JSON中一个数组结构被包装成intoArray<JSONVlaue>,它意味着数组里的每一个元素都是一个JSONValue。甚至你从JSONValue中取出一个数组,你仍然可以使用基本的属性去获取元素的值: 1 2 3 4 5  | if let array = json["key_of_array"].array{
     if let string = array[0].string{
         //The array[0] is still a JSONValue!
     }
 }
  |  
 对象也是一样。因此,推荐的方式是访问每一个数组和对象时使用JSONValue的下标。 1 2 3  | if let string = json["key_of_array"][0].string{
   }
  |  
 实际上,你可以用下标访问一个JSONValue,还不用担心运行时错误导致的崩溃: 1  | let userName = json[99999]["wrong_key"]
  |  
 如果你使用推荐的方式去取数据,它是安全的: 1 2 3  | if let userName = json[99999]["wrong_key"]["name"].string{
     //It's always safe
 }
  |  
 
  |