Liam SY Kim
by Liam SY Kim
2 min read

Categories

When I use HTTP connection for login system , I should catch the end point of getting data.

As you know, when HTTP connection is done asychronously, you should not use return value for this case.

I have used Future function in Flutter, but I had struggle to find the similar function in swift.

Escape closure supports @escaping property. If you add @escaping property after the name of argument(:), escape closure recieves ‘Completion handler’ which supports sending async task completion state to other side and sending the return value as well.

If @escaping property is not exist after argument, then this is Nonescape Closure. If you do not add @escaping property, Nonescape property is default.

Nonescape property does not support completion handler.

Because we have used Nonescape closure so far, I just focus on showing escape closure, and completion handler.

I arranged 2 cases which I used to do.

  • Completion Handle with TrailingClosure
  • Completion Handle with DeclaredClosure

There are getFruitColor examples below.

If you send parameter on getFruitColor function with completionHanlder, then completionHanlder prints the color of given fruit.

  • FULL Code : https://github.com/dev-wd/simple_swift_example/blob/master/escape_closure/ViewController.swift

Case 1. Completion Handle with TrailingClosure

  • Implement case is implemented in ‘viewDidLoad()’.

  • ‘completion’ is completionHandler which includes ‘@escaping’ property.
  • you don’t need to send ‘completion’ parameter, but add trailing closure instead.

// case 1 : Completion Handle with TrailingClosure
func getFruitColorwithTrailingClosure(_ fruitName : String, completion: @escaping (String)-> Void) {
        
    var color = "Not yet"
        
    if fruitName == "banana" {
        color = "yellow"
    }
        
    if fruitName == "apple" {
        color = "red"
    }
        
    if fruitName == "melon" {
           color = "green"
    }
        
    completion(color)
}
    
    
// Implement case 1
getFruitColorwithTrailingClosure("banana") {
    color in
    print(color)
}
        
        

Case 2. Completion Handle with DeclaredClosure

  • Declare closure for completionHandler.
  • Because you declared closure first, you don’t need to add trailing closure when you implement getFruitColor function.
// Declare closure for case 2.
let getColorClosure : (String) -> Void = {
    color in
    print(color)
}
    
// case 2 : Completion Handle with DeclaredClosure
func getFruitColorwithClosure(_ fruitName : String, completion: @escaping (String)-> Void) {
    var color = "Not yet"
        
    if fruitName == "banana" {
        color = "yellow"
    }
        
    if fruitName == "apple" {
        color = "red"
    }
        
    if fruitName == "melon" {
        color = "green"
    }
        
    completion(color)
        
}
    
// Implement case 2        
getFruitColorwithClosure("melon",completion: getColorClosure)
    

Conclusion

Asynchoronous function’s end state can be catched by EscapingClosure.

Do not return the value on your service API.

Let’s get completion state by completionHandler from now on!

Reference

  • Swift Programming 2 by YAGOM