Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Build a Vending Machine App in Swift Using the Vending Machine Updating the Quantity

Rea Rahhal
PLUS
Rea Rahhal
Courses Plus Student 4,732 Points

Use of unresolved identifier totalPrice? what's wrong

import UIKit

fileprivate let reuseIdentifier = "vendingItem" fileprivate let screenWidth = UIScreen.main.bounds.width

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {

@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet weak var totalLabel: UILabel!
@IBOutlet weak var balanceLabel: UILabel!
@IBOutlet weak var quantityLabel: UILabel!
@IBOutlet weak var priceLabel: UILabel!


@IBOutlet weak var quantityStepper: UIStepper!


let vendingMachine:VendingMachine
var currentSelection:VendingMachine?//to store the selection

required init?(coder aDecoder: NSCoder) {
    do{
        //use type methods,take plist and cinvert it to dictionary
        let dictionary = try PListConverter.dictionary(fromFile: "VendingInventory", ofType: "plist")
        //once we have a dict we can fgo and create an inventory
        let inventory = try InventoryUnarchiver.vendingInventory(fromDictionary: dictionary)
       self.vendingMachine = FoodVendingMachine(inventory: inventory)

    }catch let error{
        fatalError("\(error)")
    }
    super.init(coder: aDecoder)
}




override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    setupCollectionViewCells()
    balanceLabel.text = "$\(vendingMachine.amountDeposited)"
    totalLabel.text = "$00.00"
    priceLabel.text = "$0.00"    }

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Setup

func setupCollectionViewCells() {
    let layout = UICollectionViewFlowLayout()
    layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 20, right: 0)

    let padding: CGFloat = 10
    let itemWidth = screenWidth/3 - padding
    let itemHeight = screenWidth/3 - padding

    layout.itemSize = CGSize(width: itemWidth, height: itemHeight)
    layout.minimumLineSpacing = 10
    layout.minimumInteritemSpacing = 10

    collectionView.collectionViewLayout = layout
}

//MARK:- Vending

@IBAction func purchase() {
    if let currentSelection = currentSelection{

        do{
            try vendingMachine.vend(selection: currentSelection as! VendingSelection, quantity:Int(quantityStepper.value))
            updateDisplayWith(balance: vendingMachine.amountDeposited,totalPrice:0.0,itemPrice: 0,itemQuantity:1)
        }catch{
            //error handling code 
        }
        if let indexPath = collectionView.indexPathsForSelectedItems?.first{
            collectionView.deselectItem(at: indexPath, animated: true)
            updateCell(having: indexPath, selected: false)
            quantityStepper.value = 1 //everytime we select a new item the quantity goes back to 1 (whenever an item is selected)
            quantityLabel.text = "1"
           // quantity = 1

        }

    }else{
        //alert user to  no selection
    }
}
func updateDisplayWith(balance: Double? = nil, totalPrice? = nil,itemPrice:Double? = nil,itemQuantity : Int? = nil){

    if let balanceValue = balance {

balanceLabel.text = "$(balanceValue)" }

    if let totalValue = totalPrice{

totalLabel.text = "$(totalValue)" }

    if let priceValue = itemPrice{
      priceLabel.text = "$\(priceValue)"
    }

    if let quantityValue = itemQuantity{
        quantityLabel.text = "$\(quantityValue)"
    }

}

func updateTotalPrice( for item : VendingItem){
    totalLabel.text = "\(item.price * quantityStepper.value)"
}


@IBAction func updateQuantity(_ sender: UIStepper) {

    quantityLabel.text = "\(Int(quantityStepper.value))"

    if let currentSelection = currentSelection,let item = vendingMachine.item(forSelection: (currentSelection as? VendingSelection)!){
        updateTotalPrice(for: item)
    }
}


// MARK: UICollectionViewDataSource


func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return vendingMachine.selection.count
}


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as? VendingItemCell else { fatalError() }
    let item = vendingMachine.selection[indexPath.row]//inddex value is stored into index path
    cell.iconView.image = item.icon()
    return cell
}

// MARK: - UICollectionViewDelegate

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    updateCell(having: indexPath, selected: true)

    quantityStepper.value = 1
    quantityLabel.text = "1"
   // quantity = 1
    totalLabel.text = "$00.00"







    currentSelection = vendingMachine.selection[indexPath.row] as? VendingMachine
    if let currentSelection = currentSelection,let item = vendingMachine.item(forSelection: (currentSelection as? VendingSelection)!){


        priceLabel.text = "$\(item.price)"
        totalLabel.text = "$\(item.price * quantityStepper.value)"
    }
}

func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
    updateCell(having: indexPath, selected: false)
}

func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) {
    updateCell(having: indexPath, selected: true)
}

func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) {
    updateCell(having: indexPath, selected: false)
}

func updateCell(having indexPath: IndexPath, selected: Bool) {

    let selectedBackgroundColor = UIColor(red: 41/255.0, green: 211/255.0, blue: 241/255.0, alpha: 1.0)
    let defaultBackgroundColor = UIColor(red: 27/255.0, green: 32/255.0, blue: 36/255.0, alpha: 1.0)

    if let cell = collectionView.cellForItem(at: indexPath) {
        cell.contentView.backgroundColor = selected ? selectedBackgroundColor : defaultBackgroundColor
    }
}

}

1 Answer

Magnus Hållberg
Magnus Hållberg
17,232 Points

Since its not clear from the question where this error comes from its hard to say. One place it could be is in the "IBAction func purchase" where you are calling the "updateDisplayWith" function. Swift (and probably other programming languages) are picky with spaces. Try adding spaces after the commas and colons, like below.

updateDisplayWith(balance: vendingMachine.amountDeposited, totalPrice: 0.0, itemPrice: 0, itemQuantity: 1)

Hope this helps. /M