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 trialMartel Storm
4,157 Pointsinitializing optional layers Code Challenge
Sorry my life and code is a mess. Can someone provide the answer and explain a bit?
struct Book {
let title: String
let author: String
let price: String?
let pubDate: String?
init? (dict: [String : String]) {
guard let Book = title ["title"], let author = ["author"],
else {
return nil}
let price = bookPrice ["price"]
return Book(dict)
}
}
1 Answer
Dan Lindsay
39,611 PointsHey Martel,
To help with understanding, first look at how we do an init method for a class that has no optional properties:
class BookNoOptionals {
let title: String
let author: String
let price: String
let pubDate: String
init(title: String, author: String, price: String, pubDate: String) {
self.title = title
self.author = author
self.price = price
self.pubDate = pubDate
}
}
When we say self.title, we are basically referring to the let title: String property of our class. We then assign that to our title parameter of our init method. However, when one or more of our original properties is an Optional, we need to use a failable initializer, as we may not have to use those properties. You have the guard statement almost correct(you have the author part right, but should have title instead of Book), but we still need to assign the properties of our struct(using self) to the properties in our initializer. So here is the updated book struct:
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.title refers to our let title: String, and we assign the value of title from our guard statement to it
self.author = author
self.price = dict[“price”] // if someone decides to add this key to our dict, we assign it’s value to our let price: String? property
self.pubDate = dict[“pubDate”]
}
}
So we now could create a book with just a title and author, like this:
let myBook = Book(dict: ["title": "The Blood Mirror", "author": "Brent Weeks"])
or we can add one or both of the other properties that are optional, like this:
let myBookWithPrice = Book(dict: ["title": "The Blood Mirror", "author": "Brent Weeks", "price": "21.99"])
or this
let myBookWithPriceAndPubDate = Book(dict: ["title": "The Blood Mirror", "author": "Brent Weeks", "price": "21.99", "pubDate": "2016"])
Now we can access those properties with dot notation.
myBook?.author \\ this will give us “Brent Weeks”
Hope this helped!
Dan
Martel Storm
4,157 PointsMartel Storm
4,157 PointsThank you for taking the time to provide shut a clear and helpful response!