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 Type Casting

Taylor Smith
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Taylor Smith
iOS Development Techdegree Graduate 14,153 Points

Build a vending machine app...wth am I watching

Pasan starts off this course saying he was afraid it was moving too fast. well....I think he's right. every video I watch I have to spend 30 minutes researching what the heck he was talking about. There's a lack of explanation for a lot of things..."we need to downcast this typcast because of objects to any objects so we code this," I'm being facetious... but that's how it sounds, and it's ultra confusing. Makes me feel like I haven't learned what I should have at this point...anyone else feel this way or is it just me?

11 Answers

Cameron Hyatt
Cameron Hyatt
5,948 Points

I'm glad I'm not alone. Not everything is easily understood and I'm still having a hard time finding the logic and reason to Pasan's decisions before he actually does it and explains it. I feel like I just took Swift 101 and then getting thrown into a third year class. Is the rest of the material going to feel the same after we finish the Vending Machine app? Should I repeat this project once or twice more until I really understand it?

I feel the same way as well. At times i'm very lost and it makes me feel like i havent learned anything so far. It's sort of frustrating at times i must admit.

Ovidiu Tepes
Ovidiu Tepes
2,424 Points

I'm almost at the end of the Vending Machine course and I decided to check the community, hoping that I'm not the only one that finds extremely difficult to follow. Been watching the entire course using .75 speed and pausing every 2 minutes.

Jhoan Arango
Jhoan Arango
14,575 Points

Welcome to the developer's world. It will get better I promise.

Robert Cadorette
Robert Cadorette
9,275 Points

@Xavier Thanks for posting this. Regarding the super/sub/base class diagram, when I questioned what I saw, it convinced me I officially know nothing. This vid was defeating first time around. To anyone reading this, you are not alone, keep pushing forward!

Also: I highly recommend Big Nerd Ranch guide to Swift, 2nd edition as a resource. Going cover to cover as a supplement will drive a lot of this stuff home.

I found Big Nerd Raunch superior in a number of ways to the material I encountered here. Highly recommended. I would suggest going through the book ahead of what is presented here, thereby making the videos more akin to a review.

Olivier Van hamme
Olivier Van hamme
5,418 Points

I did find the diagram [4:39] confusing as well. Isn't the superclass another word for base class? My understanding is that the subclass inherits from the base class.

In the diagram, the base class is right at the bottom, while it is supposed to be at the top.

Xavier D
PLUS
Xavier D
Courses Plus Student 5,840 Points

Hi,

I think one of the more complicated parts was when Pasan stepped away from the project to explain the as and if operators using the employee example. When Pasan says employee, it could be the employee array, it could be the Employee class, it could mean employee as the local constant in the for statement, and it could be employee in the if statement.

So what I did to try and make things easier for myself was to type out what he said (word for word), and then modify his words that I needed more clarification on. Below are my notes for this video, I hope I didn't add more confusion on the matter...

class Employee
{
    let name: String

    init(name: String)
    {
        self.name = name
    }
}

class HourlyEmployee: Employee
{
    let hourlyWage: Double

    init(name: String, hourlyWage: Double)
    {
        self.hourlyWage = hourlyWage
        super.init(name: name)
    }

    func payWages(for hours: Double) -> Double
    {
        return hourlyWage * hours
    }
}

class SalariedEmployee: Employee
{
    let salary: Double

    init(name: String, salary: Double)
    {
        self.salary = salary
        super.init(name: name)
    }

    func paySalary() -> Double
    {
        return salary/24
    }
}

let hourlyEmployee = HourlyEmployee(name: "Taylor", hourlyWage: 12.00)
let salariedEmployee = SalariedEmployee(name: "Lorenzo", salary: 62000)

let employees = [hourlyEmployee, salariedEmployee]
// We know from learning about arrays that Swift arrays can only contain a single type; however, ypu can mix types in an array if all the array items have a common base type. When we mix and match them in the array, Swift converts or cast each object to the base type, to satisfy the array homogeneity rule.

for employee in employees // currently this will not work to access object methods (unless there are base/super class methods)
{
}

/*
 To actually use this instance in the right context, we can either check that it is the right type that we need or downcast them to a different type--there are two operators to help accomplish this task.

 The 'is' operator returns true if the type matches a type we specify and false if not. Thus, we can use it to inspect each item the array.
 */

for employee in employees // currently this will not work to access object methods (unless there are base/super class methods)
{
    if employee is HourlyEmployee
    {
        print("Hourly")
    }

    if employee is SalariedEmployee
    {
        print("Salaried")
    }
}

/*
 Even though the employee array thinks that its items are of the base classes type, we can check each array item to see if they are instances of a particular sub class (i.e. using the 'is' operator inside the for loop's if statements to check each item in the local constant of the if statement to see if items inherit from Hourhly Employee and from SalariedEmployee). Now we don't want to get into the details of how this is done exactly in the background, but just know that even though that each item in the array are of the employee base class, each array item also contains information on any subclasses they inherit from. But all this allows us to do is check it right (i.e. using the 'is' operator to check.)? We still can't call the payWages function on the hourlyEmployee instance or paySalary on the salariedEmployee instance using just the 'is' operator since both are inside the same array that's contrained to the base class of those instances.

 What if we want to actually work with the specific subtypes? For that, we have another operator, the Typecast operator, 'as'. The Employee class, in this example, is a higher less specific type than than any of the subclasses (i.e. the HourlyEmployee and the SalariedEmployee subclasses.). The 'as' operator allows you to cast to one of the more specific subclasses in a process know as 'downcasting'. It's called downcasting because if you think of the object graph as a tree, the base type on top, and more specific types as nodes extending downwards, then when going from a base, to a subclass we go down the tree.

 Downcasting may not always succeed. So the typecast operator comes in two different flavors, the conditional form as with a question mark, and the forced form, as with an exclamation point. The forced form, like the force unwrap operator, should only be used when you know the downcast will succeed.

 For example, in our code, we verified that an employee instance is of a particular type by using the type check operator (i.e. the 'is' operator). We know that the local constant of the if statement named 'employee' here is an instance of the HourlyEmployee subclass for sure. So inside the if statement, we can use the Forced operator to downcast the instance.
 */

for employee in employees // now this works
{
    if employee is HourlyEmployee
    {
        print("Hourly")
        let hourlyEmployee = employee as! HourlyEmployee
        hourlyEmployee.payWages(for: 10.00)
    }

    if employee is SalariedEmployee
    {
        print("Salaried")
        let salariedEmployee = employee as! SalariedEmployee
    }
}

/*
 The Forced Downcast operater, like the Forced Unwrap operator, should be treated carefully. Only used the Forect Downcast operator ony if you're 110% sure the downcast will succeed, otherwise your application will crash.

 For a safer option, you can use the Conditional Typecast operator as with a question mark. This operator returns an optional value if the cast succeeds or nil if it fails.
 */

for employee in employees // now this works
{
    if employee is HourlyEmployee
    {
        print("Hourly")
        let hourlyEmployee = employee as? HourlyEmployee // using Conditional Typecast operator along with...
        hourlyEmployee?.payWages(for: 10.00) // ...optional chaining

    }

    if employee is SalariedEmployee
    {
        print("Salaried")
        let salariedEmployee = employee as? SalariedEmployee // using Conditional Typecast operator along with...
        salariedEmployee?.paySalary() // ...optional chaining
    }
}




for employee in employees // now this works
{
    if employee is HourlyEmployee
    {
        print("Hourly")
        if let hourlyEmployee = employee as? HourlyEmployee // using if let along with the Conditional Typecast operator
        {
            hourlyEmployee.payWages(for: 10.00)
        }

    }

    if employee is SalariedEmployee
    {
        print("Salaried")
        if let salariedEmployee = employee as? SalariedEmployee  // using if let along with the Conditional Typecast operator
        {
            salariedEmployee.paySalary()
        }
    }
}

BTW: I think I noticed an error in the video....not with Pasan, but the tree diagram/object graph that Pasan uses to explain downcasting. At around 4:42, the graph shows the top blue box labeled "Superclass". Pasan explains that with downcasting, you travel down the tree to the bottom nodes, and the bottom nodes are to be the subclasses of the top node, since the top node is labeled as the superclass node. However, the bottom nodes have a label next to it called "Base Class". To my knowledge, base class and superclass are two terms that mean the same thing. I believe that the bottom nodes should have a sub class label.

XD

Jhoan Arango
Jhoan Arango
14,575 Points

Hello:

No, it's not you, I was lost in the exact same place where he says " downcasting ". But that actually helped me research and learn about it. Treehouse will not teach you every single thing about swift, so sometimes you need to do some research on your own. And it's ok to feel lost, this is a new language you are learning, and it requires time and research plus practice. Keep it up, and everything will make sense with time.

If you have any questions about anything about this course, don't hesitate to ask here.

Good luck

Xavier D
PLUS
Xavier D
Courses Plus Student 5,840 Points

Thanks for the guide info, I will check into that! I too recently bumped into a beginner resource called Hacking with Swift (HWS). What interested me was that it advertised lots of gaming examples, and I love video games! What interested me more was that there was a free version, thus I decided to drive right in being that there's a chapter dealing with Sprite Kit.

There's a course here dealing with it here...but... (stammers)...but the one doing the course is the same one who I remember doing the crystal ball app when I was trying to learn Objective-C back in 2014. Around that time, there was an instructor named Douglass explaining C-- I really liked his learning style very much, and Pasan's style remind me of him. But when it came to Objective-C and the crystal ball app, it was a different instructor..and I found it real difficult to find a deeper understanding in his code example explanations....so... I delay in viewing that course on Sprite Kit...however, the learning style may have gotten better over time.and he really made me appreciate how Pasan teaches Swift.

Anywho, I almost completed the free HWS,--it's really short and Sprite Kit is up next...and as I'm finishing that up, it makes me appreciate everything I learned here. I'm zipping through it and the info I gathered here helped a lot. I do hope Pasan explains Sprite Kit one day.

Nathania Johnson
Nathania Johnson
7,637 Points

You're not alone. The Vending Machine App lesson feels like a huge leap to me. Up until now, I have felt the class to be fairly well-paced, especially compared to other sites I've tried to learn programming from. But I'm pretty lost with this project. I have peeked ahead at Introduction to Auto Layout and it's back to being well-paced. I hope I'm not completely lost when I try Intermediate.

Ben Payne
Ben Payne
3,549 Points

I think I share everyone's sentiment in viewing the Vending Machine app as a big jump from the preceding content. I'm wondering if everyone who feels this way should pause review, and ensure they understand Vending Machine before proceeding to Introduction to Auto Layout/Intermediate Swift? Or would it be a more efficient use of time to go directly to Auto Layout/Intermediate Swift despite feeling a little confused over Vending Machine?

Johnny Nguyen
Johnny Nguyen
3,875 Points

It's not too hard but what I find lost is how to apply it to our own app.

I also agree, glad everyone is on the same page. There's really no other way around looking at more tutorials if you are still lost.