Быстрый как перегрузка

Я создаю простой Json Parser, который работает так: у меня есть класс JsonData, который содержит Anyobject в качестве данных. Когда я использую jsonData["key"] он возвращает JsonData, чтобы я мог связать jsonData["key"]["key2"] и т. д.

Мой вопрос в том, как я могу реализовать этот класс, чтобы я мог передать его, скажем, String:

jsonData["key"] как String без использования некоторых обходных путей, таких как

jsonData["key"].data как строка

Код:

   class JsonData:CustomStringConvertible{
    let data:AnyObject

        var description: String{
        get{
            return "\(data)"
        }
    }
    init(_ data: Data) {
        self.data = try! JSONSerialization.jsonObject(with: data, options: []) as! [[String:AnyObject]]
    }

    init(_ data: AnyObject)    {
        self.data = data
    }

    subscript(key:String) -> JsonData{
        let newData = data as! [String:AnyObject]
        let test = newData[key]!
        return JsonData(test)
    }
    subscript(index:Int) ->JsonData{
        let newData = data[index]!
        return JsonData(newData)
    }

}

person Jarosław Krajewski    schedule 18.07.2016    source источник
comment
Вы действительно должны изучить SwiftyJson.   -  person Sulthan    schedule 18.07.2016
comment
@Султан Согласен. Обычно я нахожу это излишним (я думаю, что люди действительно переоценивают сложность написания простого кода синтаксического анализа в большинстве случаев), но если у вас действительно сложные и динамические структуры JSON, это хороший инструмент для создания синтаксического анализатора. Но вы все равно должны помещать все в структуры для использования вне сетевого стека.   -  person Rob Napier    schedule 18.07.2016
comment
@RobNapier Я полностью согласен. Я не понимаю, почему люди все время работают с вложенными неразборными словарями. Это как работать в Javascript.   -  person Sulthan    schedule 18.07.2016


Ответы (1)


Чтобы сделать это, вы бы добавили еще одну перегрузку, но это не сработает так, как вы думаете.

subscript(key: String) -> String {
    let newData = data as! [String:AnyObject]
    return newData[key] as! String
}

Итак, jsonData["key"] as String работает, но jsonData["key"]["key2"] неоднозначно, и вам придется написать его (jsonData["key"] as JsonData)["key2"], что, вероятно, не то, что вам нужно.

Короткий ответ на этот вопрос: не делайте этого. Если вам нужен такой большой доступ к JSON, вы, вероятно, неправильно храните свои данные. Как можно быстрее разберите его на структуры, а затем работайте со структурами. Преобразуйте структуры обратно в JSON, когда захотите. Обширная работа с AnyObject будет ломать ваш мозг и компилятор снова и снова. AnyObject — это необходимое зло, а не повседневный инструмент. Вскоре вы столкнетесь с тем ужасным днем, когда у вас есть AnyObject?, а компилятор просто плачет. Ну, по крайней мере, это не Any.

Если оставить это в стороне, лучшим решением будет использование помеченных индексов.

subscript(string key: String) -> String {
    let newData = data as! [String:AnyObject]
    return newData[key] as! String
}

Теперь вы можете получить к нему доступ как json[string: "key"], а не json["key"] as String.

person Rob Napier    schedule 18.07.2016