如何使用 Swift 检索响应 JSON 数据
How to retrieve response JSON data with Swift
我正在尝试使用 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)
}
}
我为这里的餐厅做了一个模型class:
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).
您正在收到回复 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
}
}
我正在尝试使用 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)
}
}
我为这里的餐厅做了一个模型class:
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).
您正在收到回复 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
}
}