Ios 奇怪的JSON解析

Ios 奇怪的JSON解析,ios,iphone,swift,Ios,Iphone,Swift,它应该是一个包含口袋妖怪的迷你pokedex应用程序。我在解析这个特定的JSON时遇到了很多麻烦 { count: 949, next: null, previous: null, results: [ { name: "bulbasaur", url: "https://pokeapi.co/api/v2/pokemon/1/" }, { name: "ivysaur", url: "https://pokeapi.co/api/v2/pokemon/2/" }, { name: "venus

它应该是一个包含口袋妖怪的迷你pokedex应用程序。我在解析这个特定的JSON时遇到了很多麻烦

{
count: 949,
next: null,
previous: null,
results: [
{
name: "bulbasaur",
url: "https://pokeapi.co/api/v2/pokemon/1/"
},
{
name: "ivysaur",
url: "https://pokeapi.co/api/v2/pokemon/2/"
},
{
name: "venusaur",
url: "https://pokeapi.co/api/v2/pokemon/3/"
},
{
name: "charmander",
url: "https://pokeapi.co/api/v2/pokemon/4/"
},
{
name: "charmeleon",
url: "https://pokeapi.co/api/v2/pokemon/5/"
},
{
name: "charizard",
url: "https://pokeapi.co/api/v2/pokemon/6/"
},
{
name: "squirtle",
url: "https://pokeapi.co/api/v2/pokemon/7/"
},
{
name: "wartortle",
url: "https://pokeapi.co/api/v2/pokemon/8/"
},
{
name: "blastoise",
url: "https://pokeapi.co/api/v2/pokemon/9/"
},
{
name: "caterpie",
url: "https://pokeapi.co/api/v2/pokemon/10/"
},
{
name: "metapod",
url: "https://pokeapi.co/api/v2/pokemon/11/"
},

它基本上是一个包含多个URL的JSON。最初的JSON包含一些数据,这些数据是pokemon结构的数组。通过这个解析我没有问题,但我甚至不知道从哪里开始使用额外的URL

给定的内部URL的第一位看起来像这样,整个东西都是巨大的

{
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
}
],
base_experience: 64,
forms: [
{
name: "bulbasaur",
url: "https://pokeapi.co/api/v2/pokemon-form/1/"
}
],
game_indices: [
{
game_index: 1,
version: {
name: "white-2",
url: "https://pokeapi.co/api/v2/version/22/"
}
},
{
game_index: 1,
version: {
name: "black-2",
url: "https://pokeapi.co/api/v2/version/21/"
}
},
{
game_index: 1,
version: {
name: "white",
url: "https://pokeapi.co/api/v2/version/18/"
}
},
{
game_index: 1,

问题是,我只需要从第二个属性中提取某些属性。不知道如何提取一些,而忽略其他。这就是我目前所拥有的

struct Pokedex: Decodable {
    let count: Int?
    let next: Bool?
    let previous: Bool?
    let results: [Results]
}

struct Results: Decodable {
    let name: String?
    lt url: String?
}

struct Pokemon : Decodable {
    let weight: Int?
    let height: Int?
}

struct endPokemon {
    let name: String
    let weight: Int
    let height: Int
}
重量和高度在第二个url中,但稍后在页面下方

var pokemons = [Pokemon]()

    func loadJSON() {
        let url = "https://pokeapi.co/api/v2/pokemon/"
        guard let urlObj = URL(string: url) else { return }

        URLSession.shared.dataTask(with: urlObj) {(data, response, error) in
            guard let data = data else { return }

            do {
                let pokedex = try JSONDecoder().decode(Pokedex.self, from: data)

                for pokemon in pokedex.results {
                    guard let jsonURL = pokemon.url else { return }
                    guard let newURL = URL(string: jsonURL) else { return }

                    URLSession.shared.dataTask(with: newURL) {(data, response, error) in
                        guard let data = data else { return }

                        do {
                            let load = try JSONDecoder().decode(Pokemon.self, from: data)
                            self.pokemons.append(load)
                        } catch let jsonErr {
                            print("Error serializing inner JSON:", jsonErr)
                        }
                    }
                }
            } catch let jsonErr{
                print("Error serializing JSON: ", jsonErr)
            }
        }.resume()
我没有运行任何错误,但是口袋妖怪数组是空的


有什么想法吗?

您的对象类型看起来不错。唯一的问题是没有对内部dataTask调用.resume。检查下面更正的代码段

func loadJSON() {
    let url = "https://pokeapi.co/api/v2/pokemon/"
    guard let urlObj = URL(string: url) else { return }

    URLSession.shared.dataTask(with: urlObj) {(data, response, error) in
        guard let data = data else { return }

        do {
            let pokedex = try JSONDecoder().decode(Pokedex.self, from: data)

            for pokemon in pokedex.results {
                guard let jsonURL = pokemon.url else { return }
                guard let newURL = URL(string: jsonURL) else { return }

                URLSession.shared.dataTask(with: newURL) {(data, response, error) in
                    guard let data = data else { return }

                    do {
                        let load = try JSONDecoder().decode(Pokemon.self, from: data)
                        self.pokemons.append(load)
                    } catch let jsonErr {
                        print("Error serializing inner JSON:", jsonErr)
                    }
                }.resume()
            }
        } catch let jsonErr{
            print("Error serializing JSON: ", jsonErr)
        }
        }.resume()
}

好的,修好了。谢谢有点第一个JSON之所以相关,是因为我需要使用该JSON来创建所有口袋妖怪的数组。我只是不确定实现这一目标的最佳实践是什么。只从JSON响应中提取某些内容是完全正确的,对吗?不在结构中为它们创建变量?我的最后一个结构包含我想要保留的值。我在第一个JSON中循环URL的方法是一个好主意吗?嘿,谢谢你的回答!这肯定解决了一些问题。为了确保我正确理解这一点,可以只从JSON中提取某些内容,而不是所有的值,对吗?创建pokemon数组的最佳方法是什么,其属性在第一个JSON响应中由url给出?我只需要名称、重量和高度,但名称属于第一个结构,而其他两个在另一个JSON响应中。谢谢是的,只解析JSON中所需的值是完全正确的。在数组中保留细节看起来不错,因为嵌套JSON中还有名称和id属性以及权重和高度,所以您可以始终将不同数组中的对象关联起来。伙计,非常感谢!最后一个问题,有没有比现在更好的方法来创建数组?用于在原始数组上循环