Search code examples
swiftescapingclosures

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?


Solution

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