utahiosmac / Marshal

Marshaling the typeless wild west of [String: Any]
MIT License
697 stars 62 forks source link

Decode value with leading-dot key #102

Closed dispatchqueue closed 7 years ago

dispatchqueue commented 7 years ago

How to get value for key ".tag" from this JSON:

{
    ".tag": "test"
    "name": "something"
}

Marshal splits the key by ., so object.value(for: ".tag") returns nil because tag key is not found.

jarsen commented 7 years ago

Good question... I don't think this case has been considered, but this seems to be pretty atypical JSON. Supporting this case would be difficult without removing the keypath support.

Out of curiosity, why is your API doing this? Given that JSON is usually supposed to be easily translated and used as a Javascript object where it's nice to be able to use the . operator having keys with periods in it seems undesirable.

My suggestion for a workaround would be to manipulate the dictionary before you pass it in. i.e., when you get it back from the network, do something like:

foo["tag"] = foo[".tag"]
let myObject = try MyObject(object: foo)
dispatchqueue commented 7 years ago

Thanks @jarsen.

Dropbox API is doing like that: https://www.dropbox.com/developers/documentation/http/documentation#files-get_metadata

Other JSON libraries are using this keypath syntax to access nested data: object.value("user", "email", "person"). I think that syntax is better and less error-prone than using ..

jarsen commented 7 years ago

That's a great suggestion, and one I think definitely worth exploring.

jarsen commented 7 years ago

I'm going to reopen this because I feel like that's probably worth implementing.

dispatchqueue commented 7 years ago

Great! Thanks @jarsen.