0

Trying to make a loader using animation trough this code:

        var images: [UIImage] = []
        for i in 1...10 
        {
            let strImageName : String = "loader\(i).png"
            images.append(UIImage(named: strImageName)!)
        }
        self.loader.animationImages = images
        self.loader.animationDuration = 1.0
        self.loader.startAnimating()

I got this error fatal error: "unexpectedly found nil while unwrapping an Optional value Then my application crashed" and those information from the debugger after the crash:

images = ([UImage]) 0 values  
strImageName = (String) “loader1.png”

I can’t understand what is wrong in my code. Can anyone help me please?

Anurag_Soni
  • 542
  • 2
  • 17
Ne AS
  • 1,490
  • 3
  • 26
  • 58
  • 2
    Possible duplicate of [What does "fatal error: unexpectedly found nil while unwrapping an Optional value" mean?](http://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu) – Idan Nov 22 '16 at 11:16
  • 7
    `UIImage(named: strImageName)!` means "please crash my app if this image doesn't exist" and this is what happens. Don't force unwrap, handle errors... – Eric Aya Nov 22 '16 at 11:16
  • https://i.imgflip.com/utfq7.jpg – fpg1503 Nov 22 '16 at 11:32

3 Answers3

2

What's happening is that UIImage's initializer is failable and the image you're trying to create can't be found so force unwrapping crashes. You have to conditionally unwrap (i.e. if let):

var images: [UIImage] = []
for i in 1...10  {
    let strImageName = "loader\(i).png"
    if let image = UIImage(named: strImageName) {
        images.append(image)
    } else {
        print("Image '\(strImageName)' does not exist!")
    }
}
self.loader.animationImages = images
self.loader.animationDuration = 1.0
self.loader.startAnimating()

You can also do it in a single line using map/flatMap:

let images = (1...10).map { "loader\($0).png" }.map { UIImage(named: $0) }.flatMap { $0 }
fpg1503
  • 7,492
  • 6
  • 29
  • 49
1

You need to use if let construct for safely unwrap because UIImage's initializer is failable.

public /*not inherited*/ init?(named name: String)

The named of the file. If this is the first time the image is being loaded, the method looks for an image with the specified name in the application’s main bundle.

Return Value - The image object for the specified file, or nil if the method could not find the specified image.

let strImageName = "loader\(i).png"

if let image = UIImage(named: strImageName) {
    images.append(image)
}
Sahil
  • 9,096
  • 3
  • 25
  • 29
0

Apple's Swift Guide : Implicitly unwrapped optionals should not be used when there is a possibility of a variable becoming nil at a later point. Always use a normal optional type if you need to check for a nil value during the lifetime of a variable.

raheem
  • 17
  • 4
  • 1
    Except that OP is not using an implicitly unwrapped Optional, they are just force unwrapping a normal Optional. – Eric Aya Nov 22 '16 at 11:35