swift - 使用 Swift 5 中的 Decodables 在一页上执行多个 API 请求

标签 swift decodable

我使用 decodable 来获取加载 TableView 后需要访问的 URL 列表。

这是我获取 URL 的结构:

struct CharactersUrls: Decodable {
    let characters: [String]
}

struct Characters: Decodable {
    let characters: [String]
}

struct CharacterInfo: Decodable {
    let Id: Int
    let name: String
    let status: String
}

这是我的功能:

    fileprivate func getCharactersUrls() {
    let endpoint  = "https://rickandmortyapi.com/api/episode/\(episodeID ?? "1")"
    guard let url = URL(string: endpoint) else { return }

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

        do {
            let charactersUrls = try JSONDecoder().decode(CharactersUrls.self, from: data)
            print("Characters URLS: \(charactersUrls)")

            let endpoints = [charactersUrls]
            print("Endpoints -> \(endpoints)")

        } catch let jsonError {
            print("Error Serializing JSON:", jsonError)
        }

        }.resume()
}

我成功在控制台中打印了网址:

Endpoints -> [Rick___Morty.CharactersUrls(characters: ["https://rickandmortyapi.com/api/character/1", "https://rickandmortyapi.com/api/character/2", "https://rickandmortyapi.com/api/character/38", "https://rickandmortyapi.com/api/character/87",  "https://rickandmortyapi.com/api/character/338"])]

现在我需要点击每个 url 以从中获取 id、name、status 并将它们加载到 tableView

使用 Decodable 实现此目的的最佳方法是什么?

最佳答案

首先,您的 CharacterInfo 结构是错误的,id 是小写的。

要获取所有字符的信息,您需要第二个数据任务。要在所有任务完成时收到通知,请使用 DispatchGroup。为了方便起见,status 被解码为枚举。

struct CharactersUrls: Decodable {
    let characters: [URL]
}

enum Status : String, Decodable {
    case dead = "Dead", alive = "Alive"
}

struct CharacterInfo: Decodable {
    let id: Int
    let name: String
    let status: Status
}

var characterInfos = [CharacterInfo]()

fileprivate func getCharactersUrls() {
    let endpoint  = "https://rickandmortyapi.com/api/episode/\(episodeID ?? "1")"
    guard let endPointURL = URL(string: endpoint) else { return }

    let group = DispatchGroup()

    let outertask = URLSession.shared.dataTask(with: endPointURL) { data, response, error in
        guard let data = data else { print(error!); return }

        do {
            let charactersUrls = try JSONDecoder().decode(CharactersUrls.self, from: data)
            print("Characters URLS: \(charactersUrls)")
            for infoURL in charactersUrls.characters {
                group.enter()
                let innertask = URLSession.shared.dataTask(with: infoURL) { data, response, error in
                    defer{ group.leave() }
                    guard let data = data else { print(error!); return }
                    do {
                        let characterInfo = try JSONDecoder().decode(CharacterInfo.self, from: data)
                        characterInfos.append(characterInfo)
                    } catch {
                        print("Error Getting Info for \(infoURL):", error)
                    }

                }
                innertask.resume()
            }
            group.notify(queue: .main) {
                print(characterInfos)
            }

        } catch {
            print("Error Serializing JSON:", error)
        }

    }
    outertask.resume()
}

要在表格 View 中显示 characterInfos 数组,有无数的教程和示例。

关于swift - 使用 Swift 5 中的 Decodables 在一页上执行多个 API 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57240372/

相关文章:

Swift:正确解码不精确的十进制

json - 使用 Swift 4 的 Decodable 解码 Void

swift - 如何在 SwiftUI 中从图库中选择图像

ios - 安装 pod 后无法访问 pod swift 文件

ios - 将可视格式的约束转换为 NSLayoutAnchor API

ios - 在 Collection View 中显示长单元格(如矩形)时出现问题

swift - NSTableView:第二列在不应该出现的时候出现

json - 字典的可解码 keyDecodingStrategy 自定义处理

ios - 如果字典数组缺少一个键,如何编写 Codable

ios - 如何在 Codable 类型中使用 Any