7

It's trivial enough to do something like this:

class Collection {
    init(json: [String: AnyObject]){
        guard let id = json["id"] as? Int, name = json["name"] as? String else {
            print("Oh noes, bad JSON!")
            return
        }
    }
}

In that case we were using let to initialize local variables. However, modifying it to use class properties causes it to fail:

class Collection {

    let id: Int
    let name: String

    init(json: [String: AnyObject]){
        guard id = json["id"] as? Int, name = json["name"] as? String else {
            print("Oh noes, bad JSON!")
            return
        }
    }

}

It complains that let or var needs to be used but obviously that isn't the case. What's the proper way to do this in Swift 2?

David Snabel
  • 9,801
  • 6
  • 21
  • 29
Leah Sapan
  • 3,621
  • 7
  • 33
  • 57

1 Answers1

14

In the if let, you are unwrapping values from the optional as new local variables. You can’t unwrap into existing variables. Instead, you have to unwrap, then assign i.e.

class Collection {

    let id: Int
    let name: String

    init?(json: [String: AnyObject]){
        // alternate type pattern matching syntax you might like to try
        guard case let (id as Int, name as String) = (json["id"],json["name"]) 
        else {
            print("Oh noes, bad JSON!")
            self.id = 0     // must assign to all values
            self.name = ""  // before returning nil
            return nil
        }
        // now, assign those unwrapped values to self
        self.id = id
        self.name = name
    }

}

This is not specific to class properties - you can’t conditionally bind into any variable, for example this doesn’t work:

var i = 0
let s = "1"
if i = Int(s) {  // nope

}

Instead you need to do:

if let j = Int(s) {
  i = j
}

(though of course, in this case you’d be better with let i = Int(s) ?? 0)

Airspeed Velocity
  • 40,491
  • 8
  • 113
  • 118
  • Yeah that's what I did in the meantime, but I figured there had to be a cleaner way. Thanks. – Leah Sapan Jul 07 '15 at 14:29
  • Not with guard, anyway - see the [big list](http://stackoverflow.com/questions/29717210/when-should-i-compare-an-optional-value-to-nil/29717211#29717211) to see if there’s another unwrapping technique that might work in this case. – Airspeed Velocity Jul 07 '15 at 14:30