0

I am working on a Firebase Swift project using CocoaPods.

Every time after I log in the main ViewController, automatically I get EXC_BREAKPOINT error:

fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)

Here are some of my code lines where I got errors:

All codes from Joke.swift:

import Foundation
import Firebase


class Joke {
private var _jokeRef: Firebase!

private var _jokeKey: String!
private var _jokeText: String!


private var _jokeVotes: Int!


private var _username: String!

var jokeKey: String {
    return _jokeKey
}

var jokeText: String {
    return _jokeText
}

var jokeVotes: Int {
    return _jokeVotes //1
}

var username: String {
    return _username
}

// Initialize the new Joke

init(key: String, dictionary: Dictionary<String, AnyObject>) {
    self._jokeKey = key

    // Within the Joke, or Key, the following properties are children

    if let votes = dictionary["votes"] as? Int {
        self._jokeVotes = votes
    }

    if let joke = dictionary["jokeText"] as? String {
        self._jokeText = joke
    }

    if let user = dictionary["author"] as? String {
        self._username = user
    } else {
        self._username = ""
    }

    // The above properties are assigned to their key.

    self._jokeRef = DataService.dataService.JOKE_REF.childByAppendingPath(self._jokeKey)
}



// Add or Subtract a Vote from the Joke.

func addSubtractVote(addVote: Bool) {

    if addVote {
        _jokeVotes = _jokeVotes + 1
    } else {
        _jokeVotes = _jokeVotes - 1
    }

    // Save the new vote total.

    _jokeRef.childByAppendingPath("votes").setValue(_jokeVotes)

  } 
}

In JokeCellTableViewCell.swift:

var joke: Joke!
...............

func configureCell(joke: Joke) {

        self.joke = joke

        // Set the labels and textView.

        self.jokeText.text = joke.jokeText
        self.totalVotesLabel.text = "Total Votes: \(joke.jokeVotes)" // 2
        self.usernameLabel.text = joke.username

        // Set "votes" as a child of the current user in Firebase and save the joke's key in votes as a boolean.

.........
}

And in the main ViewController, JokesFeedTableViewController.swift:

var jokes = [Joke]()

....................


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {


    let joke = jokes[indexPath.row]

    // We are using a custom cell.

    if let cell = tableView.dequeueReusableCellWithIdentifier("JokeCellTableViewCell") as? JokeCellTableViewCell {

        // Send the single joke to configureCell() in JokeCellTableViewCell.

        cell.configureCell(joke) // 3

        return cell

    } else {

        return JokeCellTableViewCell()

    }
   ...........

// 1, // 2, // 3 are code lines where errors appear.

I hope you could help me to fix this!

Thank you in advance!

Razvan Julian
  • 59
  • 3
  • 14
  • What's `_jokeVotes`? – Hamish Mar 30 '16 at 07:58
  • Possible duplicate of [fatal error: unexpectedly found nil while unwrapping an Optional value](http://stackoverflow.com/questions/24948302/fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-value) – Fonix Mar 30 '16 at 07:59
  • @originaluser2 `var jokeVotes: Int { return _jokeVotes }` _jokeVotes is declared as Init – Razvan Julian Mar 30 '16 at 08:00
  • @Fonix, it's not right same. – Razvan Julian Mar 30 '16 at 08:11
  • Where do you initialise `_jokeVotes`? Have you set a breakpoint and used the debugger to step through and see what is nil? – Paulw11 Mar 30 '16 at 08:15
  • @Paulw11, I initialises `_jokeVotes` as Int at the top of the page: `private var _jokeVotes: Int!`. I used the debugger step by step to follow what's wrong, but it seems that hasn't changed anything. – Razvan Julian Mar 30 '16 at 08:30
  • That declares it as an implicitly unwrapped optional, but it doesn't initialise it. Since you made it an implicitly unwrapped optional with ! but never assigned a value you will get the exception when you,access it since you told Swift it wouldn't be nil with ! but it is – Paulw11 Mar 30 '16 at 08:32
  • @Paulw11, if I delete the "!" from initialization, I get errors on other functions. I updated the whole 'Joke.swift'. What do you guess I should do? – Razvan Julian Mar 30 '16 at 11:07
  • You need to understand the difference between declaration and initialisation. What you have is a declaration, and the ! says that you will initialise it later; ie give it an initial value. But you haven't done that so it is nil and you get a crash. `var _jokeVotes=0` both declares *and* initialises the variable – Paulw11 Mar 30 '16 at 11:43

1 Answers1

1

Your problem is that you have not clearly defined the expectations of the Joke class.

Your initializer suggests that the properties on Joke should be optional, however, you are using them as though they are not. You must decide on which way you want to take it.

If the properties can be optional, I would suggest something like this:

class Joke {
    private let jokeReference: Firebase

    let jokeKey: String

    private(set) var jokeText: String?

    private(set) var jokeVotes: Int?

    let username: String

    // Initialize the new Joke

    init(key: String, dictionary: Dictionary<String, AnyObject>) {
        jokeKey = key

        // Within the Joke, or Key, the following properties are children

        if let votes = dictionary["votes"] as? Int {
            jokeVotes = votes
        }

        if let joke = dictionary["jokeText"] as? String {
            jokeText = joke
        }

        if let user = dictionary["author"] as? String {
            username = user
        } else {
            username = ""
        }

        // The above properties are assigned to their key.

        jokeReference = DataService.dataService.JOKE_REF.childByAppendingPath(jokeKey)
    }
}

However, if the properties should never be nil, you need something like this:

class Joke {
    private let jokeReference: Firebase

    let jokeKey: String

    let jokeText: String

    let jokeVotes: Int?

    let username: String

    // Initialize the new Joke

    init?(key: String, dictionary: Dictionary<String, AnyObject>) {

        jokeKey = key

        guard let votes = dictionary["votes"] as? Int,
            joke = dictionary["jokeText"] as? String else {
                return nil
        }

        jokeText = joke
        jokeVotes = votes

        if let user = dictionary["author"] as? String {
            username = user
        } else {
            username = ""
        }

        // The above properties are assigned to their key.
        jokeReference = DataService.dataService.JOKE_REF.childByAppendingPath(jokeKey)
    }
}
Infinity James
  • 4,667
  • 5
  • 23
  • 36
  • Do you mean to replace it with something like that: 'private var jokeRef: Firebase! private(set) var jokeKey: String! private(set) var jokeText: String! private(set) var jokeVotes: Int! private(set) var username: String!'? – Razvan Julian Mar 30 '16 at 10:55