Swift使用Optik库展示远程图片时如何实现ImageDownloader
实现方案
你之前的写法错误原因是:ImageDownloader是协议类型,本身无法直接实例化,必须先定义一个遵循该协议的具体类型,再生成实例传入参数。
步骤1:确认闭包类型
Optik中ImageDownloaderCompletion的默认定义为:
public typealias ImageDownloaderCompletion = (UIImage?, Error?) -> Void
如果你的库版本有差异,以你本地引入的Optik版本定义为准。
步骤2:实现自定义MyImageDownloader
这里给出两种常见实现方式,你可以按需选择:
方式一:基于原生URLSession实现(无第三方依赖)
import UIKit import Optik // 定义遵循ImageDownloader协议的类 class MyImageDownloader: ImageDownloader { func downloadImage(from url: URL, completion: @escaping ImageDownloaderCompletion) { let task = URLSession.shared.dataTask(with: url) { data, response, error in // 处理错误情况 if let error = error { DispatchQueue.main.async { completion(nil, error) } return } // 验证数据并转成UIImage guard let data = data, let image = UIImage(data: data) else { DispatchQueue.main.async { completion(nil, NSError(domain: "ImageDownloadError", code: -1, userInfo: [NSLocalizedDescriptionKey: "图片数据无效"])) } return } // 成功返回,UI相关回调切回主线程执行 DispatchQueue.main.async { completion(image, nil) } } task.resume() } }
方式二:基于第三方图片库实现(以Kingfisher为例,项目已引入该类库时可选用)
import Kingfisher import Optik class MyImageDownloader: ImageDownloader { func downloadImage(from url: URL, completion: @escaping ImageDownloaderCompletion) { KingfisherManager.shared.retrieveImage(with: url) { result in switch result { case .success(let imageResult): completion(imageResult.image, nil) case .failure(let error): completion(nil, error) } } } }
步骤3:传入实例初始化Optik
直接实例化上面实现的MyImageDownloader即可,原有逻辑无需额外修改:
// 实例化自定义下载器 let imageDownloader = MyImageDownloader() let imageViewer = Optik.imageViewer( withURLs: [ URL(string: "https://somewebsite.com/image1.png")!, URL(string: "https://somewebsite.com/image2.png")!, URL(string: "https://somewebsite.com/image3.png")! ], imageDownloader: imageDownloader ) present(imageViewer, animated: true)
如果你使用的Swift版本较旧,原有代码中的
NSURL写法也可以正常运行,不需要强制替换为URL。
内容的提问来源于stack exchange,提问作者poPaTheGuru
相关产品推荐
相关产品推荐

