Open djk3000 opened 1 year ago
平时接口拿一些数据的时候,一般都是异步的,我们需要拿到之后传出来。 下面就用一个简单的下载图片的例子来说明一下常用的异步回调传数据的方法。
class DownloadImageAsyncImageLoder { func downloadWithEscaping(completionHandler: @escaping (_ image: UIImage? , _ error :Error?) -> ()) { URLSession.shared.dataTask(with: url) {[weak self] data, response, error in let image = self?.handleResponse(data: data, response: response) completionHandler(image, error) } .resume() } func handleResponse(data: Data?, response: URLResponse?) -> UIImage? { guard let data = data, let image = UIImage(data: data), let response = response as? HTTPURLResponse, response.statusCode >= 200 && response.statusCode < 300 else { return nil } return image } }
使用
let loader = DownloadImageAsyncImageLoder() func fetchImage() { loader.downloadWithEscaping { [weak self] image, error in DispatchQueue.main.async { if let image = image { self?.image = image } } } }
class DownloadImageAsyncImageLoder { func downloadWithCombine() -> AnyPublisher<UIImage?, Error> { URLSession.shared.dataTaskPublisher(for: url) .map(handleResponse) .mapError({ $0 }) .eraseToAnyPublisher() } func handleResponse(data: Data?, response: URLResponse?) -> UIImage? { guard let data = data, let image = UIImage(data: data), let response = response as? HTTPURLResponse, response.statusCode >= 200 && response.statusCode < 300 else { return nil } return image } }
let loader = DownloadImageAsyncImageLoder() func fetchImage() { loader.downloadWithCombine() .receive(on: DispatchQueue.main) .sink { _ in } receiveValue: {[weak self] image in if let image = image { self?.image = image } } .store(in: &cancelable) }
这是ios15新增的一套体系,如果需要在API中使用的话需要ios15以上。
class DownloadImageAsyncImageLoder { func downloadWithAsync() async throws -> UIImage? { do { let (data, response) = try await URLSession.shared.data(from: url, delegate: nil) return handleResponse(data: data, response: response) } catch { throw error } } func handleResponse(data: Data?, response: URLResponse?) -> UIImage? { guard let data = data, let image = UIImage(data: data), let response = response as? HTTPURLResponse, response.statusCode >= 200 && response.statusCode < 300 else { return nil } return image } }
func fetchImage() async { let image = try? await loader.downloadWithAsync() await MainActor.run(body: { self.image = image }) } //在调用的时候需要用Task来使用它 .onAppear{ // vm.fetchImage() Task { await vm.fetchImage() } }
异步回调
平时接口拿一些数据的时候,一般都是异步的,我们需要拿到之后传出来。 下面就用一个简单的下载图片的例子来说明一下常用的异步回调传数据的方法。
方法一:逃逸闭包
使用
方法二:Combine
使用
方法三:async / await
这是ios15新增的一套体系,如果需要在API中使用的话需要ios15以上。
使用
参考资料