使用NSJSONSerialization

时间:2015-04-27 22:34:00

标签: json swift alamofire

使用swift 1.2,xcode 6.3和IOS 8,我试图使用NSJSONSerialization类从json响应构建一个对象。 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)时错误是

"无法为类型' Club'调用初始值设定项使用类型的参数列表(JSONString [JSON])"

我不知道,我怎么能将NSJSONSerialization类与复杂的JSON响应一起使用。

1 个答案:

答案 0 :(得分:2)

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)
        }
    }
}