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 trialAlistair Cooper
Courses Plus Student 7,020 Points! Use of undeclared type 'VendingSelection' compiler error
Hi there,
Next to all the uses of [VendingSelection] in the VendingMachineType protocol I'm getting a "! Use of undeclared type 'VendingSelection'" compiler error. Should the // Concrete Types section with the enum VendingSelection declaration go above the VendingMachineType protocol?
Thanks for any ideas!
protocol VendingMachineType {
var selection: [VendingSelection] { get } // get = it's a read only property
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)
}
Alistair Cooper
Courses Plus Student 7,020 PointsHi Martin,
Sorry, here's the whole code. I have a feeling it's painfully simple :^i Thanks for taking a look!
import Foundation
// Protocols
protocol VendingMachineType {
var selection: [VendingSelection] { get } // get = it's a read only property
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)
}
protocol ItemType {
var price: Double { get }
var quantity: Double { get set } // the quantity can change so it's get set
}
// Error Types
enum InventoryType: ErrorType {
case InvalidResource
case ConversionError
case InvalidKey
}
// 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 InventoryType.InvalidResource
} // .mainBundle() coresponds to app bundle for this app.
guard let dictionary = NSDictionary(contentsOfFile: path), let castDictionary = dictionary as? [String: AnyObject] else {
throw InventoryType.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 InventoryType.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
}
struct VendingItem: ItemType {
let price: Double
var quantity: Double
}
// VendingMachine is better as a class. Classes are good at modeling state
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 // setting an initial value to give user money to play with
// because it's required in the protocol we need the required keyword
required init(inventory: [VendingSelection : ItemType]) {
self.inventory = inventory
}
func vend(selection: VendingSelection, quantity: Double) throws {
// add code
}
func deposit(amount: Double) {
// add code
}
}
2 Answers
Martin Wildfeuer
Courses Plus Student 11,071 PointsHey there, thanks for posting your code! As far as I can tell the class PlistConverter
misses a closing bracket. That is
...
return inventory
}
}
} // This one is missing
Let me know if that solves your problem :)
Alistair Cooper
Courses Plus Student 7,020 Pointslol! oh dear. Yes that's it. Lesson learned. Thanks Martin! -A
Martin Wildfeuer
Courses Plus Student 11,071 PointsSure thing! :)
Martin Wildfeuer
Courses Plus Student 11,071 PointsMartin Wildfeuer
Courses Plus Student 11,071 PointsVendingSelection
needs to be defined somewhere in your code, but it seems to be missing. Can you post the definition ofVendingSelection
as well, please? It might shed some light on this, thanks :)