Search code examples
swiftoption-typeguard

Swift guard check for nil file - unexpectedly found nil


I'm trying to use a guard statement to check if this file is available or not.

guard UIImage(contentsOfFile: Bundle.main.path(forResource: imageName, ofType: "png")!) != nil else {
    print("\(imageName).png file not available")
    return
}

But I am getting a crash on the guard line with:

Fatal error: Unexpectedly found nil while unwrapping an Optional value

imageName is not an optional. It is a String with a value.

nil is exactly what I'm trying to test for so why is the guard statement crashing?


Solution

  • Combining guard and forced-unwrapping is an oxymoron. One of the common uses of guard is guard let which safely guards against nil and eliminates the need to force-unwrap.

    I would redo your code to something like:

    guard let imagePath = Bundle.main.path(forResource: imageName, ofType: "png"), let image = UIImage(contentsOfFile: imagePath) else {
        print("\(imageName).png file not available")
        return
    }
    
    // Use image here as needed
    

    If you don't actually need the image but you just want to make sure an image can be created, you can change that to:

    guard let imagePath = Bundle.main.path(forResource: imageName, ofType: "png"), UIImage(contentsOfFile: imagePath) != nil else {
        print("\(imageName).png file not available")
        return
    }
    

    Having said all of that, if the image is actually supposed to be in your app bundle and it is simply a temporary issue such as forgetting to target the file properly, then don't use guard and go ahead and force-unwrap. You want the app to crash during development early on so you can fix the problem.

    let image = UIImage(contentsOfFile: Bundle.main.path(forResource: imageName, ofType: "png")!)!
    

    One last thing. You can more easily get the image using:

    let image = UIImage(named: imageName)!