Handle uncaught exception valueForUndefinedKey in Swift

When valueForKey: is invoked for an undefined key, the runtime forwards the call to valueForUndefinedKey:. The default implementation of the later simply raises NSUndefinedKeyException.

We can't catch the exception from Swift code, but we can override the method valueForUndefinedKey: in an extension and return some error:

extension NSObject {
    @objc
    func value(forUndefinedKey key: String) -> Any {
        NSError(domain: "Dynamic", code: 404, userInfo: [NSLocalizedDescriptionKey: "Accessing undefined key: '\(key)'"])
    }
}