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 Swift 2.0 Enumerations and Optionals Introduction to Optionals Initializing Optional Values

ok, i used the ! operator and shouldn't have..

I used the bang operator to solve this and know I should't have.. but am at a loss as to how to approach this without doing it. any pointers?

struct Book {

    let title: String

    let author: String

    let price: String?

    let pubDate: String?

    init?(dict: [String: String]){

        self.title = dict["title"]!

        self.author = dict["author"]!

        self.price = dict["price"]

        self.pubDate = dict["pubDate"]


    }

}

2 Answers

Danny Yassine
Danny Yassine
9,136 Points

Looking at your Struct, you are saying that a Book must have a Title and author, but price and pubDate are of Optional type, thus these two properties don't need to be initializes with a value when you are initializing/creating your Struct.

For title and author properties, when beeing initialized, the value being passed to them must be true and "not-nil". Thats why you had to put the bang operator when accessing your dictionary for "title" and "author". If a value of nil was to come from the dictionary, it would create a run-time error. Since swift can detect that, you had to pit "!" to remove the error.

For price and pubDate properties, if the value in the dictionary for "price" and "pubDate" are nil, thats ok, because those two properties are optionals and they can be nil. Thats why you don't need the bang operator for them.

So its also up to you on how you want to build your models if some properties will be optionals or not.

here's the link for the Optionals in the Swift Programming Book, Look for the OPTIONALS header:

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID330

Thanks Danny, that helps a lot!

Hey Andrew,

I'm finding it difficult to elucidate exactly why force unwrapping an Optional is so "bad" so maybe Pasan Premaratne can add some words here. Nonetheless, here is one way to create this Struct without force unwrapping each non-Optional:

struct Book {
    let title: String
    let author: String
    let price: String?
    let pubDate: String?

    init?(dict: [String: String]) {
        guard let title = dict["title"], let author = dict["author"] else {
            return nil
        }

        self.title = title
        self.author = author
        self.price = dict["price"]
        self.pubDate = dict["pubDate"]
    }

}
Pasan Premaratne
Pasan Premaratne
Treehouse Teacher

In this instance, your data to initialize Book is obtained from a dictionary that you pass in when creating the struct. Let's say this dictionary is something that you get by hitting a 3rd party web service. There is no way to guarantee that the response dictionary will always contain the values you're expecting (the API may change, your connection may drop resulting in incomplete data, etc). Let's assume 90% of the time the data is correct but 10% of the time the author key is missing for some books. In that 10% case, this line of code

self.author = dict["author"]!

will cause the app to crash completely with no information provided to the user. So rather than being safe, the ! operator does the exact opposite and creates unsafe code. The Swift team named it the force unwrap operator to indicate that you are working against the goal of safety and forcing your code to do something it really shouldnt.

Awesome Pasan! Thanks for clearing that up. I was trying to explain but my brain wouldn't cooperate; I kept typing and deleting and typing and deleting...