Search code examples
iosswiftxcodenullforced-unwrapping

How to debug "fatal error with nil while unwrapping an optional value"?


This is my first real app I'm writing and I don't understand why I get this "nil" error while unwrapping an optional.

Before I post the code, here's the idea of a simple expense calculator.

I have two textfields (expenseLabel and guestLabel). At the start of the App both should be empty. Here's the first problem. If the user accidentally presses the calculate button I get the following error:

unexpectedly found nil while unwrapping an Optional value

(It's the first line of code I marked down below within ** ... **).

As long as the user enters numbers or the label is not empty at the start of the app (eg. I enter a number in the storyboard) this doesn't happen, but for some strange reason I get the same nil error on the second to last line (again marked within ** ... ** ) when I update the resultLabel.text. Xcode marks this line with the following extra info:

Thread 1: EXC_BAD_INSTRUCTION (code=EXE_I386_INVOP, subcode=0x0)

Here's the code:

class ViewController: UIViewController {


@IBOutlet weak var expenseLabel: UITextField!
@IBOutlet weak var guestLabel: UITextField!
@IBOutlet weak var resultLabel: UILabel!

@IBAction func splitButton(_ sender: Any) {

    let expense = expenseLabel.text
    let guests = guestLabel.text

    **var result = Double(expense!)! / Double(guests!)!**
    result = round(result * 100) / 100

    **resultLabel.text = String(result)**
    self.view.endEditing(true)
} 
...

It's actually not much code, but I don't understand why I get this error. I even tried the following and introduced the two variables expense and guests before everything else:

expense = Double(expenseLabel.text!) ?? 0.0
guests = Double(guestLabel.text!) ?? 0.0

I thought this would help to remove the nil unwrapping error, but this didn't work as well.

I feel pretty helpless right now, because again this is not much code and it is for some reason I don't see not working at all.


Solution

  • You have to check

    • Is the text property nil?
    • ( Is the text property empty? )
    • Can the string in the text property be converted to a Double?

    Strictly spoken in this case the second check can be omitted because an empty string can not be converted to Double anyway.

    if let expense = expenseLabel.text, // !expense.isEmpty, 
       let expenseValue = Double(expense),
       let guests = guestLabel.text, // !guests.isEmpty, 
       let guestValue = Double(guests) {
    
       let result = round((expenseValue / guestValue) * 100) / 100
       resultLabel.text = String(result)
    } else {
       resultLabel.text = "Something went wrong"
    }