Skip to content

Instantly share code, notes, and snippets.

@rmirabelli
Created December 17, 2021 20:03
Show Gist options
  • Save rmirabelli/0810046338ed126c384bdd3996b6426f to your computer and use it in GitHub Desktop.
Save rmirabelli/0810046338ed126c384bdd3996b6426f to your computer and use it in GitHub Desktop.
A sample using completions, and then with async/await
import Foundation
import UIKit
enum PostError: Error {
case badURL
case badResponse
case noData
case decodingError
}
struct PostsService {
private let urlString = "https://jsonplaceholder.typicode.com/posts"
// - MARK: using completion & result
func fetchPosts(completion: @escaping (Result<[DeluxePost], Error>) -> Void) {
guard let url = URL(string: urlString) else { completion(.failure(PostError.badURL)); return}
let session = URLSession(configuration: .ephemeral)
let task = session.dataTask(with: url) { data, response, error in
guard error == nil else { completion(.failure(error!)); return}
guard let response = response as? HTTPURLResponse else {completion(.failure(PostError.badResponse)); return}
guard response.statusCode == 200 else { completion(.failure(PostError.badResponse)); return}
guard let data = data else { completion(.failure(PostError.noData)); return}
guard let posts = try? JSONDecoder().decode([Post].self, from: data) else {completion(.failure(PostError.decodingError)); return}
expensiveTransform(posts: posts) { deluxe in
completion(.success(deluxe))
}
}
task.resume()
}
func expensiveTransform(posts: [Post], completion: @escaping ([DeluxePost]) -> Void) {
let deluxePosts = posts.map { DeluxePost(post: $0) }
completion(deluxePosts.compactMap {$0})
}
// MARK: Using Async/Await
func posts() async throws -> [DeluxePost] {
guard let url = URL(string: urlString) else { throw PostError.badURL }
let session = URLSession(configuration: .ephemeral)
let (data, response) = try await(session.data(from: url))
guard let response = response as? HTTPURLResponse else { throw PostError.badResponse }
guard response.statusCode == 200 else { throw PostError.badResponse }
let posts = try JSONDecoder().decode([Post].self, from: data)
let deluxe = try await transform(posts)
return deluxe
}
func transform(_ posts: [Post]) async throws -> [DeluxePost] {
posts.compactMap { DeluxePost(post: $0) }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment