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

问题描述 投票:0回答:1

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


    extension UIImage {
        func load(image imageName: String) -> UIImage {
            // declare image location
            let imagePath: String = "\(NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])/\(imageName).png"
            let imageUrl: URL = URL(fileURLWithPath: imagePath)

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

            // image has not been created yet: create it, store it, return it
            do {
                let url = URL(string: eventInfo!.bannerImage)!
                let data = try Data(contentsOf: url)
                let loadedImage: UIImage = UIImage(data: data)!
            }
            catch{
                print(error)
            }

            let newImage: UIImage = 
                try? UIImagePNGRepresentation(loadedImage)?.write(to: imageUrl)
            return newImage
        }
    }

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

ios swift uiimage
1个回答
0
投票

这是一个简单的变量范围问题。你在loadedImage块中声明了do但是你试图在那个块之外使用(之后)。

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,则必须永远不要在主队列上运行此代码。

© www.soinside.com 2019 - 2024. All rights reserved.