Rob Rob - 5 months ago 36
iOS Question

Swift Closure Value Capture scope

I have a question using Swift 3, I am trying to access the task variable from inside my completion closure but it is not available. If I try to access "task" inside the block I get "error: use of unresolved identifier 'task'" What am I doing wrong?

typealias completionHandler = (data: Data?, httpResponse: HTTPURLResponse?, validServer: Bool, serverRealm: String?, serverVersion: String?) -> Void
typealias failureHandler = (data: Data?, response: URLResponse?, error: NSError?) -> Void


func ping(address: String, completionBlock: completionHandler, failureBlock: failureHandler?) -> URLSessionDataTask? {
guard var addressComponents = URLComponents(string: address) else {
let error = NSError(domain: "PING", code: 99, userInfo: [NSLocalizedDescriptionKey : "Invalid URL: \(address)"])
failureBlock?(data: nil, response: nil, error: error)
return nil
}
addressComponents.path = Paths.ping.rawValue
let request = URLRequest(url: addressComponents.url!, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: gsTimeout)

//--------------------------------------------------------------------------------
// Ping the server and process the repsonse
//--------------------------------------------------------------------------------
var task: URLSessionDataTask
task = session.dataTask(with: request) { (data, response, error) in
if error == nil {
if let response = response as? HTTPURLResponse {
let results = self.parseHeader(response)
print("Results: \(results)")
if results.isServer == true {
completionBlock(data: data, httpResponse: response, validServer: results.isServer, serverRealm: results.realm, serverVersion: results.serverVersion)
}
}
} else {
failureBlock?(data: data, response: response, error: error)
}
}

task.taskDescription = Paths.ping.rawValue
task.resume()
return task
}


This is what I get after trying the suggestion

enter image description here

Answer

There is nothing wrong with your code. It compiles just fine.

You are unable to po the value of task using LLDB while paused in the debugger because you are paused inside the completion block. You never captured task in this code (you didn't refer to it), so it is not in scope here. Only outside scope actually referred to inside a closure is captured by the closure.