将 API 的 Image URL 字符串转换为 UIImage

Posted

技术标签:

【中文标题】将 API 的 Image URL 字符串转换为 UIImage【英文标题】:Converting string of an Image URL of API to UIImage 【发布时间】: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 【参考方案1】:

问题是来自api的图像是.svg类型的,不能直接转换为UIImage。为了将其更改为 UIImage,我们需要使用名为 SwiftSVG 的第三方框架。该框架的 Github 存储库如下。谢谢大家。

https://github.com/mchoe/SwiftSVG

【讨论】:

以上是关于将 API 的 Image URL 字符串转换为 UIImage的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Cloudinary 将带有转换的 url 输出为字符串?

如何将图像 url 转换为 system.drawing.image

将 javascript 对象转换为 url 查询

浏览器端将语音转换为URL格式的字符串(base64 位编码)

将 android.media.Image (YUV_420_888) 转换为位图

将android.media.Image(YUV_420_888)转换为Bitmap