Reputation: 187
I'm making an http post request within the XCTest framework in Xcode for a simple UI test for my app. Within the request, the response is returned. I can't access that response outside of the URLSession task, and I need to because it contains a JWT that must be decoded and used for another http post request.
I've tried researching how to do this, but it is hard to know the right path as I am a beginner in Swift. I've tried creating a new json object and assigning that response to it outside of the URLSession, but it just says that it can't find that response, it is outside of scope.
// make HTTP request
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
print(responseJSON)
}
}
task.resume()
let response = responseJSON as! [String:Any]
The expected results are that I now have my response object outside of the http request and I can then decode it. The actual results is the error:
Use of unresolved identifier 'responseJSON'
Upvotes: 0
Views: 1243
Reputation: 19750
The request your making is asynchronous. So when you run the line...
let response = responseJSON as! [String:Any]
the network request hasn't finished yet. So you would normally use a completion handler that will be called when the network returns
Here is an example playground:
//: Playground - noun: a place where people can play
import PlaygroundSupport
import UIKit
PlaygroundPage.current.needsIndefiniteExecution = true
func postSomeData(completion: @escaping ([String: Any]?, Error?) -> Void) {
// setup request
let url = URL(string: "https://jsonplaceholder.typicode.com/todos/1")
let request = URLRequest(url: url!)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
completion(nil, error)
}
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
completion(responseJSON, nil)
}
}
task.resume()
}
postSomeData() { response, error in
print(response, error)
PlaygroundPage.current.finishExecution()
}
Output:
Optional(["id": 1, "title": delectus aut autem, "completed": 0, "userId": 1]) nil
I would also suggest that you use Codable
for parsing and mapping the JSON response. Here is an intro to using Codable but there are lots of resources available online on the subject.
Upvotes: 1