0

I have price list of ingredients, stored in Cloud Firestore. I want to calculate price for specific recepie, pass it to another VC and apply to label, so I wrote this code:

extension RecepiesViewController: UICollectionViewDelegate {
    //Passing data to next VC
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let destinationVC = segue.destination as! ResultViewController
        destinationVC.result = totalPrice
    }
    //Recepie cell pressed
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print("You selected cell #\(indexPath.item)!")
        // Calculating price for recepie
        func recepieCalculation(_ completion: @escaping (Double) ->()) {     
            for ingridients in cakeRecepies![indexPath.item].ingridientList {
                db.collection("Okey")
                    .document(ingridients.name)
                    .getDocument() { (document, error) in
                        if let document = document, document.exists {
                            let data = document.data()
                            if let price = data!["price"] as? Double, let count = data!["count"] as? Int  {
                                let priceForOne = price / Double(count)
                                self.totalPrice = self.totalPrice + priceForOne * Double(ingridients.count)
                            }
                        } else {
                            print("Document does not exist")
                        }
                        completion(self.totalPrice)
                }
            }
        }
        recepieCalculation {totalPrice in
            self.performSegue(withIdentifier: "goToResult", sender: self)
        }
    }
}

Another VC code:

import Foundation
import UIKit
import RealmSwift

class ResultViewController: UIViewController {

    @IBOutlet weak var resultLabel: UILabel!
    var result: Double = 0.0 {
        didSet {
            print(result)
            resultLabel.text = String(format: ".%f", result)
        }
    }
    @IBOutlet weak var recepieImage: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

And at line resultLabel.text = String(format: ".%f", result) got error

Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

What could be wrong?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Does this answer your question? [What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean?](https://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu) – user28434'mstep Jun 03 '20 at 12:44
  • 1
    looks like your label outlet is not connected to storyboard. – kishan vekariya Jun 03 '20 at 12:44
  • 1. No, I don't have any force unwrappers "!" . 2. Label was connected, checked it twice – Max Gavrilov Jun 03 '20 at 12:53
  • @MaxGavrilov, `1. No, I don't have any force unwrappers "!" .` — **false**: `@IBOutlet weak var resultLabel: UILabel!` – user28434'mstep Jun 03 '20 at 13:14
  • Also, before `viewDidLoad` is called **all** outlets are `nil`. So if `didSet` for `result` is called before `viewDidLoad`, then `resultLabel` is `nil`. – user28434'mstep Jun 03 '20 at 13:15
  • 'Also, before viewDidLoad is called all outlets are nil. So if didSet for result is called before viewDidLoad, then resultLabel is nil. 'Thanks, didn't know about that – Max Gavrilov Jun 03 '20 at 13:26

1 Answers1

2

This is a common mistake.

At the moment the destination controller of the segue is going to be presented the outlets are not connected yet, so assigning the value to the label in the didSet observer crashes.

Solution:

  • Delete the observer

    var result = 0.0 
    
  • and assign the value in viewDidLoad

    override func viewDidLoad() {
        super.viewDidLoad()
        print(result)
        resultLabel.text = String(format: ".%f", result)
    }
    
vadian
  • 274,689
  • 30
  • 353
  • 361