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).