How to get response JSON data using Swift
I am trying to use the Yelp API and get the corresponding JSON according to the search term. Here is the YelpAPI client I'm 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 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 throws this error:
Could not cast value of type '__NSCFDictionary' (0x10b914a60) to 'NSData' (0x10b913a48).
source to share
You receive a JSON response. It's just a binarized object NSData
that you would like to convert to a JSON object if I'm not mistaken. Right now, I think it will print illegible blocks of alphanumeric 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
It looks like this is a bad query case. Read about the contract between client and server for this job. There must be some parameter that may be missing or something unexpected. I'm afraid we cannot help you as we do not know what the contract is.
EDIT # 2
At this point in the code ...
let JSONObject = NSJSONSerialization.JSONObjectWithData(response, options: NSJSONReadingOptions(0), error: nil)
... the API accepts the response type as NSData
. But your answer type NSDictionary
. This will give you a warning; however, there is no type check at compile time, it is compiled. But the runtime tries to treat it response
like NSData
, but it doesn't; it's actually a NSDictionary
glitch.
Just register NSDictionary
. You will receive results.
Edit # 3 Your final code should look 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
}
}
source to share