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 trialDalton Keen
8,082 PointsFailable Initializers
Objective: "In the editor, you have a struct named Book which has few stored properties, two of which are optional.
Your task is to create a failable initializer that accepts a dictionary as input an initializes all the stored properties. (Hint: A failable init method is one that can return nil and is written as init?). Name the initializer parameter dict.
Use the following keys to retrieve values from the dictionary: "title", "author", "price", "pubDate""
The previous videos explained how to use guard statements in functions so I applied the same logic to the initializer and it doesn't work. I've tried declaring variables using self (ex: let self.title) and no difference. I'm just not sure at all how to go about solving this one. Any help is appreciated.
Thanks
struct Book {
let title: String
let author: String
let price: String?
let pubDate: String?
init?(dict: [String : [String : [String : [String]]]])
{
guard let title = dict["title"], let author = dict["author"] else {
return nil
}
let price = dict["price"]
let pubDate = dict["pubDate"]
}
}
2 Answers
jcorum
71,830 PointsAlmost! The type of the dict needs to be [String:String]. Once you've vetted the title and author you get from the dictionary you still need to set the member variables title and 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"]
}
}
jcorum
71,830 PointsChristian, re your code: First, the challenge asked you to create a failable initializer, not a function. Second, initializers must be inside their structs, not outside them. And initializers don't return anything. They create objects and initialize their member variables.
Re your request:
let dict1 = [ "title" : "Pride & Prejudice", "author" : "Jane Austen", "price" : "23.95"]
let b1 = Book(dict: dict1)
b1?.title //"Pride & Prejudice"
b1?.author //"Jane Austen"
b1?.price //"23.95"
b1?.pubDate //nil
Note that the above code must be outside the struct, as it is using the struct to create a Book object (b1) from a dictionary.
If you put the struct and the above code in an Xcode playground (7.3.1.), and then alt-click on b1, you will see, in the popup, that b1 is Book?, i.e., an optional. If you try to remove the ? you will get an error message saying "Value of optional type 'Book?' not unwrapped; did you mean to use '!' or '?'?"
Christian McMullin
13,086 PointsMy code works fine the playground. I know the challenge was asking to use init which i did. It just seems easier to me to use a func rather then init, and I was wondering if there is a benefit in using the init method rather then the func like I did.
//this is an instance of my code up above in my last comment.
let newBook = Book(title: "legend of Drittz", author: "r.a. salvator", price: "15.00", pubDate: nil)
newBook.title //returns "legend of Drittz"
newBook.author //returns "r.a. salvator"
newBook.price //returns "15.00"
newBook.pubDate // returns nil
//this does not return an error and works perfectly.
Dalton Keen
8,082 PointsDalton Keen
8,082 PointsAhhh. Got it! Thanks
Christian McMullin
13,086 PointsChristian McMullin
13,086 PointsCould you demonstrate how do declare a new instance of that struct with using the init? I can't seem to figure it out? also why would you use it that way instead of like this.