What's a good example of an escape closure in Swift?
I'm reading the Swift programming language manual and it mentions an escaping closure. With regards to escaping closures, I don't know what they mean by "the closure is passed as an argument to the function, but is called after the function returns." Could someone provide an example on escaping closures?
An example of an escaping closure would be the completion handler in some asynchronous task, such as initiating a network request:
func performRequest(parameters: [String: String], completionHandler: @escaping (Result<Data, Error>) -> Void) {
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try! JSONEncoder().encode(parameters)
let task = URLSession.shared.dataTask(with: request) { data, _, error in
guard let data = data else {
completionHandler(.failure(error!))
return
}
completionHandler(.success(data))
}
task.resume()
}
And this is called like so:
performRequest(parameters: ["foo" : "bar"]) { result in
switch result {
case .failure(let error):
print(error)
case .success(let data):
// now use data here
}
}
// Note: The `completionHandler` above runs asynchronously, so we
// get here before the closure is called, so don't try to do anything
// here with `data` or `error`. Any processing of those two variables
// must be put _inside_ the closure above.
This completionHandler
closure is defined as @escaping
because URLSession
method dataTask
runs asynchronously (i.e. it returns immediately and its own closure will be called later when the request finishes).
In Swift 3 closure parameters become non-escaping by default.
We need to write @escaping
closure attribute before the parameters type to indicate the closure is called after the function returns.
typealias MyOperation = (Data?) -> ()
func addToQueue(data: Data?, operation: @escaping MyOperation) {
OperationQueue.main.addOperation {
operation(data)
}
}
If we remove @escaping
attribute, Xcode will show the error message below