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!

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

Lana Wong
Lana Wong
3,968 Points

How do I create a failable init? How do you initialize stored properties and return nil?

INSTRUCTIONS: 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 of type [String : String] as input and initializes all the stored properties. (Hint: A failable init method is one that can return nil and is written as init?).

Use the following keys to retrieve values from the dictionary: "title", "author", "price", "pubDate"

Note: Give your initializer argument the name dict

How do I create a failable init? How do you initialize stored properties and return nil?

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

       init?(dict: [String: String]){
   title = Book[title]
   author = Book[author]
    price = Book[price]
   pubDates = Book[pubDates]


1 Answer

Jack Baer
Jack Baer
5,049 Points

Hi Lana -

Im going to start off with explaining what a bailable initializer does, and what you did wrong.

A failable initializer is basically an initializer for the properties of the object, just it can return nil. In the video, Pasan showed how an error arose if you tried returning nil without the initializer fallible.

The exercise is asking you to return a dictionary, which by default returns an Optional value. This means that you need to use a failable initializer when you take a dictionary as an initializer argument. The first line of your code is correct. You need to take a single argument: dict, as a type dictionary with [String: String]. And you were right as it is declared with init?.

But what you did wrong is in the init body. Remember how you have to use the self keyword to store the init values in the object property values? Well you are trying to use those property values inside the initializer, therefore it is out of scope.

Here's the solution I came up with:

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


The reason this works, is that it uses the guard statement to check the two non-Optional stored properties, and if they don't exist, it returns nil for the instance of the Friend struct.

Basically, look at the code already provided. It declares 4 properties: title, author, price, and pubDate. price and pubDate are Optional Strings, as show in the type declaration. The others are just Strings. This means that you need to make sure that the non-Optional properties are checked to see if their values exist, and if they don't, nil needs to be returned. I used guard here for the early exit of returning nil.

Then there is now title and author constants that we have checked and can now use, so we use self to set those values to the stored properties.

Then, since price and pubDate are Optionals, the check is not required, and therefore we can try and get the keys directly, setting them to their stored properties inside the body of the struct.

I hope this helped, and if you have any more questions about this, just ask!


Gavin Hobbs
Gavin Hobbs
5,205 Points

Hey Jack Baer I still don't quite understand what this code does? Could you explain it? Thanks a million!

  • Gavin