I want to make a GET request in swift to get some Json data.
I tried to use AFNetworking and it works, but I don't know how to return the Json I get.
I tried with a return
but it's made before the GET so I get nothing...
func makeGet(place:String) -> String
{
var str:String = ""
let manager = AFHTTPRequestOperationManager()
manager.requestSerializer.setValue("608c6c08443c6d933576b90966b727358d0066b4", forHTTPHeaderField: "X-Auth-Token")
manager.GET("http://something.com/api/\(place)",
parameters: nil,
success: { (operation: AFHTTPRequestOperation!,responseObject: AnyObject!) in
str = "JSON: \(responseObject.description)"
println(str) //print the good thing
},
failure: { (operation: AFHTTPRequestOperation!,error: NSError!) in
str = "Error: \(error.localizedDescription)"
})
return str //return ""
}
Can you help me ?
You're not getting a response from that function, because the GET operation happens asynchronously. That is, the order of execution looks like this:
You call makeGet
makeGet
creates manager
, which fires off a GET request
makeGet
finishes executing and returns an empty string
(some time later) manager
receives a value back from the server and executes either the success
or failure
block.
So the only time you have access to the JSON that comes back from the server is in step 4, and you need to find a way of storing that value so you can parse it or use it or whatever. There are a variety of options here -- one is to define closures that call event handlers on your class instance, like this:
class MyClass {
func jsonLoaded(json: String) {
println("JSON: \(json)")
}
func jsonFailed(error: NSError) {
println("Error: \(error.localizedDescription)")
}
func makeGet(place:String) {
let manager = AFHTTPRequestOperationManager()
manager.requestSerializer.setValue("608c6c08443c6d933576b90966b727358d0066b4", forHTTPHeaderField: "X-Auth-Token")
manager.GET("http://something.com/api/\(place)",
parameters: nil,
success: { (operation: AFHTTPRequestOperation!, responseObject: AnyObject!) in
self.jsonLoaded(responseObject.description)
},
failure: { (operation: AFHTTPRequestOperation!, error: NSError!) in
self.jsonFailed(error)
}
)
}
}
Since you want to return the value after the webservice request is completed you have to pass the data via a delegate or a block(In swift it is called closures)
I see blocks useful here
//Above your class file create a handler alias
typealias SomeHandler = (String! , Bool!) -> Void
func makeGet(place:String , completionHandler: SomeHandler!)
{
var str:String = ""
let manager = AFHTTPRequestOperationManager()
manager.requestSerializer.setValue("608c6c08443c6d933576b90966b727358d0066b4", forHTTPHeaderField: "X-Auth-Token")
manager.GET("http://something.com/api/\(place)",
parameters: nil,
success: { (operation: AFHTTPRequestOperation!,responseObject: AnyObject!) in
str = "JSON: \(responseObject.description)"
println(str) //print the good thing
completionHandler(str,false) //str as response json, false as error value
},
failure: { (operation: AFHTTPRequestOperation!,error: NSError!) in
str = "Error: \(error.localizedDescription)"
completionHandler("Error",true)
})
//return str //return "" You don't want to return anything here
}
When you want to call the method get the values like this
makeGet(){
yourJSONString , errorValue in //Here the value will be passed after you get the response
if !errorValue {
println("The End."
}
}
More about swift closures
FYI: AFNetworking owner has created a new Networking layer for swift and it is called Alamofire (AF from AFNetworking is Alamofire :])
let manager = AFHTTPSessionManager()
manager.GET("http://api.androidhive.info/json/movies.json", parameters: nil, success: { (operation, responseObject) -> Void in
print(responseObject)
}, failure: nil)
AFHTTPRequestOperationManager is not available in latest AFnetworking library, it has replaced with AFHTTPSessionManager.
This is a simple example of getting response object.