You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 08:15:03