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 trialcharlesdi
5,706 PointsBuild 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
2,180 PointsYoann NUSSBAUMER
2,180 PointsI've got the same problem and I fixed it in this way:
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.