swift - 不知道如何得到完成的结果
问题描述
我无法使用完成处理程序的结果。我收到此错误“无法将 '()' 类型的值转换为预期的参数类型”
struct SearchCollectionViewModel {
let name: String
let previewURL: String?
var image:UIImage?
let dataController = DataController()
}
extension SearchCollectionViewModel {
init(with result: Result) {
self.name = result.trackName
self.previewURL = result.previewURL
if let url = result.previewURL {
let imgData = preview(with: url, completion: { data -> Data? in
guard let data = data as? Data else { return nil }
return data
})
self.image = UIImage(data: imgData)
}
}
private func preview(with url: String, completion: @escaping (Data) -> Data?) {
dataController.download(with: url) { data, error in
if error == nil {
guard let imageData = data else { return }
DispatchQueue.main.async {
_ = completion(imageData)
}
}
}
}
}
解决方案
几点观察:
您不能“返回”通过转义闭包异步检索的值。
闭包定义
(Data) -> Data?
表明闭包不仅会传递Data
为图像检索的值,而且闭包本身也会返回一些东西给preview
. 但它显然没有这样做(因此需要_
,如_ = completion(...)
)。我建议您将其更改为(Data?) -> Void
(或使用该Result<T, U>
模式)。我建议重命名您的
Result
类型,因为有一个众所周知的泛型要求Result<Success, Failure>
返回.success(Success)
or.failure(Failure)
。这是我们已经使用了一段时间的模式,但也正式在 Swift 5 中引入。见SE-0235。您的代码库可以有自己的
Result
类型,但如果您开始采用此Result<T, U>
约定,它会在以后引起混淆。你真的不应该从 启动异步过程
init
,而是调用一个方法来做到这一点。就个人而言,我会将转换移至
UIImage
,DataController
例如extension DataController { func downloadImage(with url: URL, completion: @escaping (UIImage?, Error?) -> Void) { let task = URLSession.shared.dataTask(with: url) { data, _, error in let image = data.flatMap { UIImage(data: $0) } completion(image, error) } task.resume() } }
所以,我可能会建议你最终得到类似的东西:
class SearchCollectionViewModel {
let name: String
let previewURL: String?
let dataController = DataController()
var image: UIImage?
init(with result: Result) {
self.name = result.trackName
self.previewURL = result.previewURL
}
}
extension SearchCollectionViewModel {
func preview(with url: String, completion: @escaping (UIImage?) -> Void) {
guard let urlString = previewURL, let url = URL(string: urlString) else {
completion(nil)
return
}
dataController.downloadImage(with: url) { [weak self] image, error in
DispatchQueue.main.async {
self?.image = image
completion(image)
}
}
}
}
推荐阅读
- python - 在 /news/create/ CreateNewsView 配置不当,缺少 QuerySet
- vue.js - vue-cli · 下载 repo vuejs-templates/webpack-simple 失败:无法建立隧道套接字,statusCode=403
- php - php -ajax 函数不向控制器发送数据
- ios - 动态 UICollectionView 单元格高度
- image-processing - for 循环中的操作仅适用于 imageJ 中的最后一个文件
- javascript - 当我从 javascript 生成相同的代码时出现填充
- php - Yii2中年份大于月份小于指定年份时如何获取大于选定年份和月份的记录
- php - SOAP 错误 - PHP 中的 VersionMismatch 但 SOAP UI 正常
- mqtt - 使用 MQTT 响应创建单个 Json 对象
- php - Symfony 5 中参数注入的自动装配问题