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

r5
r5
2,416 Points

Code Challenge: Initializing Optional Values

Hey, after many different tries I'm kind of stuck on this challenge here. I believe the second guard statement is wrong but it all works as it should in the playground but it is not accepted in the editor.

Maybe you could point out what I'm doing wrong.

Thanks

Task: 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"

optionals.swift
struct Book {
    let title: String
    let author: String
    let price: String?
    let pubDate: String?

}

func book(dict: [String: String]) -> Book? {
    guard let title = dict["title"],
        let author = dict["author"] else {
            return nil
    }

    guard let price = dict["price"],

        let pubDate = dict["pubDate"] else {
            return nil
    }


    return Book(title: title, author: author, price: price, pubDate: pubDate)
}

7 Answers

If the hint does not help, this might:

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

}
r5
r5
2,416 Points

No apparently I didn't use one...

But thank you for the help!

Christopher Davis
Christopher Davis
8,555 Points

I've been stuck on this challenge for hours. I've even copy/pasted the "passing" code from your comment and the comments of others, and it still hasn't worked.

I'm at a total loss.

Jose Patarroyo
Jose Patarroyo
2,953 Points

Hello, I see that the code works, but I'm a little confused with this challenge. How comes when I create a structure of type Book I only have to pass two parameters of type String? shouldn't I had to do an initializer with a dictionary that contained four parameters? I run the code but when I create a constant of type Book, I always get a nil return, so I can never have that structure....I don't know if I'm making sense here, I'm very confused with the subject.

s t
s t
2,699 Points

I have some questions... I thought the guard statement is initializing and unwrapping the value, therefore why are we initializing these two again;

self.title = title self.author = author

and then I don't get how this was arrived at;

self.price = dict["price"] self.pubDate = dict["pubDate"]

sometimes I feel there are too many options to choose from when completing the challenge, do we use whats in the video or documentation, I seem to end up with a mixture of everything that complicates my answer most times. I guess this is the process of learning!

Hint: Are you using an init?

Jose Patarroyo
Jose Patarroyo
2,953 Points

Just to clarify, I was trying to use something like this:

init?(dict: [String: [String: [String: String]]]){
//here goes the code
}

But I got kind of lost....

r5
r5
2,416 Points

Hey, you only have to use two parameters of type string because there only two options available.

Example:

struct Book {
    //  1      2
    let title: String
//            1          2
init?(dict: [String: String])
}

But If you have more parameters like a few challenges before with the movieDictionary you would have to use your code. It always depends how many String/Values you have in your struct or dict.

Example 2:

//                             1       2           3
let movieDictionary = ["Spectre": ["cast": ["Daniel Craig"]]]
//                            1       2       3
init:(movieDictionary: [String: [String: [String]]])

Hope I could help you!

Jose Patarroyo
Jose Patarroyo
2,953 Points

Thank you r5. One more question, how do you create a working constant of the type Book? I tried to create one but it is always nil. Am I missing something?

r5
r5
2,416 Points

Sorry I don't really understand what you mean. What exactly do you want to create?

Jose Patarroyo
Jose Patarroyo
2,953 Points

Since Book is a struct, I would like to crate a constant of that type. I tried but it always returns nil for every parameter... I guess is because not all of them are initialized

r5
r5
2,416 Points

Apparently you tried it with the method from omarelamrieado, right?

Edit: Yeah I know now what you mean. And I didn't found a solution for that.

Alex Wride
Alex Wride
4,420 Points

It's possible that the Book struct is being used in this context purely as an example to demonstrate how to initialize with optionals. It may not be intended to work outside of the example.