我无法使用完成处理程序的结果。 我收到此错误“无法将类型'()'的值转换为预期的参数类型”
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)
}
}
}
}
}
答案 0 :(得分:0)
一些观察结果:
您不能“返回”通过转义闭包异步检索的值。
闭包定义(Data) -> Data?
表示闭包不仅将传递为图像检索的Data
,而且闭包本身将返回一些信息到{{1} }。但这显然不是这样做的(因此需要preview
,如_
一样)。我建议您将其更改为_ = completion(...)
(或使用(Data?) -> Void
模式)。
我建议重命名您的Result<T, U>
类型,因为有一个众所周知的泛型Result
用于返回Result<Success, Failure>
或.success(Success)
。这是我们使用了一段时间的一种模式,但是Swift 5也正式引入了这种模式。参见SE-0235。
您的代码库可以有自己的.failure(Failure)
类型,但是如果您开始采用此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()
}
}