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 2.0 Displaying Additional Views Controlling Custom Views

Build Fail: Type 'VendingMachine' does not conform to protocol 'VendingMachineType'

I've finished the app and I have one error. The error occurs on the class VendingMachine: VendingMachineType

I have downloaded Pasan's code and I can't seem to find the discrepancy that is causing the problem. Did I miss something or am I looking in the wrong area?

Full code:

// // VendingMachine.swift // VendingMachine // // Created by Charles Di Renzo on 8/17/16. // Copyright © 2016 Treehouse. All rights reserved. //

import Foundation import UIKit

//protocols

protocol VendingMachineType { var selection: [VendingSelection] { get } var inventory: [VendingSelection: ItemType] { get set } var amountDeposited: Double { get set }

init(inventory: [VendingSelection: ItemType])
func vend(selection: VendingSelection, quantity: Double) throws
func deposit(amount: Double)
func itemForCurrentSelection(selection: VendingSelection) -> ItemType?

}

protocol ItemType { var price: Double { get } var quantity: Double { get set } }

//Error Types

enum InventoryError: ErrorType { case InvalidResource case ConversionError case InvalidKey }

enum VendingMachineError: ErrorType { case InvalidSelection case OutOfStock case InsufficientFunds(required: Double) //this associate value will tell the user how much they have }

//Helper Classes

//this is a type method class PlistConverter { class func dictionaryFromFile(resource: String, ofType type: String) throws -> [String : AnyObject] {

    guard let path = NSBundle.mainBundle().pathForResource(resource, ofType: type) else {
            throw InventoryError.InvalidResource
    }

    guard let dictionary = NSDictionary(contentsOfFile: path), let castDictionary = dictionary as? [String: AnyObject] else {
            throw InventoryError.ConversionError
    }
    return castDictionary
}

}

class InventoryUnarchiver { class func vendingInventoryFromDictionary(dictionary: [String: AnyObject]) throws -> [VendingSelection : ItemType] {

    var inventory: [VendingSelection : ItemType] = [:]

    for(key, value) in dictionary {
        if let itemDict = value as? [String: Double], let price = itemDict["price"], let quantity = itemDict["quantity"] {


            let item = VendingItem(price: price, quantity: quantity)

            guard let key = VendingSelection(rawValue: key) else {
                throw InventoryError.InvalidKey
            }

            inventory.updateValue(item, forKey: key)

        }
    }
        return inventory
}

}

//Concrete Types //look into raw values here, they become important

enum VendingSelection: String { case Soda case DietSoda case Chips case Cookie case Sandwich case Wrap case CandyBar case PopTart case Water case FruitJuice case SportsDrink case Gum

func icon() -> UIImage {
    if let image = UIImage(named: self.rawValue) {
        return image
    } else {
        return UIImage(named: "Default")!
    }
}

}

struct VendingItem: ItemType { let price: Double var quantity: Double }

class VendingMachine: VendingMachineType {

let selection: [VendingSelection] = [.Soda, .DietSoda, .Chips, .Cookie, .Sandwich, .Wrap, .CandyBar, .PopTart, .Water, .FruitJuice, .SportsDrink, .Gum]

var inventory: [VendingSelection: ItemType]
var amountDesposited: Double = 10.0

required init(inventory: [VendingSelection : ItemType]) {
    self.inventory = inventory
}

func vend(selection: VendingSelection, quantity: Double) throws {
    guard var item = inventory[selection] else {
        throw VendingMachineError.InvalidSelection
    }

    guard item.quantity > 0 else {
        throw VendingMachineError.OutOfStock
    }
    //at this point we have an item and a quantity implement a cancel button as homework here. 

    //time to reduce quantity by amount purchased

    item.quantity -= quantity
    inventory.updateValue(item, forKey: selection)


    //here we are checking to see if we have enough money and throwing an error if they do not
    let totalPrice = item.price * quantity
    if amountDesposited >= totalPrice {
        amountDesposited -= totalPrice
    } else {
        let amountRequired = totalPrice - amountDesposited
        throw VendingMachineError.InsufficientFunds(required: amountRequired)
    }
}

func itemForCurrentSelection(selection: VendingSelection) -> ItemType? {
    return inventory[selection]
}

func deposit(amount: Double) {
    amountDesposited += amount
}

}

Yoann NUSSBAUMER
Yoann NUSSBAUMER
2,180 Points

I've got the same problem and I fixed it in this way:

struct VendingItem: ItemType {
    let price: Double = 0.0
    var quantity: Double = 0.0
    var amountDeposited: Double = 0.0
}

But I still don't understand why it's working in the video and not in my compiler. Maybe the version of Swift is slightly different.