Reputation: 173
Im learning about Swift and i trying to make an HTTP request. My code is working but i dont know how to return the result of the request:
func makeRequest(request: URLRequest)->String{
let task = URLSession.shared.dataTask(with: request){data, response, error in
guard let data = data, error == nil else{
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
print (data)
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
print(json)
} catch {
print("error serializing JSON: \(error)")
}
//print("responseString = \(responseString)")
}
task.resume()
return "Something"//i need to return the json as String
}
Someone can help me please? i was trying using CompletionHanlder but all the example that i found is based on swift 2, and this causes error on my code
Upvotes: 1
Views: 4122
Reputation: 47876
The completion handler's type needs to be something like this:
@escaping ({argument types...})->{result type}
@escaping
is needed as the completion handler is executed later when the communication is completed.
{argument types...}
needs to be the types you want to pass to the handler, so in your case, a single type String
. And you usually do not use the result from the handler, so you need to specify Void
(aka ()
).
Thus your completion handler's type needs to be:
@escaping (String)->Void
So, your method header becomes:
(You know you need a closing parenthesis for argument list.)
func makeRequest(request: URLRequest, completion: @escaping (String)->Void)
Whole your method would be something like this:
func makeRequest(request: URLRequest, completion: @escaping (String)->Void) {
let task = URLSession.shared.dataTask(with: request) {data, response, error in
guard let data = data, error == nil else{
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
print(data as NSData) //<-`as NSData` is useful for debugging
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
print(json)
//Why don't you use decoded JSON object? (`json` may not be a `String`)
} catch {
print("error serializing JSON: \(error)")
}
//Not sure what you mean with "i need to return the json as String"
let responseString = String(data: data, encoding: .utf8) ?? ""
completion(responseString)
}
task.resume()
}
You can use it as:
makeRequest(request: request) {response in //<-`response` is inferred as `String`, with the code above.
print(response)
}
Upvotes: 2
Reputation: 11
func makeRequest(request: URLRequest, completion: (result : String?)->() {
let task = URLSession.shared.dataTask(with: request){data, response, error in
guard let data = data, error == nil else{
print("error=\(error)")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
print (data)
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
print(json)
} catch {
print("error serializing JSON: \(error)")
}
completion("yourResultString")
//print("responseString = \(responseString)")
}
task.resume()
}
to call it
makeRequest(request: request) { (result : String?) in
if let result = result {
print("got result: \(result)")
}
Upvotes: 1
Reputation: 1191
You can't "return" the result of the request. By the time you have a result your makeRequest
function has already returned to its caller. You should:
makeRequest
to not return anything, because there's no
point responseString
result.Upvotes: 0