Swift: Connect with API using Async Await

Swift: Connect with API using Async Await

The sample code below shows the non-reactive ways to connect with an API endpoint using async-await. The code is a generic implementation for API connection. This means it can be used with any model class as long as the model class implements the Decodable protocol. This means it can be directly used in any network layer implementation.

The below code can be found here. The code below would be mostly self-explanatory, please refer to the comments for more clarity.

  1. Create an Enum to capture various errors while making the API connection.

/*Enum to capture various errors during the connection.*/

enum NetworkError: Error 
    case badUrl
    case decodingError
    case badRequest
    case noData
    case custom(Error)
}
        

2. Create the Protocol with Generic Model for the Network Service Class.

/*Create the Protocol, With Generic T which is a Decodable */

protocol NetworkServiceProtocol {

func fetchDataFromApi <T:Decodable>(withUrl: String) async -> Result <T,NetworkError>

}
        

3. Implement the Network Service Class for Generic Model.

class NetworkService: NetworkServiceProtocol {

?? ?
func fetchDataFromApi<T>(withUrl: String) async -> Result<T, NetworkError> where T : Decodable {

? ? ? ? guard let url = URL(string: withUrl) else {

? ? ? ? ? ? return .failure(.badUrl)

? ? ? ? }

? ? ? do {

? ? ? ?  let (data, response) = try await URLSession.shared.data(from: url)

? ? ? ? ? ? if ((response as? HTTPURLResponse)?.statusCode != 200) {

? ? ? ? ? ? ? ? return .failure(.badRequest)

? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? let response = try JSONDecoder().decode(T.self, from: data)

? ? ? ? ? ? ? ? return .success(response)

? ? ? ? ? ? }

? ? ? ? } catch let error {

? ? ? ? ? ? debugPrint(error)

? ? ? ? }

? ? ? ? return .failure(.decodingError)
? ? }
}        

4. Invoke the Service. Please notice WebCharacterResponse which is my model object as it captures the JSON data specific to the API which I am using. You can use your own response object as is, the only condition being your response object should also implement the decodable protocol.

?
func fetchData(forPage: Int) async {

? ? ? ? let urlString = AppUrls.baseUrl + "\(forPage)"

? ? ? ? let result: Result<WebCharactersResponse, NetworkError> = 

        await networkService.fetchDataFromApi(withUrl: urlString)

? ? ? ? switch result {

? ? ? ? case .success( let characterResponse):

? ? ? ? ? ? if let characters = characterResponse.results {

? ? ? ? ? ? ? ? self.characters.append(contentsOf: characters) ? 

? ? ? ? ? ? }

? ? ? ? case .failure(let error):

? ? ? ? ? ? print(error)

? ? ? ? }

? ? }        

要查看或添加评论,请登录

Christo Abhinav Kumar的更多文章

  • Swift: Initializers

    Swift: Initializers

    This post explores all you need to know about initializers in swift. Please find all relevant code here.

  • Swift: Protocols

    Swift: Protocols

    Please find the GitHub link of all the code here. Protocols are used to create the loosely coupled system.

社区洞察

其他会员也浏览了