Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Otto linden
Otto linden
5,857 Points

Why do I get this error: Value of optional type 'UIImage?' must be unwrapped to a value of type 'UIImage'.

Why do I get this error when running my code that is supposed to make an app and show 2 images! This is the code:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var pic: UIImageView!
    @IBOutlet weak var button: UIButton!

    let factProvider = ImageProvider()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    @IBAction func changePic(_ sender: Any) {
        pic.image = ImageProvider[0]
    }

}

And

import GameKit

let imageOtto = UIImage(named:"Otto_l.jpg")
let imageRurik = UIImage(named:"Rurik_ö.jpg")


struct imageProvider {
    let images = [
    imageRurik, imageOtto
    ]
    func randomImage() -> UIImage {
        let randomNumber = GKRandomSource.sharedRandom().nextInt(upperBound: images.count)
        return images[randomNumber]
    }
} 

In the first code i get this error: Type 'ImageProvider.Type' has no subscript members on the last line. And in the second code i get this error: Value of optional type 'UIImage?' must be unwrapped to a value of type 'UIImage' on the return images[randomNumber]

1 Answer

Magnus Hållberg
Magnus Hållberg
17,232 Points

In the view controllers changePic action you are calling "ImageProvider" with a capital I, your struct is named imageProvider with a small cap i so Swift probably doesn't know what to do with that. Also you have created an instance of ImageProvider (with a capital I) that you don't use. I sugest the following changes. Rename your struct to ImageProvider with a capital I (convention say that typs should start with a capital letter and struct is a type). Use the instance you have created to get the image like this, pic.image = factProvider.randomImage(). In the struct you have to unwrap the image from the array since UIImage is optional, In the code I have provided I used an "if let" to do that and returned nil if there was no image. I also made the return optional to be able to return nil.

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var pic: UIImageView!
    @IBOutlet weak var button: UIButton!

    let factProvider = ImageProvider()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    @IBAction func changePic(_ sender: Any) {
        pic.image = factProvider.randomImage()
    }

}

// Your struct
import GameKit

let imageOtto = UIImage(named:"Otto_l.jpg")
let imageRurik = UIImage(named:"Rurik_ö.jpg")


struct ImageProvider {
    let images = [
    imageRurik, imageOtto
    ]
    func randomImage() -> UIImage? {
        let randomNumber = GKRandomSource.sharedRandom().nextInt(upperBound: images.count)
        if let returnImage = images[randomNumber] {
            return returnImage
        }
        return nil
    }
}

Hope this help