从 URL 加载图像并使用 Swift4 将它们存储在本地

Posted

技术标签:

【中文标题】从 URL 加载图像并使用 Swift4 将它们存储在本地【英文标题】:Loading images from a URL and storing them locally using Swift4 【发布时间】:2019-08-07 03:12:40 【问题描述】:

我需要从 URL 加载图像并将它们存储在本地,这样就不必一遍又一遍地重新加载它们。我正在开发这个扩展:

扩展 UIImage 函数加载(图像图像名称:字符串)-> UIImage // 声明图片位置 让 imagePath: String = "\(NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])/\(imageName).png" 让 imageUrl: URL = URL(fileURLWithPath: imagePath) // 检查图像是否已经存储 如果 FileManager.default.fileExists(atPath: imagePath), 让 imageData: 数据 = 试试?数据(内容:imageUrl), 让图像:UIImage = UIImage(数据:imageData,比例:UIScreen.main.scale) 返回图片 // 图像尚未创建:创建、存储、返回 做 让 url = URL(string: eventInfo!.bannerImage)! 让数据=尝试数据(contentsOf:url) 让loadedImage:UIImage = UIImage(数据:数据)! 抓住 打印(错误) 让 newImage: UIImage = 尝试? UIImagePNGRepresentation(loadedImage)?.write(to: imageUrl) 返回新图像

我遇到了一个问题,UIImagePNGRepresentation 中的“loadedImage”返回错误“使用未解析的标识符加载图像”。我的目标是在本地存储图像的 PNG 表示。对此错误的任何建议将不胜感激。

【问题讨论】:

【参考方案1】:

这是一个变量范围的简单问题。您在 do 块内声明 loadedImage,但随后您尝试在该块之外(之后)使用。

loadedImage 的使用移动到do 块内。

您还需要更好的错误处理和可选结果的更好处理。并且您的 load 方法可能应该返回一个可选图像,以防所有获取图像的尝试都失败。或者返回一些默认图片。

这是您使用更好的 API 和更好的选项和错误处理重写的方法。

extension UIImage 
    func load(image imageName: String) -> UIImage? 
        // declare image location
        guard let imageUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent(imageName).appendingPathExtension("png") else 
            return nil // or create and return some default image
        

        // check if the image is stored already
        if FileManager.default.fileExists(atPath: imageUrl.path) 
            if let imageData = try? Data(contentsOf: imageUrl), let image = UIImage(data: imageData) 
                return image
            
        

        // image has not been created yet: create it, store it, return it
        do 
            let url = URL(string: eventInfo!.bannerImage)! // two force-unwraps - consider better handling of this
            if let data = try Data(contentsOf: url), let loadedImage = UIImage(data: data) 
                try data.write(to: imageUrl)

                return loadedImage
            
        
        catch
            print(error)
        

        return nil // or create and return some default image
    

如果eventInfo!.bannerImage 是一个远程 URL,那么您绝不能在主队列上运行此代码。

【讨论】:

您的代码运行良好!我实际上把它从扩展中拿出来,让它成为一个单独的功能。对于那些要遵循的修改,我必须添加一个?到“尝试”。这条线是:如果让数据=尝试? Data(contentsOf: url), let loadedImage = UIImage(data: data) 如果在do/catch 中,则不需要try? 而不是try Xcode 抱怨它不存在,当我添加 ?错误消失了。抱歉,我不明白为什么,但它似乎解决了它。

以上是关于从 URL 加载图像并使用 Swift4 将它们存储在本地的主要内容,如果未能解决你的问题,请参考以下文章

从图像 URL 加载图像需要很长时间才能显示

Firebase 和 Alamofire Url TableViewCell 图像加载问题 Swift 4

iOS:从 url 加载图像

如何从HTTP请求将图像加载到UIButton Swift中

如何从图像集合中保存视频文件?

将图像保存到数据库并从服务器加载