Alex
Alex

Reputation: 5

Problems with loading image path from realm in Swift

In my app I am storing an image in local storage and I am saving the path of that image in my Realm database. And now i have problems with load this image from that path?

Thats how I save path to database:

let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory,nsUserDomainMask, true)
let dirPath = paths.first


    let imageURL1 = URL(fileURLWithPath: dirPath!).appendingPathComponent("refuge1.jpg")

    let med1 = Meditation()
    med1.name = "Refuge"
    med1.count = 0
    med1.targetAmount = 111111
    med1.malasStep = 108
    med1.imagePath = imageURL1.path
    med1.id = 1

It's straightforward that am trying to get an image from this meditation.imagePath path. I double-checked the path, image is there still am not able to set the image using this path, is there is something that am missing?

In debug mode I see this:

Meditation {
name = Refuge;
count = 0;
targetAmount = 111111;
malasStep = 108;
imagePath = /Users/macbook/Library/Developer/CoreSimulator/Devices/2E25309F-D6A9-41C3-9EF4-67203142172C/data/Containers/Data/Application/F198640B-3C72-4F9C-8173-FB00D3ABEC15/Documents/refuge1.jpg;
id = 1;}

but my variable image still nil in debug mode

// Configure the cell...
    cell.nameOfMeditation.text = meditation.name
    cell.countOfMeditation.text = String(meditation.count)
    let image = UIImage(contentsOfFile: meditation.imagePath)
    cell.imageForMeditation.image = image

    return cell

I see name of meditation and sound, bot no omg.

Upvotes: 0

Views: 720

Answers (2)

TiM
TiM

Reputation: 16011

It's not advised to save the absolute file path of a file in an iOS app (ie, everything including /Users/macbook/Library/Developer/...), in Realm or anywhere else.

For security reasons, iOS devices rename the UUID folder name between launches. This means that while the folder path was valid at the time it was saved, it won't be at a later date.

Instead, it's recommended to save just the relative path of the file (eg, its location in relation to just the Documents folder. In this case, it would be just /refuge1.jpg) and to then dynamically build the absolute path by requesting the Documents directory path as you need it.

Upvotes: 1

Pierce
Pierce

Reputation: 3158

Try this:

// Use these convenience methods if you do a lot of saving and loading
func getDocumentsURL() -> URL {
    let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    return documentsURL
}

func fileInDocumentsDirectory(_ filename: String) -> String {

    let fileURL = getDocumentsURL().appendingPathComponent(filename)
    return fileURL.path

}

func saveRefugeOne(image: UIImage) {
    // Create a file name, and then save the path in your documents with that name
    let imageFileName:String = "refuge1.jpg"
    let imagePath = fileInDocumentsDirectory(imageFileName!)
    saveImage(image, path: imagePath)
}

func loadRefugeOne() -> UIImage? {

    // Get the image back
    let imageName:String = "refuge1.jpg"  // Or whatever name you saved
    let imagePath = fileInDocumentsDirectory(imageName)

    if let loadedImage = self.loadImageFromPath(imagePath) {
         return loadedImage
    } else { 
        print("Couldn't Load: \(imageName)") 
        return nil
    }

}

// This will be your method to save image
func saveImage(_ image: UIImage, path: String ) {

    //If you want PNG use this let pngImageData = UIImagePNGRepresentation(image)
    // But since you mentioned JPEG:

    if let jpgData = UIImageJPEGRepresentation(image, 1.0) {
        try? jpgData.write(to: URL(fileURLWithPath: path), options: [.atomic])
    }

}

// This will load image from saved path. Make sure to store the path
// somewhere. This makes it easier to save images locally. You can 
// save the image in the documents directory, and then just save the
// path in CoreData or something similar.
func loadImageFromPath(_ path: String) -> UIImage? {

    let image = UIImage(contentsOfFile: path)

    if image == nil {

        print("couldn't find image at path: \(path)")
    }

    return image

}

Hopefully this will help. It's the method I always use, and it works like a charm when I follow my own steps right ;-)

Upvotes: 0

Related Questions