【发布时间】:2020-11-28 19:55:22
【问题描述】:
我有一个模型叫 College
class College : Decodable {
let name : String
let id : String
let iconUrl : String
}
还有一些与大学相关的 API,每个 API 的响应都略有不同。 2个例子是
-
获取 api/v1/colleges 此 API 的响应 JSON 是
{ “成功”:字符串, “学院”:[学院] }
-
获取 api/v1/college/{collegeID} 此 API 的响应 JSON 是
{ “成功”:字符串, “学院”:学院 }
现在,从我只需要获取大学信息的两个响应中,“成功”键对我没有用。我的问题是,如何在不为每个 API 创建单独的响应模型的情况下获取大学信息?目前我已经为每个 API 响应实现了单独的类
class GetCollegesResponse : Decodable {
let success : String
let colleges : [College]
}
class GetCollegeResponse : Decodable {
let success : String
let college : College
}
我在各自的 API 调用中使用它们,就像这样
Alamofire.request(api/v1/colleges ....).responseJSON { response in
let resp = JSONDecoder().decode(GetCollegesResponse.self, response.data)
//get colleges from resp.colleges
}
Alamofire.request(api/v1/college/\(id) ....).responseJSON { response in
let resp = JSONDecoder().decode(GetCollegeResponse.self, response.data)
// get college form resp.college
}
有没有更简单的方法来完成这项工作?
【问题讨论】:
-
您希望最终结果是什么?您是否希望它始终为
[College],即使是单个结果?这里有多种方法,具体取决于您想要实现的目标。例如,您还可以将其设为通用响应类型,如下所示:APIResponse<T: Decodable> { let success: String, let payload: T } -
不,我希望第一个具有大学数组,而另一个只有一个大学对象。最后,我的问题归结为,如何在不为整个响应创建模型的情况下从 json 响应中获取特定值?如果有办法做到这一点,那么无论是 College 还是 [College] 都没关系,因为我们可以使用 [College].self 获得大学数组。
-
我先写了一个答案,后来才发现API响应中的key也不一样。实际上,您从服务器获得了相当不同的响应,其中密钥可能会根据响应的内容而改变-即,不仅值类型不同。那么,什么决定了密钥呢?
-
我想知道是否有一种方法可以通过非常简单的步骤获取内部对象,例如最多 2 到 3 行代码。我唯一的问题是,对于每个 API 响应,我都必须创建一个新模型,这会不必要地增加文件数量和复杂性。但是,如果不摆弄您在回答中提到的泛型,似乎没有办法做到这一点。我想要的是 1. 以某种方式只提取我想要的密钥,就像它完成的那样是 swiftyJSON let collegeEncoded = response["college"] 2. 使用解码器解码 let college = JSONDecoder().decode(College.self,collegeEncoded)
标签: ios json swift alamofire decodable