2

Use Swift Concurrency with Completion Handlers

 2 years ago
source link: https://www.swiftjectivec.com/snip-completion-handler-block-closure-to-swift-async-concurrency/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Use Swift Concurrency with Completion Handlers

// Written by Jordan Morgan // Sep 17th, 2022 // Read it in about 1 minutes // RE: Snips

let concatenatedThoughts = """

Welcome to Snips! Here, you'll find a short, fully code complete sample with two parts. The first is the entire code sample which you can copy and paste right into Xcode. The second is a step by step explanation. Enjoy!

The Scenario

Convert an existing function that uses a completion handler over to Swift Concurrency.

struct CatFact: Codable {
    let fact: String
}

// 1
func getCatFact(completion:@escaping ((String) -> Void)) {
    let reqURL = URL(string: "https://catfact.ninja/fact")!
    URLSession.shared.dataTask(with: URLRequest(url: reqURL)) { data, response, error in
        guard let factData = data,
              let catFact = try? JSONDecoder().decode(CatFact.self, from: factData) else {
            completion("No cat facts today.")
            return
        }
        completion(catFact.fact)
    }.resume()
}

// 2
func getCatFact() async -> String {
    // 3
    await withCheckedContinuation { continuation in
        getCatFact { fact in
            continuation.resume(returning: fact)
        }
    }
}

With that, you can call getCatFact using Swift Concurrency:

let result = await getCatFact()

Instead of this:

getCatFact { result in 
    print(result)
}

The Breakdown

Step 1
The first step is to realize that you don’t remove your existing function that uses a completion handler. Instead, you need to simply note what return type (if any) the completion handler returns. In this case, it’s just a String.

Step 2
Create a new function that matches the original’s signature, and have its return type match whatever the completion handler returns. Again, that’s a String here. Be sure to add async, and throws if it has error handling.

Step 3
Finally, call the original function within your new async version, and wrap it in a continuation. Within the completion handler, resume it and you’re done! If you’re using error handling, there is a throwing version of a continuation available, too.

Until next time ✌️


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK