2

I'm new to Swift and have been trying to wrap (ha) my head around optional values. As far as I can see - although I'm probably wrong - variables can be optional and therefore contain a nil value and these have to be accounted for in code.

Whenever I hit the 'save' button in my application I get the error: 'fatal error: unexpectedly found nil while unwrapping an Optional value'.

@IBAction func saveTapped(sender: AnyObject) {

    //code to save fillup to Parse backend

    // if variable is not nil
    if let username = PFUser.currentUser()?.username {

        // set username equal to current user
        self.object.username = username

    }else{

        println("PFUser.currentUser()?.username contained a nil value.")

    }

    // if variable is not nil
    if let amount = self.amountTextField.text {

        //set amount equal to value in amountTextField
        self.object.amount = self.amountTextField.text

    }else{

        println("self.amountTextField.text contained a nil value.")

    }

    // if variable is not nil
    if let cost = self.costTextField.text {

        // set cost equal to the value in costTextField
        self.object.cost = self.costTextField.text

    }else{

        println("self.costTextField.text contained a nil value.")

    }

    // set date equal to the current date
    self.object.date = self.date

    //save the object
    self.object.saveEventually { (success, error) -> Void in

        if error == nil {

            println("Object saved!")

        }else{

            println(error?.userInfo)

        }


    }

    // unwind back to root view controller
    self.navigationController?.popToRootViewControllerAnimated(true)

}

Not sure if the error is because of something in this block of code or somewhere else - can provide the main class code if needed.

Any help anyone can provided would be really appreciated as this has been bugging me for a while now.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
mforrest
  • 104
  • 2
  • 3
  • 12
  • Is `self.date` an Optional and the error happening on the `self.object.date = self.date` line? Because it looks like it's the only value that could be nil and don't have an `if let`. – Eric Aya Apr 30 '15 at 17:29
  • BTW, you should do with all your `if let` like you did in the first one with `username`: use the unwrapped value inside the first branch. I mean, use `amount` instead of `self.amountTextField.text` inside the `if let`, etc. – Eric Aya Apr 30 '15 at 17:31
  • You could also get `nil while unwrapping optional` if for instance, your `self.costTextField` was not hooked up properly as an outlet and you had declared it as an implicitly unwrapped optional like `@IBOutlet var costTextField: UITextField!` – Frankie Apr 30 '15 at 17:40
  • @ericd I've removed all references to Date just to make sure and the error still appears. Also changed my `if let` statements as you suggested and it still doesn't work. Could it perhaps be other code causing the error? Even though this error only occurs when I perform the `saveTapped` action. – mforrest Apr 30 '15 at 17:47
  • @Frankie my textFields are declared as implicitly unwrapped...how should they be declared? – mforrest Apr 30 '15 at 17:50
  • Xcode should highlight the line where the error happens, normally. Does it? – Eric Aya Apr 30 '15 at 17:51
  • @ericd the error appears in the console and Xcode shows me a complicated looking page with stuff like this everywhere: `0x100435474 <+44>: brk #0x1 `. Doesn't seem to show where the error is located in my code. – mforrest Apr 30 '15 at 17:56
  • I see. In this case I would try setting breakpoints in your code at important locations to try and catch where it crashes exactly. Not sure at all it comes from the code you show here. :/ – Eric Aya Apr 30 '15 at 18:02

1 Answers1

5

From your code and the comments it sounds like your issue definitely lies with self.object

Your code never uses an if let statement to check to ensure self.object is not nil

Using println(username) works because your username is not nil. But when you try to call self.object.username, it's the self.object that is causing the crash.

You may have a property in your implementation like var object:CustomPFObject! which means, the first time you access this variable it's expected to not be nil. You'll probably want to check the code where you are setting self.object for the first time, and to make sure that it's being set before you've tried to access it.

If you're not able to manage when self.object is set, and when it's accessed, then change your declaration to var object:CustomPFObject? Now it's an optional, and as you write your code you'll be forced to make decisions as you go along.

For example:

var object:CustomPFObject?

let text = self.object.username //won't compile

let text = self.object!.username //mighty crash

let text = self.object?.username //you're safe, 'text' just ends up nil

I hope this helps you solve your issue.

Frankie
  • 11,508
  • 5
  • 53
  • 60
  • Thanks that's solved the problem. Although now whenever I apply a variable to `object.username` it is always nil. I'm assuming this is something to do with how I've set up my Parse Subclass but the documentation provided by Parse is minimum at best. – mforrest Apr 30 '15 at 20:50
  • I really wouldn't know what the issue is, but if `object` is of type `PFObject` then try `object["username"]`. Assuming your `object` is not nil of course. – Frankie Apr 30 '15 at 20:59
  • According to the Parse documentation I can set the variable using `object.username = x`. It works fine when getting variables from the object using `x = object.username` but yes perhaps the object is nil, I'll have a look into that. – mforrest Apr 30 '15 at 21:05