打开应用程序时如何加载数据?

时间:2019-04-10 07:01:17

标签: json swift xcode api

我已经正确地编写了代码,但是由于某种原因,在调用fetchData()的方法之后,superHero数组仍然为空。我在做什么错了?

class MainViewController: UICollectionViewController {

    private var superHeroes = [SuperHero]()

    let url = "https://cdn.rawgit.com/akabab/superhero-api/0.2.0/api/all.json"

    override func viewDidLoad() {
        super.viewDidLoad()

        fetchData()
    }

    // MARK: UICollectionViewDataSource

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return superHeroes.count
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell

        let superHeroe = superHeroes[indexPath.row]
        cell.configureCell(superHero: superHeroe)


        return cell
    }

    func fetchData() {

        guard let url = URL(string: url) else { return }

        URLSession.shared.dataTask(with: url) { (data, _, _) in

            guard let data = data else { return }

            do {
                self.superHeroes = try JSONDecoder().decode([SuperHero].self, from: data)
                print(self.superHeroes)
            } catch let error {
                print(error)
            }
        }.resume()
    }
}

2 个答案:

答案 0 :(得分:1)

由于您尚未发布SuperHero Codable,因此我根据HERE向您的JSON创建了一个新的索引。它看起来像:

typealias SuperHero = [SuperHeroElement]

struct SuperHeroElement: Codable {
    let id: Int
    let name, slug: String
    let powerstats: Powerstats
    let appearance: Appearance
    let biography: Biography
    let work: Work
    let connections: Connections
    let images: Images
}

struct Appearance: Codable {
    let gender: Gender
    let race: String?
    let height, weight: [String]
    let eyeColor, hairColor: String
}

enum Gender: String, Codable {
    case empty = "-"
    case female = "Female"
    case male = "Male"
}

struct Biography: Codable {
    let fullName, alterEgos: String
    let aliases: [String]
    let placeOfBirth, firstAppearance: String
    let publisher: String?
    let alignment: Alignment
}

enum Alignment: String, Codable {
    case bad = "bad"
    case empty = "-"
    case good = "good"
    case neutral = "neutral"
}

struct Connections: Codable {
    let groupAffiliation, relatives: String
}

struct Images: Codable {
    let xs, sm, md, lg: String
}

struct Powerstats: Codable {
    let intelligence, strength, speed, durability: Int
    let power, combat: Int
}

struct Work: Codable {
    let occupation, base: String
}

现在,下一件事是您需要替换:

private var superHeroes = [SuperHero]()

private var superHeroes: SuperHero?

然后在您的fetchData方法中替换

self.superHeroes = try JSONDecoder().decode([SuperHero].self, from: data)

self.superHeroes = try JSONDecoder().decode(SuperHero.self, from: data)

这里superHeroesArray的{​​{1}},因此您可以通过索引从中访问数据。喜欢

SuperHeroElement

此外,一旦从服务器中的数据进入主队列后,您就需要重新加载集合视图,例如:

guard let response = self.superHeroes else {return}
print(response[0].images) //Accessing data at 0 index

答案 1 :(得分:1)

尝试一下:-

使用self.collectionView.reloadData()方法打印do数组后,可以将superHero置于fetchData()条件下。