UIImageJPEGRepresentation returns nil when file at specified path is deleted in Swift?

606 Views Asked by At

I'm completely confused as to how UIImageJPEGRepresentation is related to a file's path in the Documents directory.

Basically, when I delete a file from a file path, and then call UIImageJPEGRepresentation on a UIImage, it returns nil, but if the file path is not deleted, UIImageJPEGRepresentation returns the data representation of the image.

Here's my sample code to demonstrate what I mean:

func functionA()
{
    if imagePaths_ARRAY.isEmpty == false
    {
        for pathToDelete in imagePaths_ARRAY
        {
            if fileManager.fileExists(atPath: pathToDelete)
            {
                do
                {
                    try fileManager.removeItem(atPath: pathToDelete)
                }
                catch let error as NSError
                {
                    print(error.localizedDescription)
                }
            }
            else
            {
                print("ERROR")
            }
        }

        imagePaths_ARRAY.removeAll()
    }

    print(images_ARRAY)

    for image in images_ARRAY
    {
        print(image)

        if let imageData = UIImageJPEGRepresentation(image, 0.5)
        {
            print("RETURN GOOD")
            let imageName = getImageName()

            let imagePath = getDirectoryPath().appending("/" + imageName)

            let success = fileManager.createFile(atPath: imagePath, contents: imageData, attributes: nil)

            if success == true
            {
                imagePaths_ARRAY.append(imagePath)
            }
        }
        else
        {
            print("RETURN NIL")
        }

    }
}

The very FIRST time functionA is called, imagePaths_ARRAY is empty so the inside block of code does not execute. I loop through an array of UIImages and for each image, I call UIImageJPEGRepresentation to convert it to a Data object to write to file, and I add the imagePath to my imagePaths_ARRAY array to be used elsewhere in my code.

For each image, I see a log of RETURN GOOD and all the images are written to file.

However, when functionA is called the SECOND time,imagePaths_ARRAY is not empty, so I delete all the files from the paths in imagePaths_ARRAY.

But when UIImageJPEGRepresentation is called on the image again, it returns nil?

I am completely confused as to why because each image in images_ARRAY gives me a valid UIImage:

[<UIImage: 0x600000085280> size {4288, 2848} orientation 0 scale 1.000000]

As mentioned in the first sentence, I like to know how removing a file using removeItem causes UIImageJPEGRepresentation to return nil?

UPDATE: when I replace UIImageJPEGRepresentation with UIImagePNGRepresentation instead, the image is compressed just fine. I'm completely confused!

1

There are 1 best solutions below

6
DonMag On

Seems like something else must be going on in your code.

I just gave it a try, and with the following code I can tap the button repeatedly and every time through I get success:

//
//  TestViewController.swift
//

import UIKit

class TestViewController: UIViewController {

    var imagePaths_ARRAY = [String]()
    var images_ARRAY = [UIImage]()

    let fileManager = FileManager.default

    override func viewDidLoad() {
        super.viewDidLoad()

        let names = ["s1", "s2", "s3"]

        for s in names {
            if let img = UIImage(named: s) {
                images_ARRAY.append(img)
            }
        }
    }

    @IBAction func btnTapped(_ sender: Any) {
        functionA()
    }


    func getDirectoryPath() -> String {
        return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
    }

    func getImageName() -> String {
        let randomNum:UInt32 = arc4random_uniform(1000000)
        return "randomName_\(randomNum)"
    }

    func functionA()
    {

        print(imagePaths_ARRAY)

        if imagePaths_ARRAY.isEmpty == false
        {
            for pathToDelete in imagePaths_ARRAY
            {
                if fileManager.fileExists(atPath: pathToDelete)
                {
                    do
                    {
                        try fileManager.removeItem(atPath: pathToDelete)
                    }
                    catch let error as NSError
                    {
                        print(error.localizedDescription)
                    }
                }
                else
                {
                    print("ERROR")
                }
            }

            imagePaths_ARRAY.removeAll()
        }

        print(images_ARRAY)

        for image in images_ARRAY
        {
//          print(image)

            if let imageData = UIImageJPEGRepresentation(image, 0.5)
            {
                let imageName = getImageName()

                let imagePath = getDirectoryPath().appending("/" + imageName)

                let success = fileManager.createFile(atPath: imagePath, contents: imageData, attributes: nil)

                if success == true
                {
                    print("RETURN GOOD")
                    imagePaths_ARRAY.append(imagePath)
                }
            }
            else
            {
                print("RETURN NIL")
            }

        }

    }

}