【发布时间】:2022-01-06 16:32:42
【问题描述】:
我正在尝试转换从 api 获得的 url 字符串。我在我的 modelView 中获取 api 的 url,如下所示:
class DetailViewModel {
var countryCode : String?
public func getImageURL(with completion: @escaping (String) -> Void) {
APIHandler.getDataForCountryImage(for: countryCode!) { result in
print("result is \(result)")
completion(result.data.flagImageUri)
}
}
}
上面的 print 语句成功地将 url 打印为字符串。因此,将 url 作为字符串获取没有问题。
我正在使用 viewModel 初始化我的 viewController,如下所示:
private var viewModel: DetailViewModel
//MARK: - LifeCycle
init(with viewModel: DetailViewModel) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
}
并尝试使用以下代码将我从 modelView 获得的图像 url 字符串转换为 UIImage:
private func setCountryFlagImage() {
self.viewModel.getImageURL { [weak self] imageURL in
print("image url is \(imageURL)")
let url = URL(string: imageURL)
DispatchQueue.main.async {
self?.countryImage.load(url: url!)
}
}
}
此函数还打印 print("image url is (imageURL)") 语句,相关 url 为字符串。
在 dispatchque 内部,我基本上使用的是我在下面编写的 UIImageView 扩展。 countryImage 是我要更新图像的 UIImageView。
extension UIImageView {
func load(url: URL) {
URLSession.shared.dataTask(with: url) { data, response, error in
if error == nil {
guard
let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
let mimeType = response?.mimeType, mimeType.hasPrefix("image"),
let data = data, error == nil,
let image = UIImage(data: data) else { return }
DispatchQueue.main.async { [weak self] in
print("dispatch")
self?.image = image
}
}
else {
print("error is \(error)")
}
}.resume()
}
}
当我运行代码时,我可以在终端中看到 setCountryFlagImage 的打印语句,但另外还有一条警告说 "[boringssl]boringssl_metrics_log_metric_block_invoke(144)" 但我想这可能无关紧要我的问题。
在代码的扩展块上,我从来没有看到 print("dispatch") 语句,这是因为我无法保护 let image = UIImage(data: data)
我在这里错过了什么?
【问题讨论】:
-
永远不要从具有同步
Data(contentsOf:)的远程 URL 加载数据,甚至在后台线程上也不行。别。有一些高效的库可以同步a加载(和缓存)数据。boringssl警告确实无关紧要。 -
尽管使用库,还有其他方法可以解决这个问题吗?坚持使用 swift 库?用那个链接写了这个扩展:hackingwithswift.com/example-code/uikit/…
-
是的,
URLSession和 Swift 5.5 中另外还有async/await。保罗很棒,但不幸的是,他有时会提出一些愚蠢的建议。不过文章中还有一个严重的建议。 -
可爱的@vadian 非常感谢您的帮助。我已经编辑了关于扩展的问题的最后一个块。除了 UIImage(data:data) 之外,每个守卫语句似乎都有效。你知道发生了什么吗?我在保护它之前打印了数据,看起来我已经有一些千字节的数据了。但不能使用guard语句解包
-
我猜我从 api 获得的数据不能以某种方式转换为 UIImage