在本地持久存储照片

时间:2021-03-12 19:55:58

标签: ios swift

我想在用户设备上的应用程序中本地存储几张图片。 到目前为止我一直在使用的东西(仍在开发中):

    static func filePath(forKey key: String) -> URL? {
        let fileManager = FileManager.default
        guard let documentURL = fileManager.urls(for: .documentDirectory,
                                                 in: FileManager.SearchPathDomainMask.userDomainMask).first else { return nil }
        
        return documentURL.appendingPathComponent(key + ".png")
    }

    static func savePhoto(imageKey: String) {
        if let filePath = Helpers.filePath(forKey: imageKey) {
            do {
                try Constants.PHOTO_DATA.write(to: filePath, options: .atomic)
            } catch {
                print("error")
            }
        } else {
            print(" >>> Error during saving photo. Filepath couldn't be created.")
        }
    }

    static func getPhoto(imageKey: String) -> (image: UIImage, placeholder: Bool) {
        if let filePath = Helpers.filePath(forKey: imageKey),
           let fileData = FileManager.default.contents(atPath: filePath.path),
           let image = UIImage(data: fileData) {
               // Retrieve image from device
               return (image, false)
        }
        return (UIImage(named: "placeholder")!, true)
    }

现在,在测试过程中我意识到它不起作用(但我几乎 100% 确定它直到现在都在工作,奇怪..)。它会在每次启动时更改应用的容器目录。

例如

Path:
/var/mobile/Containers/Data/Application/1F3E812E-B128-481C-9724-5E39049D6C81/Documents/D5F14199-CFBF-402A-9894-3487976C4C74.png
Restarting the app, then the path it gives (and where it does not find the image):
/var/mobile/Containers/Data/Application/0A9FCE45-1ED4-46EB-A91B-3ECD56E6A31B/Documents/D5F14199-CFBF-402A-9894-3487976C4C74.png

我读了一点,据我所知,“预期”它不起作用,因为应用程序的目录可以在用户重新启动应用程序时随时更改。我应该使用 URL 类的 bookmarkData。

我的问题是我无法将它与 bookmarkData 一起使用,因为我真的不知道我应该如何使用它,并且无法根据我找到的一些示例代码/文章理解它的行为。到目前为止,我只是使用 URL 来存储/检索照片,但现在我应该使用这个 bookmarkData,它是一种数据类型,这让我很困惑。

1 个答案:

答案 0 :(得分:1)

我不确定您想要代码的含义,因为 Helper 和 Constants.PHOTO_DATA 都是未知的。肯定会在文档目录中保存 UIImage 的代码在这里:

class ImageSaver {

    private let imageStore = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first

    //Make this static variable to allow access from all objects without instantiating this class
    static var shared : AuxiliaryObjects {
        return AuxiliaryObjects()
    }

    /**
     Declaration: save(image : UIImage, with fileName: String, and imageName: String?)
     
     Description: This method saves the received image to the persistent store in the documents directory of the user.
     
     - Parameter image: The UIImage object that must be stored in the documents directory.
     - Parameter fileName: A string with the name under which the image must be stored.
     - Parameter imageName: The name of the image if needed.
     */
    func save(image: UIImage, with fileName: String, and imageName: String?) {

        let fileStore = imageStore?.appendingPathComponent(fileName)
        let imageData = UIImagePNGRepresentation(image)
        
        do {
            try imageData?.write(to: fileStore!)
        } catch {
            print("Couldn't write the image to disk.")
        }
    }

    /**
     Declaration: getImage(with fileName: String, with rectangle: CGRect) -> UIImage?
     
     Description: This method retrieves the image with the specified file name and a given size. 
     
     - Parameter fileName: a string with the file name to retrieve.
     - Parameter rectangle: the size of the image to return.
     
     - Returns: UIImage?, the image retrieved from the documents directory.
    */
    func getImage(with fileName: String, with rectangle: CGRect) -> UIImage? {
        
        var returnImage : UIImage?
        var imageRectangle = rectangle
        
        do {
            imageStoreArray = try FileManager.default.contentsOfDirectory(at: imageStore!, includingPropertiesForKeys: resourceKeys, options: .skipsHiddenFiles) as [NSURL]
        } catch {
            return returnImage
        }

        for url in imageStoreArray {
            
            let urlString = url.lastPathComponent
            
            if urlString == fileName {
                
                let retrievedImage = UIImage(contentsOfFile: url.path!)
                
                //When there is no size set, the original size image is returned
                if (rectangle.size.height > 0) || (rectangle.size.width > 0) {
                    let imageWidth = retrievedImage?.size.width
                    let imageHeight = retrievedImage?.size.height
                    
                    if imageWidth! > imageHeight!
                    {
                        //The picture is wider than it is high
                        imageRectangle.size.height *= (imageHeight! / imageWidth!)
                    } else {
                        imageRectangle.size.width *= (imageWidth! / imageHeight!)
                    }
                    
                    UIGraphicsBeginImageContextWithOptions(imageRectangle.size, false, UIScreen.main.scale)
                    retrievedImage?.draw(in: imageRectangle)
                    returnImage = UIGraphicsGetImageFromCurrentImageContext()
                    UIGraphicsEndImageContext()
                } else {
                    returnImage = retrievedImage
                }
            }
        }
        
        return returnImage
    }
}

告诉我这是否适合您。

亲切的问候, MacUserT