What's a good example of an escape closure in Swift?

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 Operation = (Data?) -> ()

func addToQueue(data: Data?, operation: @escaping Operation) {
    OperationQueue.main.addOperation {
        operation(data)
    }
}

If we remove @escaping attribute, Xcode will show the error message below

non-escaping parameter error message