[swift]建立从 json 响应使用 NSJSONSerialization 对象

标签: json Alamofire Swift
发布时间: 2017/3/5 3:02:36
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

使用 swift 1.2,xcode 6.3 和 IOS 8,我就是要打造从 json 响应使用 NSJSONSerialization 类对象的 json 响应是︰

[{
  "_id" : "5470def9e0c0be27780121d7",
  "imageUrl" : "https:\/\/s3-eu-west-1.amazonaws.com\/myapi-static\/clubs\/5470def9e0c0be27780121d7_180.png",
  "name" : "Mondo",
  "hasVip" : false,
  "location" : {
    "city" : "Madrid"
  }
}, {
  "_id" : "540b2ff281b30f3504a1c72f",
  "imageUrl" : "https:\/\/s3-eu-west-1.amazonaws.com\/myapi-static\/clubs\/540b2ff281b30f3504a1c72f_180.png",
  "name" : "Teatro Kapital",
  "hasVip" : false,
  "location" : {
    "address" : "Atocha, 125",
    "city" : "Madrid"
  }
}, {
  "_id" : "540cd44581b30f3504a1c73b",
  "imageUrl" : "https:\/\/s3-eu-west-1.amazonaws.com\/myapi-static\/clubs\/540cd44581b30f3504a1c73b_180.png",
  "name" : "Charada",
  "hasVip" : false,
  "location" : {
    "address" : "La Bola, 13",
    "city" : "Madrid"
  }
}]

NSJSONSerialization.JSONObjectWithData 执行的对象类 (Club.swift) 是︰

class Club: NSObject {

    var id: String = ""
    var name: String = ""
    var imageUrl: String = ""
    var hasVip: Bool = false
    var desc: String = ""
    var location: [Location] = []

    init(JSONString: String) {

        super.init()

        var error : NSError?
        let JSONData = JSONString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)

        let JSONDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(JSONData!, options: nil, error: &error) as! NSDictionary

        self.setValuesForKeysWithDictionary(JSONDictionary as [NSObject : AnyObject])

    }

}

最后是 ApiClient 类

class ApiClient {
    func getList(completionHandler: ([JSON]) -> ()) {
        let URL = NSURL(string: "https://myapi.com/v1/clubs")
        let mutableURLRequest = NSMutableURLRequest(URL: URL!)

        mutableURLRequest.setValue("Content-Type", forHTTPHeaderField: "application/json")
        mutableURLRequest.HTTPMethod = "GET"
        mutableURLRequest.setValue("Bearer R01.iNsG3xjv/r1LDkhkGOANPv53xqUFDkPM0en5LIDxx875fBjdUZLn1jtUlKVJqVjsNwDe1Oqu2WuzjpaYbiWWhw==", forHTTPHeaderField: "Authorization")

        let manager = Alamofire.Manager.sharedInstance
        let request = manager.request(mutableURLRequest)

        request.responseJSON { (request, response, json , error) in
            if (json != nil){
                var jsonObj = JSON(json!)
                if let data = jsonObj["hits"].arrayValue as [JSON]?{

                    var aClub : Club = Club(JSONString: data)

                    println(aClub.name)

                    completionHandler(data)
                }
            }
        }
    }
}

但问题是,当我试着去 println(aClub.name) 的错误是

"不能调用 type'Club 的初始值设定项带有参数列表的类型 (JSONString [JSON])"

我不知道,我如何可以使用 NSJSONSerialization 类具有复杂的 JSON 响应。

解决方法 1:

jsonObj似乎应该将一个SwiftyJSON对象,该对象或东西那样,这一代的使用 NSJSONSerialization ,而不是在与它一起。data变量是一个数组的 JSON 对象 (即,它具有 [JSON] ),不是字符串。

但你在用 Alamofire 的 responseJSON 方法,为你做了 JSON 解析。所以你不需要使用 NSJSONSerialization 或 SwiftyJSON。它已经有解析它到数组的词典。

如果你想要的数组 Club 对象,您可以做可以只遍历这个数组,建设 Club 对象的词典︰

class ApiClient {
    func getList(completionHandler: ([Club]?, NSError?) -> ()) {
        let URL = NSURL(string: "https://myapi.com/v1/clubs")
        let mutableURLRequest = NSMutableURLRequest(URL: URL!)

        mutableURLRequest.setValue("Content-Type", forHTTPHeaderField: "application/json")
        mutableURLRequest.HTTPMethod = "GET"
        mutableURLRequest.setValue("Bearer R01.iNsG3xjv/r1LDkhkGOANPv53xqUFDkPM0en5LIDxx875fBjdUZLn1jtUlKVJqVjsNwDe1Oqu2WuzjpaYbiWWhw==", forHTTPHeaderField: "Authorization")

        let manager = Alamofire.Manager.sharedInstance
        let request = manager.request(mutableURLRequest)

        request.responseJSON { (request, response, json, error) in
            var clubs = [Club]()
            if let arrayOfDictionaries = json as? [[String: AnyObject]] {
                for dictionary in arrayOfDictionaries {
                    clubs.append(Club(dictionary: dictionary))
                }
                completionHandler(clubs, nil)
            } else {
                completionHandler(nil, error)
            }
        }
    }
}

显然,你要改变 Club 来处理字典对象︰

class Club {

    var id: String!
    var name: String!
    var imageUrl: String!
    var hasVippler: Bool!
    var location: [String: String]!

    init(dictionary: [String: AnyObject]) {
        id         = dictionary["_id"] as? String
        name       = dictionary["name"] as? String
        imageUrl   = dictionary["imageUrl"] as? String
        hasVippler = dictionary["hasVip"] as? Bool
        location   = dictionary["location"] as? [String: String]
    }
}

最后,你的表视图控制器可以调用的 API:

let apiClient = ApiClient()

var clubs: [Club]!

override func viewDidLoad() {
    super.viewDidLoad()

    apiClient.getList() { clubs, error in
        if clubs != nil {
            self.clubs = clubs
            self.tableView.reloadData()
        } else {
            println(error)
        }
    }
}
官方微信
官方QQ群
31647020