
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:
- Create a
Resulttype that can hold the response of the network request.
enum Result<T> {
case success(T)
case failure(*Error*)
}
Swift
- Create a
fetchfunction that takes aURLand returns aResulttype.
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
- Call the
fetchfunction and handle theResulttype.
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:
- Create a
fetchfunction that takes a URL and returns aAnyPublishertype.
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
- Call the
fetchfunction and handle theAnyPublishertype.
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:
- Create a
fetchfunction 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
- Call the
fetchfunction and handle theResulttype.
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
