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

philip williams
philip williams
5,991 Points

Why is VendingMachine not conforming to protocol VendingMachineType? I can't figure this one out.

//
//  VendingMachine.swift
//  VendingMachine
//
//  Created by Phil Williams on 30/03/2016.
//  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)
}

// Helper Classes

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 vendingFromDictionary(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

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 amountDeposited: 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
        }

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

        let totalPrice = item.price * quantity
        if amountDeposited >= totalPrice {
            amountDeposited -= totalPrice
        } else {
            let amountRequired = totalPrice - amountDeposited
            throw VendingMachineError.InsufficientFunds(required: amountRequired)
        }
    }

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

    func deposit(amount: Double) {
        // add code
    }
}

2 Answers

Guillem Servera
Guillem Servera
12,747 Points

There's a typo in the declaration of your function itemForCurrentSelection: Seems like you accidentally typed Cureent! :)