Open lenaios opened 3 years ago
import UIKit // 1. 이미지 String -> URLRequest // 2. URLSession.shared.dataTask -> Data // 3. Data -> UIImage // 4. UIImage -> UIImage enum FetchError: Error { case badID case badImage } func fetchThumbnail(for id: String, completion: @escaping (UIImage?, Error?) -> Void) { // 1 let url = URL(string: id)! let request = URLRequest(url: url) // 2 let task = URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { completion(nil, error) } else if (response as? HTTPURLResponse)?.statusCode != 200 { completion(nil, FetchError.badID) } else { // 3 guard let image = UIImage(data: data!) else { completion(nil, FetchError.badID) return } // 4 image.prepareThumbnail(of: CGSize(width: 40, height: 40)) { thumbnail in guard let thumbnail = thumbnail else { return // potential bug } completion(thumbnail, nil) } } } task.resume() } // 이렇게 작성하면 guard를 통과하지 못할 경우에 바로 return 시 디버깅의 어려움 // async/await 사용해서 코드를 변경해보자 // completion 삭제, error는 throws func fetchThumbnail(for id: String) async throws -> UIImage { let url = URL(string: id)! let request = URLRequest(url: url) // async throws 함수는 try await와 함께 사용되야 한다. let (data, response) = try await URLSession.shared.data(for: request) guard (response as? HTTPURLResponse)?.statusCode == 200 else { throw FetchError.badID } let image = UIImage(data: data) guard let thumbnail = await image?.byPreparingThumbnail(ofSize: CGSize(width: 40, height: 40)) else { throw FetchError.badImage } return thumbnail } // 코드가 짧아지고 가독성이 좋아짐 // 언제 실행될 지 몰라 completion으로 클로저를 넘기던 방식에서 동기스럽게 코드가 바뀌었다.
async, await in iOS 15+
sync vs async