Implementing a generic network request using async await, Combine and Completion blocks.

Async Await

Async Await is a feature introduced in Swift 5.5 that allows developers to write asynchronous code in a synchronous style. This means that we can use the async and await keywords to write asynchronous code that looks like synchronous code.

Implementing a Generic Network Request using Async Await

To implement a generic network request using async await on Swift for iOS, we will follow these steps:

  1. Create a Result type that can hold the response of the network request.
enum Result<T> { 
     case success(T)
     case failure(*Error*)
}

Swift

  1. Create a fetch function that takes a URL and returns a Result type.
func fetch<T: Decodable>(_ url: URL) async throws -> Result<T> {
        let (data, response) = try await URLSession.shared.data(from: url)
        guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else {
            throw NSError(domain: "HTTPError", code: response.statusCode, userInfo: nil)
        }
        let decoder = JSONDecoder()
        let result = try decoder.decode(T.self, from: data)
        return .success(result)
}

Swift

  1. Call the fetch function and handle the Result type.
do {
 let result: Result<User> = try await fetch(url) 
 switch result { 
 case .success(let user): 
   print(user) 
 case .failure(let error): 
   print(error) }
 } catch { 
   print(error)
}

Swift

Using Combine

We can also implement a generic network request using Combine, which is a framework that provides a declarative Swift API for processing values over time. To implement a generic network request using Combine, we will follow these steps:

  1. Create a fetch function that takes a URL and returns a AnyPublisher type.
func fetch<T: Decodable>(_ url: URL) -> AnyPublisher<T, *Error*> {
   return URLSession.shared.dataTaskPublisher(for: url).tryMap { data, response in 
             guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else { 
                   throw NSError(domain: "HTTPError", code: response.statusCode, userInfo: nil)
              } 
           let decoder = JSONDecoder() 
           return try decoder.decode(T.self, from: data) 
   }.eraseToAnyPublisher()
}

Swift

  1. Call the fetch function and handle the AnyPublisher type.
fetch(url).sink { completion in 
    switch completion { 
    case .finished: 
      break
    case .failure(let error): 
      print(error) 
    } 
} receiveValue: { user in
   print(user) 
}.store(in: &cancellables)

Swift

Using Completion Blocks

We can also implement a generic network request using completion blocks, which is a traditional way of handling asynchronous code in iOS. To implement a generic network request using completion blocks, we will follow these steps:

  1. Create a fetch function that takes a URL and a completion block.
func fetch<T: Decodable>(_ url: URL, completion: @escaping (Result<T, Error>) -> Void) { 
  URLSession.shared.dataTask(with: url) { data, response, error in 
    if let error = error { 
        completion(.failure(error))
     } else if let data = data { 
         do { 
           let decoder = JSONDecoder()
           let result = try decoder.decode(T.self, from: data) 
           completion(.success(result)) 
         } catch { 
           completion(.failure(error)) 
         } 
     } 
   }.resume()
}

Swift

  1. Call the fetch function and handle the Result type.
fetch(url) { (result: Result<User, Error>) in 
   switch result { 
   case .success(let user): 
      print(user)
   case .failure(let error): 
      print(error) 
   }
}

Swift

Conclusion

In this tutorial, we learned how to implement a generic network request using async await on Swift for iOS. We also discussed the differences between implementing this using Combine and completion blocks. Depending on the use case, you can choose the best approach that fits your needs.

Share this:

Like this:

Leave a Reply

Jetpack Comment

©

Optional Sankur

Designed with WordPress.

PROXIED V2


Leave a comment