我使用 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/