ios - 解码具有动态密钥的 JSON
问题描述
我的回复如下所示JSON
。问题是我有散列的动态密钥。我在Decodable
为这个响应创建一个结构时很迷失。
我尝试了下面的代码,但由于planName
最近引入了数据不匹配而失败。
struct ProductDescriptionResponse {
let disclaimersHtml: String?
let additionalProperties: [String: ProductDescription]?
}
struct ProductDescription {
var disclaimersHtml: String?
var hasPlanDetailsV2: Bool?
let planDescription: String
let serviceDescriptions: [ServiceDescriptions]
}
struct ServiceDescriptions {
let name: String
let subTitle: String?
let icon: String?
let description: String?
let upgradeText: String?
let featureDisclaimer: String?
}
func productDescriptions() -> Observable<ProductDescriptionResponse> {
return APIClient.sharedInstance.rx.response(apiURL: APIURL.productDescription, requestType: .get, httpBody: nil, header: .auth).map({ (responseData) -> ProductDescriptionResponse in
var parsedData = try JSONSerialization.jsonObject(with: responseData) as? [String:Any]
// Remove disclaimersHtml key from responseData & hold it to pass
// in ProductDescriptionResponse constructor during return.
let disclaimersHtml = parsedData?.removeValue(forKey: "disclaimersHtml") as? String
// Product descriptions.
var productDescriptions: [String: ProductDescription]? = nil
if let parsedData = parsedData {
// Json data without disclaimersHtml.
let jsonData = try JSONSerialization.data(withJSONObject: parsedData, options: .prettyPrinted)
productDescriptions = try JSONDecoder().decode([String: ProductDescription].self, from: jsonData)
}
// ProductDescriptionResponse with disclaimersHtml & productDescriptions.
return ProductDescriptionResponse(disclaimersHtml: disclaimersHtml,
additionalProperties: productDescriptions)
})
}
JSON响应:
{
"disclaimersHtml": "",
"planName": "",
“abc456753234”: {
"planDescription": "",
"hasPlanDetailsV2": false,
"serviceDescriptions": [
{
"name": "",
"subTitle": "",
"icon": "",
"hasTile": "",
"tileTitle": "",
"description": "",
"featureDisclaimer": "",
"upgradeText": ""
},
{
"name": "",
"subTitle": "",
"icon": "",
"hasTile": "",
"tileTitle": "",
"description": "",
"featureDisclaimer": "",
"upgradeText": ""
}
]
},
“xyz123456789”: {
"planDescription": "",
"hasPlanDetailsV2": true,
"serviceDescriptions": [
{
"name": "",
"subTitle": "",
"icon": "",
"hasTile": "",
"tileTitle": "",
"description": "",
"featureDisclaimer": "",
"upgradeText": ""
}
]
}
}
如果我在下面这样做,它会起作用。但不想像这样继续硬编码:
let _ = parsedData?.removeValue(forKey: "planName") as? String
这种类型的 JSON 是否有更好的工作方式?我不想硬编码并不断剥离值来获取ProductDescriptionResponse
,因为将来可以添加此字段。
解决方案
我解决的方法是遍历(key, value)
序列化的 JSON。
仅当匹配时才检查value
类型Dictionary<AnyHashable,Any>
和解码,否则忽略。
func productDescriptions() -> Observable<ProductDescriptionResponse> {
return APIClient.sharedInstance.rx.response(memberAPIURL: MemberAPIURL.productDescription, requestType: .get, httpBody: nil, header: .auth).map({ (responseData) -> ProductDescriptionResponse in
var productDescriptionResponse = ProductDescriptionResponse(disclaimersHtml: nil, additionalProperties: nil)
var additionalParams: [String: ProductDescription] = [:]
do {
productDescriptionResponse = try JSONDecoder().decode(ProductDescriptionResponse.self, from: responseData)
if let jsonObject = try JSONSerialization.jsonObject(with: responseData, options: .mutableLeaves) as? [String : Any] {
for (key,value) in jsonObject {
if value is Dictionary<AnyHashable,Any> {
let jsonData = try JSONSerialization.data(withJSONObject: value, options: JSONSerialization.WritingOptions.prettyPrinted)
let productDescription = try JSONDecoder().decode(ProductDescription.self, from: jsonData)
additionalParams[key] = productDescription
}
}
productDescriptionResponse.additionalProperties = additionalParams
}
} catch {
// handle error
}
return productDescriptionResponse
})
}
推荐阅读
- jsonpath - jsonpath查找所有键离开包含一个字符串
- swift - 在 swiftui 中 2 秒后推送视图
- c++ - 是否有任何 C++ 函数可以对地图进行排序?
- python - 在字符串之后对齐文本以更加对称
- php - Slim 4:使用容器与模型和控制器共享数据库连接,无需 Eloquent
- javascript - Javascript 检查数据可用性和 http 状态
- react-native - 使用 Context API 时 React Native 渲染白屏
- r - 如何获取树的每个节点中的观察索引?
- python - 使用dash upload组件上传csv文件并生成图表
- nginx-ingress - 为什么 ingress-nginx 控制器 tcp-services 不起作用?