如何使用Swift检索响应JSON数据

时间:2015-07-31 18:09:05

标签: ios swift yelp

我正在尝试使用Yelp API并根据搜索词接收相应的JSON。这是我正在使用的YelpAPI客户端:

import Foundation
import UIKit

let yelpConsumerKey = "KLGXXXXfnmhQ"
let yelpConsumerSecret = "wPmXXXXvOA"
let yelpToken = "0-3DsXXXXhAq"
let yelpTokenSecret = "BViXXXXQ-Dz3Y"

class YelpClient: BDBOAuth1RequestOperationManager {
    var accessToken: String!
    var accessSecret: String!

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    class var sharedInstance : YelpClient {
        struct Static {
            static var token : dispatch_once_t = 0
            static var instance : YelpClient? = nil
        }
        dispatch_once(&Static.token) {
            Static.instance = YelpClient(consumerKey: yelpConsumerKey, consumerSecret: yelpConsumerSecret, accessToken: yelpToken, accessSecret: yelpTokenSecret)
        }
        return Static.instance!
    }

    init(consumerKey key: String!, consumerSecret secret: String!, accessToken: String!, accessSecret: String!) {
        self.accessToken = accessToken
        self.accessSecret = accessSecret
        var baseUrl = NSURL(string: "http://api.yelp.com/v2/")
        super.init(baseURL: baseUrl, consumerKey: key, consumerSecret: secret);

        var token = BDBOAuthToken(token: accessToken, secret: accessSecret, expiration: nil)
        self.requestSerializer.saveAccessToken(token)
    }

    func searchWithTerm(term: String, success: (AFHTTPRequestOperation!, AnyObject!) -> Void, failure: (AFHTTPRequestOperation!, NSError!) -> Void) -> AFHTTPRequestOperation! {
        // For additional parameters, see http://www.yelp.com/developers/documentation/v2/search_api
        var parameters = ["term": term, "ll": "37.77493,-122.419415"]
        return self.GET("search", parameters: parameters, success: success, failure: failure)
    }

    func searchWithTerm(term: String, deal: Bool, radius: Int, sort: Int, categories: String, success: (AFHTTPRequestOperation!, AnyObject!) -> Void, failure: (AFHTTPRequestOperation!, NSError!) -> Void) -> AFHTTPRequestOperation! {
        // For additional parameters, see http://www.yelp.com/developers/documentation/v2/search_api
        var parameters = NSDictionary()
        if (radius == -1) {
            parameters = ["term": term, "ll": "37.77493,-122.419415", "deals_filter": deal, "sort": sort, "category_filter":categories]
        }
        else {
            var meter:Double = Double(radius) * 1609.34
            parameters = ["term": term, "ll": "37.77493,-122.419415", "deals_filter": deal, "radius_filter": meter, "sort": sort, "category_filter":categories]
        }
        return self.GET("search", parameters: parameters as [NSObject : AnyObject], success: success, failure: failure)
    }


}

我为这里的餐馆做了一个模特课:

import UIKit

class Resturant: NSObject {
    var name: String!
    var thumbUrl: String!
    var address: String!
    var jsonData: NSData!

    init(dictionary: NSDictionary) {
        name = dictionary["name"] as? String
        thumbUrl = dictionary["thumbUrl"] as? String
        address = dictionary["address"] as? String
    }

    class func searchWithQuery(query: String, completion: ([Resturant]!, NSError!) -> Void) {
        YelpClient.sharedInstance.searchWithTerm(query, success: { (operation: AFHTTPRequestOperation!, response: AnyObject!) -> Void in
            println(response)
        let JSONObject = NSJSONSerialization.JSONObjectWithData(response as! NSData, options: NSJSONReadingOptions(0), error: nil)
            }) { (operation: AFHTTPRequestOperation!, error: NSError!) -> Void in

        }
    }
}

let JSONObject = NSJSONSerialization.JSONObjectWithData(response as! NSData, options: NSJSONReadingOptions(0), error: nil)

这行代码提示此错误:

Could not cast value of type '__NSCFDictionary' (0x10b914a60) to 'NSData' (0x10b913a48).

1 个答案:

答案 0 :(得分:3)

您正在获得响应JSON。它只是一个二进制化的NSData对象,如果我没有错,你可以将它转换为JSON对象。现在,我猜它会打印字母数字字符的乱码,对吧?

嗯,你可以这样做:

class func searchWithQuery(query: String, completion: ([Resturant]!, NSError!) -> Void) {
        YelpClient.sharedInstance.searchWithTerm(query, success: { (operation: AFHTTPRequestOperation!, response: AnyObject!) -> Void in
            println(response) //Illegible block of data
            let JSONObject = NSJSONSerialization.JSONObjectWithData(response, options: NSJSONReadingOptions(0), error: nil)
             println(JSONObject)//Prints JSON

            }) { (operation: AFHTTPRequestOperation!, error: NSError!) -> Void in

        }
    }

编辑#1

看起来是坏请求的情况。明确客户端和服务器之间的合同。必须有一些可能缺少的参数或某些意外的请求。我担心我们无法帮助你,因为我们不知道合同是什么。

编辑#2

此时代码......

let JSONObject = NSJSONSerialization.JSONObjectWithData(response, options: NSJSONReadingOptions(0), error: nil)

... API接受响应类型为NSData。但是,您的回复类型为NSDictionary。它会给你一个警告;但是在编译时没有类型检查,它会编译。但运行时试图将response视为NSData,但事实并非如此;它实际上是一个NSDictionary,崩溃了。

只需记录NSDictionary即可。你会得到结果。

编辑#3 你的最终代码应该是这样的:

class func searchWithQuery(query: String, completion: ([Resturant]!, NSError!) -> Void) {
            YelpClient.sharedInstance.searchWithTerm(query, success: { (operation: AFHTTPRequestOperation!, response: AnyObject!) -> Void in
                println(response) //Illegible block of data
                let responseInfo = response as! NSDictionary
                println(responseInfo)
                //Prints JSON

                }) { (operation: AFHTTPRequestOperation!, error: NSError!) -> Void in

            }
        }