value(forKeyPath:) implementation on Linux?

I’m trying to use Marshal on Linux, and I’ve run into an issue where it won’t build, I think because it’s relying on NSObject.value(forKeyPath:). I suppose one solution would be to simply provide an implementation of this method in the MarshalDictionary class that calls it, no?

Can Swift’s key paths be used to navigate a JSON object?

The ‘key path’ being referred to in this method is not a Swift keypath, it’s the Objective-C definition of Key-Value Coding shining through. KVC and KVO isn’t available on Linux as it uses the Objective-C runtime.

Yes, I'm aware of all this. I was floating the idea of making Dictionaries navigable via Swift key path.

It's already possible to navigate Dictionaries via Swift key path

var dict: [String:Any] = ["asdf": 123]
let kp = \Dictionary<String, Any>["asdf"]
print(dict[keyPath: kp]) // Optional(123)

The problem is that you can only do it one level deep, because you cannot subscript Any

You want to teach the type system that it's a json object, not a general purpose dictionary

struct JsonObject {
    let value: Any?
    subscript(val: String) -> JsonObject {
        if let value = self.value as? [String:Any] {

            return JsonObject(value: value[val])
        } else {
            return JsonObject(value: nil)
        }
    }
    subscript(val: Int) -> JsonObject {
        if let value = self.value as? [Any], value.indices.contains(val) {
            return JsonObject(value: value[val])
        } else {
            return JsonObject(value: nil)
        }
    }

    var string: String? { value as? String }
    var number: Int? { value as? Int }
    var object: [String:Any]? { value as? [String:Any] }
}

let json = JsonObject(value: ["asdf": ["zxcv": 123]])
let kp = \JsonObject["asdf"]["zxcv"].number
print(json[keyPath: kp]) // Optional(123)
2 Likes

Apologies! Misinterpreted.

Hmm, that keypath seems clunkier than I would have hoped, but I guess I'm not really understanding how Swift key paths really work.

In any case, my main problem is the apparent lack of value(forKeyPath:) in Linux. Oh, actually, looking at the Marshal code again, I realize this is an extension on NSDictionary that’s using this, and maybe I can just exclude that bit for Linux builds.