Concurrency in Swift...
If you haven't read the first piece in this series, please do.
Since you've seen how to create any method async and call it, let's solve the remaining puzzle.
Depending on the architecture, you can call an API from a ViewModel, ViewController, or DataSource, and these caller methods are sync methods that cannot directly call an async function.
Task
Task comes to rescue, to read more about it, click below
In this article, we shall explore where and how this will replace or make our lives easier.
The most common use case for concurrency/asynchronization is when we need to retrieve data from our backend APIs.
We will look at how to replace closures with async await
领英推荐
//
// ClosureService.swift
// DextersLabArticles
//
// Created by Deepak Singh on 26/08/24.
//
import Foundation
import Alamofire
class CatService: ObservableObject {
enum UrlEndpoint: String, URLConvertible {
func asURL() throws -> URL {
switch self {
case .catFacts:
return URL(string: self.rawValue)!
}
}
case catFacts = "https://cat-fact.herokuapp.com/facts"
}
func fetchCatFacts(completionHanlder: @escaping (([CatFatsModel]) -> Void)) {
AF.request(UrlEndpoint.catFacts).responseDecodable(of:[CatFatsModel].self) { response in
switch response.result {
case .success(let cats):
completionHanlder(cats)
case .failure(let error):
debugPrint(error)
}
}
}
func asyncFetchCatFacts() async -> [CatFatsModel] {
do {
let value = try await AF.request(UrlEndpoint.catFacts).serializingDecodable([CatFatsModel].self).value
return value
} catch {
return []
}
}
}
and this is how different there callings would be
//
// ContentView.swift
// DextersLabArticles
//
// Created by Deepak Singh on 26/08/24.
//
import SwiftUI
struct ContentView: View {
@ObservedObject var viewModel = CatService()
var body: some View {
VStack(spacing: 20){
Button("Get Facts with Closure") {
viewModel.fetchCatFacts() { catFacts in
print(catFacts)
}
}
Button("Get Facts with Aysnc Await") {
Task(priority: .userInitiated) {
let catFacts = await viewModel.asyncFetchCatFacts()
print(catFacts)
}
}
}
.padding()
}
}
I hope the above example makes it easier to understand how to replace your closure with async await.
Going ahead we will implement multiple API calls as once
For the above code have a look at in progress project on Github : https://github.com/deepaksingh4/DextersLabArticles/tree/main/DextersLabArticles
!!! Happy Coding !!!