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 Error Handling in Swift 2.0 Error Handling Handling Errors

Nathan Mulholland
Nathan Mulholland
2,844 Points

I don't understand the Challenge Task 1 of 3?

So far everything has been pretty easy to understand with Pasan teaching. Everything sticks well, however optional binding, and error handling have been really tough for me to grasp. I feel like the course went from 0-60 really fast and that we are "Looking" at topics rather than really going in knees deep. I liked the earlier courses where we wrote the code from scratch on each project so we could get a feel for it, however now it seems that we are copy and pasting a lot of code, and Im not understanding half of what we are working on, because I'm still new and slow at reading code.

That being said and out of the way, I really don't understand this challenge. I wants me to find out if the dictionary is nil, then return an error. Then if wants to know, if "someKey" exists or not in the dictionary. I have gone through apples resources and other online resources and guard statements still do not make sense to me. I don't know which optional bindings I'm suppose to be using for each error.

If someone could help elaborate which optional bindings I would use on each one, why and possibly the code to go with it for reference. I am in this to learn, but Im afraid its starting to get really fast for me.

Please and thank you!!!

error.swift
enum ParserError: ErrorType {
  case EmptyDictionary
  case InvalidKey
}

struct Parser {
  var data: [String : String?]?

  func parse() throws {

  }
}

let data: [String : String?]? = ["someKey": nil]
let parser = Parser(data: data)

2 Answers

Aaron Bilenky
Aaron Bilenky
13,294 Points

First you need to check if the data dictionary is nil, if it is, throw the EmptyDictionary error.

if let unwrappedData = data {

} else {
      throw  ParserError.EmptyDictionary
}

If the data is not nil then you just need to check if "someKey" is in the dictionary. If not then throw the InvalidKey error

if let unwrappedData = data {

      if unwrappedData.keys.contains("someKey") {

      } else  {
        throw ParserError.InvalidKey
      }
} else {
      throw  ParserError.EmptyDictionary
}
Nathan Mulholland
Nathan Mulholland
2,844 Points

Thank you for the help! I had trouble going to sleep last night because I couldn't figure it out. Also you wrote it out in a simpleton understand way, thank you!

John Ambrose
John Ambrose
7,216 Points

My only concern here with Aaron's approach is that it starts to create the Pyramid of Doom Pasan mentions. We really should be using guard statements instead. They let us do two things:

  • clearly identify the error results (these are in the curly braces)
  • use any instance variables outside the braces which can create more terse and readable code.

here is how I wrote mine:

        guard let dict = data else {
            throw ParserError.EmptyDictionary
        }
        guard dict.keys.contains("someKey") == true else {
            throw ParserError.InvalidKey
        }

Because the guard statement lets us use the instance variable "dict" outside the braces (unlike if statements) we can then use the .key chaining (hah! get it?) to check for the "someKey" value without having to do another if let statement to bind the optional again.

Nathan Mulholland
Nathan Mulholland
2,844 Points

Awesome answer, much appreciated!

Yoann NUSSBAUMER
Yoann NUSSBAUMER
2,180 Points

And to improve that, you could remove the " == true" in the second guard statement :)