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

Trevor Wood
Trevor Wood
17,828 Points

Can somebody help me with this code challenge?

I really have no idea what he wants me to do here. These "optionals" are really not making sense to me.

Can somebody explain this to me as if I were a small child please.

optionals.swift
struct Book {
    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
    }

}

var harrypotterdict: [String:String] = [
    "title": "Harry Potter",
    "author": "JW Rowling",
    "price": "30$",
    "pubDate": "January 10th, 1998"
]


let HarryPotter = Book(title: "Harry Potter", author: "JK Rowling",
                       price: "30$", pubDate: "January 10th, 1998")

print(HarryPotter.title)
print(HarryPotter.author)
print(HarryPotter.price)
print(HarryPotter.pubDate)






print("working")

2 Answers

Hi Trevor, Here is the solution to code challenge, then I will try to explain:

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

}

1- The code challenge asks you to create a failable initializer, this means an initializer that can return nil(means retunr nothing or no object). normally initializers return the object that has been created, so to mark a failable initializer you need to add "?" to "init" to become init? 2- The challenge asked you to make the initializer accept a dictionary and call the parameter name "dict", this is what you see in my code above

Now moving to the optional thing: 3- Optional means a var or constant that can hold a value of nil (holds nothing). you mark an optional variable or constant using "?" next to the type name for example: let price: Sring? 4- When you assign a value to an optional var/constant you just do it directly and dont use either "?" or "!". for example : price = "10.5$" 5- However, when you want to read out the value stored in an optional var/constant, you need to check first if it is empty( means holds nil) or it actually holds a value, that's called unwrapping. 6- There are two ways to unwrap an optional var/constant: First way is called "force unwrapping" and it is dangerous as it can cuase your app to crash if the optional is empty(holding nil). You do this by using "!"next to variable name. For example let x = price! The second way is called "optional binding" and you do this by "if" or "guard". For example: if let x = price { // do somthing }. Or like guard statement in the above code. both "if let" or "guard let" they first check if the optional is empty or not, and if it is not , then it will assign the value in it to a variable. Optional binding is much safer than force unwrapping and you app will never crash. 7- One last thing, In swift dictionary is by nature holding optional values in it. This means you have to unwrap any value you read out of a dictionary. you unwrap using optional binding. In the code above we use guard for optional binding, so we first check that the dict["title"] and dict["author"] have values, if so we assign them to intermediate constants called title and author. Then use the constant to assign the values to actual object being create by the initializer using self.title and self.author. The other two constants in the struct "price" and "pubDate" are already defined as optionals so we can directly assign them to the values returned from the dictionary that is also optional.

I hope it is clear for you now. If not please let me know. Cheers, Safwat

Trevor Wood
Trevor Wood
17,828 Points

Thanks so much Safwat! Learned a lot :D

you are welcome :)