Разбор aa JSON в объект структуры вручную - PullRequest
1 голос
/ 28 мая 2020

Я новичок в Swift и в настоящее время делаю приложение, которое выполняет веб-запросы. Я пытался разобрать эти JSON данные, но вложенные данные просто очень трудно обернуть мою голову:

 "abilities": [
            {
                "ability": {
                    "name": "chlorophyll",
                    "url": "https://pokeapi.co/api/v2/ability/34/"
                },
                "is_hidden": true,
                "slot": 3
            },
            {
                "ability": {
                    "name": "overgrow",
                    "url": "https://pokeapi.co/api/v2/ability/65/"
                },
                "is_hidden": false,
                "slot": 1
            }
        ]

JSon Код сериализации

let jsonAny = try JSONSerialization.jsonObject(with: data, options: [])
            guard let json = jsonAny as? [String: Any] else { return }

Это это моя попытка вручную проанализировать JSON данные

    private func parsePokemonManual(json: [String: Any]) -> Pokemon {
        let abilities = json["abilities"] as? [String: Any] ?? [String: Any]()

        return Pokemon(abilities: abilities)
    }
}

Это структуры, которые я сделал для хранения данных.

struct Abilities {
    let ability : Ability

    struct Ability {
        let name : String
    }
}

Как мне успешно проанализировать JSON Данные в объект структуры Pokemon?

При таком толстом коде я получаю ошибку «Невозможно преобразовать значение типа '[String: Any]' в ожидаемый тип аргумента '[Abilities]'. Моя проблема заключается в том, что я не знаю, к какому типу использовать способности, и что моя структура «Способности» также неверна.

1 Ответ

0 голосов
/ 28 мая 2020

Есть 3 проблемы с вашей попыткой, хотя можно утверждать, что есть только 1, что вы должны использовать вместо этого Codable, но оставим здесь JSONSerialization. Проблемы:

  • Вы неправильно читаете json и должны приводить не к словарю, а к массиву словарей при доступе к «способностям»
  • Ваша структура слишком сложна, возможно из-за предыдущей проблемы
  • Наконец, вы не можете преобразовать в пользовательский тип, вам нужно преобразовать или сопоставить данные в свой тип, указав точно, какие значения использовать и как, потому что компилятор не понимает, как это сделать.

Сначала структуру можно упростить до

struct Ability {
    let name : String
}

А остальное зафиксировано в функции parsePokemonManual. Сначала получите "способности" и примените к массиву словарей. Затем сопоставьте каждый элемент в массиве, получив «способность» и преобразовав его в словарь, который используется для получения значения «имя», которое затем используется при создании экземпляра Ability

private func parsePokemonManual(json: [String: Any]) -> [Ability] {
    guard let abilities = json["abilities"] as? [[String: Any]] else {
        return []
    }

    return abilities.compactMap { dict in
        guard let ability = dict["ability"] as? [String: String], let name = ability["name"] else { return nil }

        return Ability(name: name)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...