4

I have the following code in the Playground:

class Pokemon : NSObject {

    var name :String!
    var id :Int?
    var imageURL :String!
    var latitude :Double!
    var longitude :Double!

    init(dictionary :[String:Any]) {

        super.init()
        setValuesForKeys(dictionary)
}
}

let dict :[String:Any] = ["name":"John","imageURL":"someimageURL","latitude":45.67]
let pokemon = Pokemon(dictionary: dict)

When the call to setValuesForKeys is made then it throws an exception saying the following:

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__lldb_expr_13.Pokemon 0x6000000ffd00> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key latitude.'

I have the key "latitude" but for some reason it is not able to find it. Any ideas!

rmaddy
  • 314,917
  • 42
  • 532
  • 579
john doe
  • 9,220
  • 23
  • 91
  • 167
  • 3
    Why create such an initializer? Why not create a proper initializer or set the properties directly? – rmaddy Apr 03 '17 at 18:32
  • Absolutely! But I want to find out what I am doing wrong in the above code. Also, this initializer would be helpful if you are setting lots of properties. – john doe Apr 03 '17 at 18:32
  • How about [this one](http://stackoverflow.com/q/26366082/3476191) then? – NobodyNada Apr 03 '17 at 18:36
  • @NobodyNada Nope! Please read my question before linking it to some other question. I am explicitly using setValuesForKeys function. – john doe Apr 03 '17 at 18:37
  • 1
    @johndoe It's the same exact problem, just a different symptom -- types like `int` and `double`, which cannot be optional in Objective-C are not bridged to Objective-C. – NobodyNada Apr 03 '17 at 18:38
  • why not `var name: String = ""` and `var imageURL: String = ""`? – Leo Dabus Apr 03 '17 at 19:02
  • @johndoe you should read Reflecting on Reflection at the end of this post https://developer.apple.com/swift/blog/?id=37 – Leo Dabus Apr 03 '17 at 19:05
  • BTW why are you subclassing NSObject? Looks meaningless. You should use a struct for that. – Leo Dabus Apr 03 '17 at 19:06

1 Answers1

6

The type Double! (similarly Double?) has no correspondence in the Objective-C world, so it is not exposed as an Objective-C property, so Key-Value Coding cannot find a key named "latitude" and crash.

You should convert those fields to non-optional if you need KVC.

class Pokemon : NSObject {
    var name: String!
    var id: Int = 0
    var imageURL: String!
    var latitude: Double = 0.0
    var longitude: Double = 0.0

    init(dictionary: [String: Any]) {
        super.init()
        setValuesForKeys(dictionary)
    }
}
Community
  • 1
  • 1
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005