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 trialalexander88
10,824 PointsUse of unresolved identifier 'FoodVendingMachine'
Not sure where I went wrong. Below is my viewController.swift. followed by VendingMachine.Swift As far as I know FoodVendingMachine appears once in the file below but it appears as a class within VendingMachine.swift.
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!
let vendingMachine: VendingMachine
required init?(coder aDecoder: NSCoder) {
do {
let dictionary = try PlistConverter.dictionary(fromFile: "VendingInventory", ofType: "plist")
let inventory = try InventoryUnarchiver.vendingInventory(fromDictionary: dictionary)
//ERROR APPEARS BELOW
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()
print(vendingMachine.inventory)
}
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: 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() }
return cell
}
// MARK: - UICollectionViewDelegate
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
updateCell(having: indexPath, selected: true)
}
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
}
}
}
import Foundation
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
}
protocol VendingItem {
var price: Double { get }
var quantity: Int { get set }
}
protocol VendingMachine {
var selection: [VendingSelection] { get }
var inventory: [VendingSelection: VendingItem] { get set }
var amountDeposited: Double { get set }
init(inventory: [VendingSelection: VendingItem])
func vend(_ quantity: Int, _ selection: VendingSelection) throws
func deposit(_ amount: Double)
}
struct Item: VendingItem {
let price: Double
var quantity: Int
}
//Value types: enums and structs are things
//reference types: classes do things
//below, FoodVendingMachine works better as a class
//classes are good at modeling state, that is, the particular values in our data model in a point in time
enum InventoryError: Error {
case invalidResource
case conversionFailure
case invalidSelection
}
class PlistConverter {
static func dictionary(fromFile name:String, ofType type:String) throws -> [String: AnyObject] {
guard let path = Bundle.main.path(forResource: name, ofType: type) else {
throw InventoryError.invalidResource }
guard let dictionary = NSDictionary(contentsOfFile: path) as? [String: AnyObject] else {
throw InventoryError.conversionFailure
}
return dictionary
}
}
class InventoryUnarchiver {
static func vendingInventory(fromDictionary dictionary: [String: AnyObject]) throws -> [VendingSelection : VendingItem] {
var inventory: [VendingSelection : VendingItem] = [:]
for (key, value) in dictionary {
if let itemDictionary = value as? [String: Any], let price = itemDictionary["price"] as? Double,
let quanitity = itemDictionary["quantity"] as? Int {
let item = Item(price: price, quantity: quanitity)
guard let selection = VendingSelection(rawValue: key) else {
throw InventoryError.invalidSelection
}
inventory.updateValue(item, forKey: selection)
}
}
return inventory
}
}
class FoodVendingMachine: VendingMachine {
let selection: [VendingSelection] = [.soda, .dietSoda, .chips, .cookie, .wrap, .candyBar, .sandwich, .popTart, . fruitJuice, .gum, .sportsDrink ]
var inventory: [VendingSelection : VendingItem]
var amountDeposited: Double = 10
required init(inventory: [VendingSelection : VendingItem]) {
self.inventory = inventory
}
func vend(_ quantity: Int, _ selection: VendingSelection) throws {
}
func deposit(_ amount: Double) {
}
}
1 Answer
Brennan White
11,646 PointsNot sure if it's what is giving you the error, but your FoodVendingMachine has and extra space after the period.
. fruitJuice
instead of
.fruitJuice
in the selection