D. Cohen
D. Cohen

Reputation: 577

prepare segue unexpectedly found nil while unwrapping an Optional value

Yes, another found nil while unwrapping an Optional value error. I have read tons of other stack overflow posts with similar errors such as this one and many others. I still do not fully understand how to properly deal with unwrapping a variable.

I have a class that is similar to the following:

@IBOutlet weak var nameTextField: UITextField?
@IBOutlet weak var valueInput: UITextField?

var checkbox : CheckBox?

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let name = nameTextField.text ?? ""
    let state = buttonState.getIsChecked()
    let value : Int? = Int(valueInput.text!)
    let isMoveable = true

    checkbox = CheckBox(name: name, value: value, state: state, isMoveable: isMoveable)
}

I get the error on the line the "let value : Int? = Int(valueInput.text!) line.

Upvotes: 0

Views: 432

Answers (2)

Sahil
Sahil

Reputation: 9226

You can safely unwrap the value using if let construct

var value : Int? = nil 

if let val = valueInput.text {
  value = Int(val) // it would either nil or optional value
}

and also you can do it by nil coalescing operator ?? in a single line

let value : Int? = Int(valueInput.text ?? "")

UPDATE

First check if textfields disconnected from the Interface Builder , if not connect, connect them. and if you become your textfields optionals you also have to safely unwrap the textfields ( you forgot to add it from interface builder and it will not crash if you make them optionals).

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

var name: String? = nil
var value : Int? = nil
let state = buttonState.getIsChecked()
let isMoveable = true


if let nameTextField = self.nameTextField where nameTextField.text != nil {
  name = nameTextField.text!
}

if let valueTextField = self.valueInput where valueTextField.text != nil {
  value = Int(valueTextField.text!)
}

 checkbox = CheckBox(name: name, value: value, state: state, isMoveable: isMoveable)

}

Upvotes: 2

Andy Obusek
Andy Obusek

Reputation: 12832

Sahil's answer is on track, but doesn't address that valueInput is also an optional. Use this code:

if let valueInput = valueInput,
    let val = valueInput.text {
    value = Int(val)
}

In addition regarding properly unwrapping the optional valueInput I wanted to add that chances are that if valueInput is an IBOutlet it's defined as:

@IBOutlet weak var valueInput: UITextField!

That's called an implicitly unwrapped optional. The annoying thing is that since it is also an IBOutlet, if it ever becomes disconnected from the UITextField in Interface Builder, the variable will become nil, and accessing it from anywhere in the code will cause a crash.

Change it to this:

@IBOutlet weak var valueInput: UITextField?

I've also written about this on my blog: http://cleanswifter.com/implicitly-unwrapped-iboutlets/

Note: you didn't show the definition of valueInput so I assumed it to be a UITextField

Upvotes: 0

Related Questions