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 Loading Data From a Resource Finishing Touches

Alex Chapple
Alex Chapple
3,196 Points

I keep getting Fatal Error with invalidSelection! What is wrong here?

This is my code. Is there anything wrong in here? I followed all the steps.

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 quantity = itemDictionary["quantity"] as? Int {
            let item = Item(price: price, quantity: quantity)

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

          inventory.updateValue(item, forKey: selection)

        }
    }



    return inventory
}

}

9 Answers

Jeff McDivitt
Jeff McDivitt
23,970 Points

I see at least one error; here is the correct code; see if you can spot it

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 quantity = itemDictionary["quantity"] as? Int{
                let item = Item(price : price, quantity : quantity)

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

                inventory.updateValue(item, forKey: selection)
            }
        }

        return inventory
    }

}
Alex Chapple
Alex Chapple
3,196 Points

I still get the fatal error after making the corrections. Heres the full code.

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 }

enum InventoryError: Error { case invalidResource case conversionFailure case InvalidSelection }

class PlistConvertor { 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 quantity = itemDictionary["quantity"] as? Int{
            let item = Item(price : price, quantity : quantity)

            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, .sandwich, .candyBar, .popTart, .water, .fruitjuice, .sportsDrink, .gum ]

var inventory: [VendingSelection : VendingItem]
var amountDeposited: Double = 10.00

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

}


func vend(_ quantity: Int, _ selection: VendingSelection) throws { }

func deposit(_ amount: Double) { }

}

Jeff McDivitt
Jeff McDivitt
23,970 Points

What exactly is the error saying?

Alex Chapple
Alex Chapple
3,196 Points

This is what it says next to the console that says fatal error.

aDecoder NSCoder 0x00007f8c7380ae00 self VendingMachine.ViewController 0x00007f8c71e0a770 error VendingMachine.InventoryError invalidResource dictionary [String : AnyObject]
inventory [VendingMachine.VendingSelection : VendingItem]

Jeff McDivitt
Jeff McDivitt
23,970 Points

Is this after refactoring the code?

Alex Chapple
Alex Chapple
3,196 Points

yes, after i put in the code you have given me

Alex Chapple
Alex Chapple
3,196 Points

would it be possible for you to give me the correct xcode file because I can't continue without it working?

Jeff McDivitt
Jeff McDivitt
23,970 Points

I did not refactor mine but I can give you the code if you would like. What is your email?

sabath rodriguez
sabath rodriguez
11,055 Points

literally the exact same thing, I have the exact code that is written and Ive read and re-read it and everything looks good. can you help me out please?