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

init? with guard statements

Can't seem to solve this one.

also, can't seem to attach my code with the checkmarked box when posting.

struct Book {

let title: String

let author: String

let price: String?

let pubDate: String?

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

guard let title = dict["title"], author = dict["author"] else {

    return nil

    }

    let price = dict["price"], pubDate = dict["pubDate"]

    return nil

    }

4 Answers

struct Book {

let title: String
let author: String
let price: String?
let pubDate: String?
init?(dict: [String: String]){

    guard let title = dict["title"], author = dict["author"] else {
        return nil
    }
    self.title = title
    self.author = author
    self.price = dict["price"]
    self.pubDate = dict["pubDate"]

}

}

Nathan Tallack
Nathan Tallack
22,160 Points

Yeah, this one was REALLY hard! A little too hard to be included I think. I had to read the Swift guide and play around in an Xcode playground for quite a while to work this out.

Consider this code:

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

    init?(dict: [String: String]) {
        if dict["title"] == nil { return nil }
        if dict["author"] == nil { return nil }

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

Because we have to force unwrap the title and author strings from the dictionary (which is VERY VERY bad and we were told again and again never to do this) we need to first check to ensure they are set. That is what the two if return nil statements are. Hence the optional init? for the dictionary.

In this way we can pass a dictionary that MUST have values for title and author and can optionally have values for price and pubDate (because those are declared as optional properties in our Struct).

Scary stuff. Better not to use optionals in a Struct methinks. ;)

PS: I think guard can only be used in enums. Not sure. Will have to go read about it again. :P

This one frustrated me. Thanks for working it out.

man, thats crazy! thought they were strongly hinting at guard statements from the preceding lessons. thanks!

Nathan Tallack
Nathan Tallack
22,160 Points

Thanks to Andrew Naeve's answer above, this is the CORRECT way to do it! No nasty forced unwrapping, and excellent use of the guard statement. :)

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

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

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

andrew naeve's answer and Nathan Tallack's second answer are correct (thanks, guys!!) except for a missing let keyword preceding the second statement in the guard statement (aka, 'author = ...'):

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"]
    }
}