【发布时间】:2023-03-11 18:50:01
【问题描述】:
我正在尝试在 Swift 中解码“依赖”的 JSON API 响应。让我们想象一个具有两个端点的虚构 API:
-
/players,返回具有以下属性的对象数组:-
id,代表玩家ID的整数 -
name,代表玩家姓名的字符串
-
-
/games,返回具有以下属性的对象数组:-
name,代表游戏名称的字符串 -
playerId1,一个整数,代表第一个玩家的ID -
playerId2,一个整数,代表第二个玩家的ID
-
我用 Swift struct 为每种类型建模:
struct Player: Decodable {
var id: Int
var name: String?
}
struct Game: Decodable {
var name: String
var player1: Player
var player2: Player
enum CodingKeys: String, CodingKey {
case name
case player1 = "playerId1"
case player2 = "playerId2"
}
}
我想将来自/games 的响应解码为具有正确Players 属性的Game 对象数组,因此我使用自定义初始化程序扩展了Game,但我不知道如何检索所有玩家属性:
extension Game {
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decode(String.self, forKey: .name)
// HOW SHOULD I RETRIEVE THE PLAYER'S NAME GIVEN THEIR ID HERE?
// |
// |
// V
player1 = Player(id: try values.decode(Int.self, forKey: .player1), name: nil)
player2 = Player(id: try values.decode(Int.self, forKey: .player2), name: nil)
}
}
总而言之,来自/games 的 API 响应不包含我完全初始化所需的所有信息,所以我应该如何继续:
- 我可以/应该进行两次 API 调用,一次调用
/games,另一次调用players,并在解码前以某种方式合并它们? - 我是否应该只初始化我的
Players 部分(将未知的东西留给nil)并稍后填写详细信息? (这听起来既危险又麻烦。) - 还有什么?
如果你想试验一下,可以找一个完整的例子here
【问题讨论】:
-
Graphql 在这里可能会有所帮助graphql.org
-
@Cristik 感谢您的建议,但我宁愿避免使用 GraphQL,因为我无法控制 API,并且希望避免运行我自己的服务器来模仿 GraphQL 中的原始 API :)跨度>