kakaopensource / KakaJSON

Fast conversion between JSON and model in Swift.
MIT License
1.16k stars 126 forks source link

Key path matched wrong value #28

Closed luoxiu closed 5 years ago

luoxiu commented 5 years ago

In some cases, kj_value(for modelPropertyKey: ModelPropertyKey) will return a wrong value if the key is an array. For example:

struct Battle: Convertible {
    var winner: String?
    func kj_modelKey(from property: Property) -> ModelPropertyKey {
        switch property.name {
        case "winner":  return ["teams", "0", "name"]
        default:        return property.name
        }
    }
}
let json: [String: Any] = [
    "teams": [
        ["name": "luoxiu"]
    ]
]
let battle = json.kj.model(Battle.self)
print(battle.winner)  // expect "luoxiu", got "[[\"name\": \"luoxiu\"]]"

This is because of these few lines of code:

// in `kj_value(for modelPropertyKey: ModelPropertyKey)`
let keyArray = modelPropertyKey as! [String]
for key in keyArray {
    if let value = _value(stringKey: key) {  
        // shoud not return if the value is a dict/array and the key path is not empty I think?
        return value
    }
}

Will create a pr with fixing later.

CoderMJLee commented 5 years ago

Use teams.0.name instead of ["teams", "0", "name"] in the situation?

luoxiu commented 5 years ago

@CoderMJLee Yes, teams.0.name works fine in this situation. So this is intentional? "a.b.c" is a key path, and ["a", "b", "c"] is a fallback path?

CoderMJLee commented 5 years ago

Reference

luoxiu commented 5 years ago

Sorry, 我先入为主了