使用 Swift 中的 Decodables 在一个页面上执行多个 API 请求 5
Performing multiple API requests on one page using Decodables in Swift 5
我正在使用 decodable
获取 URL 列表,一旦 TableView
加载,我需要点击这些 URL。
这是我获取 URLS 的结构:
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()
}
我在控制台中成功打印了 urls:
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()
}
要在 table 视图中显示 characterInfos
数组,有无数的教程和示例。
我正在使用 decodable
获取 URL 列表,一旦 TableView
加载,我需要点击这些 URL。
这是我获取 URLS 的结构:
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()
}
我在控制台中成功打印了 urls:
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()
}
要在 table 视图中显示 characterInfos
数组,有无数的教程和示例。