在 SWIFT 4 中使用可编码的数组中的嵌套字典键值



我在下面的结构中有 json

{
"message": null,
"data": {
"admin": {
"UserId": 1,
"CUSTOMER_PROFILING": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
},
"RISK_ASSESSMENT": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
},
"LINK_ANALYSIS": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
},
"BENCH_MARKING": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
},
"SUSPICIOUS_TRANSACTION_REPORTING": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
},
"THRESHOLD_TRANSACTION_REPORTING": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
}
},
"vinoth59": {
"UserId": 15,
"CUSTOMER_PROFILING": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
},
"RISK_ASSESSMENT": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
},
"LINK_ANALYSIS": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
},
"BENCH_MARKING": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
},
"SUSPICIOUS_TRANSACTION_REPORTING": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
},
"THRESHOLD_TRANSACTION_REPORTING": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
}
},
"ba_user": {
"UserId": 16,
"CUSTOMER_PROFILING": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
},
"RISK_ASSESSMENT": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
},
"LINK_ANALYSIS": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
},
"BENCH_MARKING": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
},
"SUSPICIOUS_TRANSACTION_REPORTING": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
},
"THRESHOLD_TRANSACTION_REPORTING": {
"id": 0,
"total": 0,
"high": 0,
"low": 0,
"medium": 0
}
}
},
"status": true
}

我的可编码类如下所示

struct UserRiskReportBase : Codable {
let message : String?
let data : [String:UserRiskReport]?
let status : Bool?
enum CodingKeys: String, CodingKey {
case message = "message"
case data = "data"
case status = "status"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
message = try values.decodeIfPresent(String.self, forKey: .message)
data = try values.decodeIfPresent([String:[String:BenchMarking]].self, forKey: .data)
status = try values.decodeIfPresent(Bool.self, forKey: .status)
}
}
struct UserRiskReport: Codable {
let userID: Int
let customerProfiling, riskAssessment, linkAnalysis, benchMarking: BenchMarking
let suspiciousTransactionReporting, thresholdTransactionReporting: BenchMarking
enum CodingKeys: String, CodingKey {
case userID = "UserId"
case customerProfiling = "CUSTOMER_PROFILING"
case riskAssessment = "RISK_ASSESSMENT"
case linkAnalysis = "LINK_ANALYSIS"
case benchMarking = "BENCH_MARKING"
case suspiciousTransactionReporting = "SUSPICIOUS_TRANSACTION_REPORTING"
case thresholdTransactionReporting = "THRESHOLD_TRANSACTION_REPORTING"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
userID = try values.decodeIfPresent(Int.self, forKey: .userID)!
customerProfiling = try values.decodeIfPresent(BenchMarking.self, forKey: .customerProfiling)!
benchMarking = try values.decodeIfPresent(BenchMarking.self, forKey: .benchMarking)!
riskAssessment = try values.decodeIfPresent(BenchMarking.self, forKey: .riskAssessment)!
suspiciousTransactionReporting = try values.decodeIfPresent(BenchMarking.self, forKey: .suspiciousTransactionReporting)!
linkAnalysis = try values.decodeIfPresent(BenchMarking.self, forKey: .linkAnalysis)!
thresholdTransactionReporting = try values.decodeIfPresent(BenchMarking.self, forKey: .thresholdTransactionReporting)!
}
}
struct BenchMarking : Codable {
let id : Int?
let total : Int?
let high : Int?
let low : Int?
let medium : Int?
enum CodingKeys: String, CodingKey {
case id = "id"
case total = "total"
case high = "high"
case low = "low"
case medium = "medium"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
id = try values.decodeIfPresent(Int.self, forKey: .id)
total = try values.decodeIfPresent(Int.self, forKey: .total)
high = try values.decodeIfPresent(Int.self, forKey: .high)
low = try values.decodeIfPresent(Int.self, forKey: .low)
medium = try values.decodeIfPresent(Int.self, forKey: .medium)
}
}

我能够获得第一级钥匙

let dec = JSONDecoder()
dec.keyDecodingStrategy = .convertFromSnakeCase
let alertList = try dec.decode(UserRiskReportBase.self, from:response.data!)
self.userRiskReportList = alertList.data!
self.headerArr = Array(alertList.data!.keys)
print(self.headerArr)

我得到第一级键,如["admin","vinoth59","ba_user"]。我需要获取二级密钥 ["CUSTOMER_PROFILING","RISK_ASSESSMENT",.....]。如何使用此可编码对象实现

下面对我有用,请注意,我已经做了一些简化并删除了不需要的代码,例如init(from:),我还删除了 可选 对于很多属性

struct UserRiskReportBase : Codable {
let message : String?
let data : [String:UserRiskReport]
let status : Bool?
}
struct UserRiskReport: Codable {
let userID: Int
let customerProfiling, riskAssessment, linkAnalysis, benchMarking: BenchMarking
let suspiciousTransactionReporting, thresholdTransactionReporting: BenchMarking
enum CodingKeys: String, CodingKey, CaseIterable {
case userID = "UserId"
case customerProfiling = "CUSTOMER_PROFILING"
case riskAssessment = "RISK_ASSESSMENT"
case linkAnalysis = "LINK_ANALYSIS"
case benchMarking = "BENCH_MARKING"
case suspiciousTransactionReporting = "SUSPICIOUS_TRANSACTION_REPORTING"
case thresholdTransactionReporting = "THRESHOLD_TRANSACTION_REPORTING"
}
var allKeys: [String] {
get {
CodingKeys.allCases.map {$0.rawValue}
}
}
}
struct BenchMarking : Codable {
let id : Int
let total : Int
let high : Int
let low : Int
let medium : Int
}
do {
let result = try JSONDecoder().decode(UserRiskReportBase.self, from: data)
for item in result.data.values {
print("Report for user: (item.userID)")
print(item.customerProfiling)
print(item.benchMarking)
//print(...)
}
} catch {
print(error)
}
let dec = JSONDecoder()
dec.keyDecodingStrategy = .useDefaultKeys
let alertList = try? dec.decode(UserRiskReportBase.self, from: respData!)
print("Compelete Data: ", alertList)
let baUser = alertList?.data["ba_user"] as? UserRiskReport
print("ba_user", alertList?.data["ba_user"])
print(baUser?.benchMarking.id)
print(baUser?.thresholdTransactionReporting.total)

请记住将.convertFromSnakeCase替换为.useDefaultKeys

最新更新