繁体   English   中英

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

[英]Loading images from a URL and storing them locally using Swift4

我需要从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表示。 对此错误的任何建议将不胜感激。

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

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,则您绝不能在主队列上运行此代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM