【问题标题】:Loading images from a URL and storing them locally using Swift4从 URL 加载图像并使用 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 表示。对此错误的任何建议将不胜感激。

【问题讨论】:

    标签: ios swift uiimage


    【解决方案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 抱怨它不存在,当我添加 ?错误消失了。抱歉,我不明白为什么,但它似乎解决了它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    • 1970-01-01
    相关资源
    最近更新 更多