LAST CHANCE: Save 50% on all my Swift books and bundles! >>

SOLVED: Solving Checkpoint 8

Forums > 100 Days of SwiftUI

Can anyone help me evaluate if what I'm doing here is correct?

// HWS Checkpoint 8
// Make a protocol that describes a building
// Your protocol should require the following:
//     A property storing how many rooms it has
//     A property storing the cost as an Integer
//     A property storing the name of the estate agent selling the building
//     A method for printing the sales summary of the building
// Create two structs, House and Office, that conform to our protocol

protocol Building {
    var rooms: Int {get set}
    var cost: Int {get set}
    var agentName: String {get set}

    func salesSummary()
}

extension Building {
    func salesSummary() {
        print("The building has \(rooms) rooms and it costs \(cost) USD in total.")
        print("This building is handled by \(agentName).")
    }
}

struct House: Building {
    var rooms = 8
    var cost = 100000000
    var agentName = "Mr House Agent"
}

struct Office: Building {
    var rooms = 50
    var cost = 500000000
    var agentName = "Mr Johnny English"
}

let myHouse = House()
myHouse.salesSummary()

let myOffice = Office()
myOffice.salesSummary()

3      

@swiftHacker wonders if they're following the protocol:

Can anyone help me evaluate if what I'm doing here is correct?

Well done!

I ran your code in a Playground and both the structs House and Office conform to the Building protocol and the salesSummary() function reports the correct values.

So I'd say "yes, what you did is correct."

Keep Coding

However, you may not appreciate the full value of a protocol's requirement to have a particular function.

Both House and Office use the protocol's default salesSummary() function. But a protocol only requires that you HAVE the named function. HOW you implement the function is up to you.

Look at the code below. I implemented a different version of salesSummary() for the Office struct.

struct Office: Building {
    // these three vars are required by the protocol
    var rooms      = 50                    // default
    var cost       = 500000000             // default
    var agentName  = "Mr Johnny English"   // default
    var floorCount = 4  // not required by the protocol

    // the Building protocol requires a function named salesSummary
    // that returns void. 
    // The protocol doesn't care WHAT is does, only that it exists.
    func salesSummary() {
        print("This building has \(rooms) offices on \(floorCount) floors.")
    }
}

3      

I see. So basically, I can still change what the function does I only need to ensure that the function name is the same as what's in the protocol. I can then somehow "override" it (change what the function does) so that it can be something else entirely. Is my understanding correct?

3      

A follow on question:

I can then somehow change what the function does so that it can be something else entirely. Is my understanding correct?

Yes!

Comparable Protocol

Think of the Comparable protocol. What does this protocol provide your struct? What does it do?

It allows you to write a custom struct for your application (House, Lego, Employee, Spaceship) and enjoy the benefits of being able to compare and sort them using built in Swift capabilities.

Sorting two objects is subjective. The rules change for every object in existence. So the Comparable protocol doesn't care HOW you implement its function, only that you DO implement its compare function.

Try it!

First tell your Office struct that is must conform to Building, but also to the Comparable protocol.

struct Office: Building, Comparable {    // <-- Here! Add the comparible protocol
    // these three vars are required by the Building protocol
    var rooms      = 50                    // default
    var cost       = 500000000             // default

    // .... snip ....
}

Xcode will complain that the Office struct does not conform to the Comparable protocol. Why?

Allow Xcode to automagically fix the error by adding the proper protocol stub. You should now see this...

struct Office: Building, Comparable {
    // This func was added by Xcode.
    // You have to implement this function to conform to the Comparable protocol.
    // ----------- IMPLEMENT THIS 
    static func < (lhs: Office, rhs: Office) -> Bool {
        <#code#>
    }
    // -----------

lhs? rhs? What does this even mean?

Your Job

You are the programmer. You speak to your users. Get their requirements and code them! It is YOUR JOB to determine how you compare two Office buildings. If I were to put two offices in front of you, what is YOUR criteria for sorting them?

As an example, let's go with NUMBER OF FLOORS. lhs is shorthand for Left Hand Side, rhs is shorthand for Right Hand Side. If the right hand building has MORE FLOORS than the left hand building, then the right hand building is "larger" than the right hand one.

So code your static func like so. (By the way, the symbol < is the function name! )

struct Office: Building, Comparable {
    // Implement the Comparable protocol
    static func < (lhs: Office, rhs: Office) -> Bool {
        // This compares the left office's floor count
        // to the right offices's floor count
        // it returns TRUE if the left floor count is less than
        // the right floor count.
        lhs.floorCount < rhs.floorCount
    }
    // .... snip ......

How does this help me?

Now that you've defined what a office building is (floors, offices, cost, etc) You can now create a collection of offices in your application. Because your Office also conforms to the Comparable protocol, you now have the superpower to SORT them added as a bonus.

Try this....

// Create three offices and stuff them into an array.
var offices = [ Office(floorCount: 12), Office(floorCount: 5), Office(floorCount: 13)]

// Yowza! 
// Super easy to sort them by YOUR criteria because you conform to Comparable
offices.sorted().forEach{print("Floors: \($0.floorCount)")} // <- Print the sorted() results

Homework

Imagine you created a struct describing a Lego brick (color, shape, number of pips, etc) Your team creates a wonderful Lego kit and gives you a list of all the required parts. Your SwiftUI application takes all the pieces and stores them in a large array named kitPieces.

Now think! How would YOU sort the Lego bricks in the kitPieces array? By color, then by pips? It's your program, you get to decide how the Comparable protocol is implemented.

And keep this in mind! The rules you use to sort two Lego bricks are wildly different from the way I would sort two Student structs. Yet we can both use the array's .sorted() method to sort our different arrays. How? We both conform to the Comparable protocol. Super Power!

Keep Coding!

5      

Hacking with Swift is sponsored by Essential Developer.

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until July 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.