I am trying to use the Yelp API and receive the corresponding JSON according to a search term. Here is the YelpAPI Client I am using:
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)
}
}
I made a model class for the restaurants here:
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)
This line of code prompts this error:
Could not cast value of type '__NSCFDictionary' (0x10b914a60) to 'NSData' (0x10b913a48).
You ARE getting the response JSON. It's just that it is a binarized NSData
object which you would want to convert to JSON object, if I am not wrong. Right now, I guess it will print illegible blocks of alpha numeric characters, right?
Well, you can do something like:
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
}
}
EDIT #1
Looks like it is the case of bad request. Be clear about the contract between the client and the server for this work. There must be some parameter that might be missing or something unexpected request. I'm afraid we cannot help you as we do not know what that contract is.
EDIT #2
At this point of code ...
let JSONObject = NSJSONSerialization.JSONObjectWithData(response, options: NSJSONReadingOptions(0), error: nil)
... the API accepts the response type as NSData
. But, your response type is NSDictionary
. It would be giving you a warning; however there is no type checking at the compile time, it compiles. But the runtime is trying to treat response
as NSData
, but it is not; it is actually a NSDictionary
, crashes.
Just log the NSDictionary
. You'll get the results.
Edit #3 Your final code should like this:
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
}
}