JoakimE
JoakimE

Reputation: 1874

Save and get image from folder inside Documents folder on iOS wrong path

On application launch I'm creating a folder inside the Documents directory, if there is none there already. This works great!

I'm downloading some images and would like to save them to use them later. My problem is that my code seems to store the files in a documents directory that is not the same that would be on the next app launch. I know that since iOS8 the documents directory can change from launch to launch. So I'm always retrieving a path to the Documents folder. Could someone answer me why this code can't get the path to the image correctly?

func requestImage(let url: String,let isbn: String, numberInRow: Int){
    var documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
    documentsPath.appendContentsOf("/bookImages")
    print("Image folder path is: \(documentsPath)")
///var/mobile/Containers/Data/Application/E6B66A15-F166-46FE-A577-9B0D911F5C92/Documents/bookImages

    let pathComponent = isbn.stringByAppendingString(".jpg")
        print("Suggested filename: \(pathComponent)") //1234567891234.jpg

        let imagePath = documentsPath.stringByAppendingString("/\(pathComponent)")
        print("Image to be saved at: \(imagePath)")
// /var/mobile/Containers/Data/Application/E6B66A15-F166-46FE-A577-9B0D911F5C92/Documents/bookImages/9788202350420.jpg
        if (data != nil){
            NSFileManager.defaultManager().createFileAtPath(imagePath, contents: data!, attributes: ["YES" : "NSURLIsExcludedFromBackupKey"])

            self.books[numberInRow].setValue(pathComponent, forKey: "imageurl")
        }



    }

When I would like to display these images I have this in the view controller

let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
let imageFolderPath = documentsPath.stringByAppendingString("/bookImages")


if let image = bookData.valueForKey("imageurl") as? String
            {
                print("Imagepath: \(self.imageFolderPath)/\(image)")
// /var/mobile/Containers/Data/Application/DB1F6FE9-1071-41A6-9E87-2A3D32ECD2B9/Documents/bookImages/9788202350420.jpg
let imagePath = self.imagePath.stringByAppendingString("/\(image)")

                reuseableCell.bookCover.image = UIImage(contentsOfFile: imagePath)
            }

I removed a lot of code that was not relevant. Why can't the image be displayed be found?

If anyone understand the error code, it is here:

BOMStream BOMStreamWithFileAndSys(int, off_t, size_t, int, char *, BomSys *): read: No such file or directory

Edit: On application launch I'm searching for files in the Documents/bookImages and the files are there.

let paths: NSArray = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.AllDomainsMask, true)
    if let documentDirectory = paths.firstObject{
        do{
            var path = documentDirectory as! String
            path.appendContentsOf("/bookImages")

            let documents = try NSFileManager.defaultManager().contentsOfDirectoryAtPath(path)

            for files in documents {
                let urlForm = NSURL.fileURLWithPath((path) + "/" + files)

                do{
                    try print("\(files): \(urlForm.resourceValuesForKeys([NSURLIsExcludedFromBackupKey])), with filepath: \(urlForm)")
                    //Prints out folder and files in the desired location

                } catch let error as NSError{
                    print("Can't find key: \(error)")
                }

            }

        }catch let error as NSError{
            print("Can't retrieve contents: \(error)")
        }
    }


9788202350420.jpg: ["NSURLIsExcludedFromBackupKey": 0], with filepath:    file:///var/mobile/Containers/Data/Application/DB7BA523-6F75-42CF-92E6- ED2AF171D1AA/Documents/bookImages/9788202350420.jpg
9788203193538.jpg: ["NSURLIsExcludedFromBackupKey": 0], with filepath: file:///var/mobile/Containers/Data/Application/DB7BA523-6F75-42CF-92E6-ED2AF171D1AA/Documents/bookImages/9788203193538.jpg
9788203254703.jpg: ["NSURLIsExcludedFromBackupKey": 0], with filepath: file:///var/mobile/Containers/Data/Application/DB7BA523-6F75-42CF-92E6-ED2AF171D1AA/Documents/bookImages/9788203254703.jpg

Upvotes: 3

Views: 4793

Answers (2)

LuKenneth
LuKenneth

Reputation: 2237

You can initialize your path variables as global variables at the top of your class, then just modify them within your requestImage method.

Then when you want to retrieve those images, you can just use the same variable name to ensure that it is the exact same path.

EDIT* I think you may need to be reading some NSData instead. You can use UIImagePNGRepresentation or UIImageJPEGRepresentation to write your file to the documents directory. I found a tutorial here

Upvotes: 1

Midhun MP
Midhun MP

Reputation: 107231

I suspect the issue is happening because you didn't created the bookImages folder in the document directory. NSFileManager won't create the directories or sub-directories automatically.

// Creating directory
do
{
    try NSFileManager.defaultManager().createDirectoryAtPath(documentsPath, withIntermediateDirectories: true, attributes: nil)
}
catch let error as NSError
{
    NSLog("\(error.localizedDescription)")
}

// Saving image
if (data != nil)
{
   // Also it would be better to check the file creation status
   let status = NSFileManager.defaultManager().createFileAtPath(imagePath, contents: data!, attributes: ["NSURLIsExcludedFromBackupKey" : "YES"])
   if status
   {
      // File created
      self.books[numberInRow].setValue(pathComponent, forKey: "imageurl")
   }
   else
   {
      // File creation failed, update your question on stack overflow, someone will surely help you to find the issue :)
   }
}

Upvotes: 2

Related Questions