我有一个像这样的 json 响应......
{
"message_code": 1,
"orderCount": 52,
"productCount": 5,
"outstandingPayment": [],
"pendingOrder": [
{
"order_id": 1,
"grand_total": 67.85
"customer_name": “xcvv”
"mobile_number": 2147483647
},
],
"bestWishes": [
{
"customer_id": 1,
"birth_date": "2018-02-02",
"type": "birth_date",
"customer_name": “xcvv”,
"mobile_number": 2147483647
},
{
"customer_id": 1,
"anniversary_date": "2018-02-02",
"type": "anniversary_date",
"customer_name": “sdfs”,
"mobile_number": 2147483647
}
]
}
为了解析pendingOrder
,我制作了一个这样的结构:
struct PendingOrder: Codable {
let order_id: Int
let grand_total: Double
let customer_name: String
let mobileNo: Int
init(order_id : Int, grand_total: Double, customer_name: String, mobileNo: Int) {
self.order_id = order_id
self.grand_total = grand_total
self.customer_name = customer_name
self.mobileNo = mobileNo
}
}
但是我如何为 bestWishes
创建一个结构,因为每个字典都有不同的数据,即第一个字典有一个字段 birth_date
而第二个字典有一个字段 周年纪念日
...?
编辑:在发出 Alamofire 请求时,这就是我解析每个数据并将它们分配给结构的方式。
if let bestWishes = result["bestWishes"] as? [[String:Any]] {
for anItem in bestWishes {
guard let customerId = anItem["customer_id"] as? Int,
let birthdate = anItem["birth_date"] as? String,
let customerName = anItem["customer_name"] as? String,
let mobNo = anItem["mobile_number"] as? Int,
let anniversaryDate = anItem["anniversary_date"] as? String,
let type = anItem["type"] as? String
else {continue}
let bestWishes = BestWishes(customer_id: customerId, birthDate: birthdate, type: type, customer_name: customerName, mobileNo: mobNo, anniversaryDate: anniversaryDate)
self.bestWishesArr.append(bestWishes)
最佳答案
首先,当使用 Codable
时,基本上您不需要初始化程序。
如果没有自定义初始化程序(与 Codable
相关),最合适的解决方案是将两个日期都声明为可选
struct BestWish: Codable {
private enum CodingKeys : String, CodingKey {
case customerID = "customer_id"
case birthDate = "birth_date"
case anniversaryDate = "anniversary_date"
case type
case customerName = "customer_name"
case mobileNumber = "mobile_number"
}
let customerID: Int
let birthDate: String?
let anniversaryDate: String?
let type: String
let customerName : String
let mobileNumber: Int
}
使用自定义初始化程序声明一个属性date
并根据类型解码
anniversary
或birth
struct BestWish: Decodable {
private enum CodingKeys : String, CodingKey {
case customerID = "customer_id"
case birthDate = "birth_date"
case anniversaryDate = "anniversary_date"
case type
case customerName = "customer_name"
case mobileNumber = "mobile_number"
}
let customerID: Int
let date: Date
let type: String
let customerName : String
let mobileNumber: Int
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
customerID = try container.decode(Int.self, forKey: .customerID)
type = try container.decode(String.self, forKey: .type)
if type == "anniversary_date" {
date = try container.decode(Date.self, forKey: .anniversaryDate)
} else {
date = try container.decode(Date.self, forKey: .birthDate)
}
customerName = try container.decode(String.self, forKey: .customerName)
mobileNo = try container.decode(Int.self, forKey: .mobileNumber)
}
}
您可以通过给定的 type
属性区分日期。
要同时解码根对象,您需要一个伞形结构
struct Root : Decodable {
// let pendingOrder : [PendingOrder]
let bestWishes : [BestWish]
}
您必须从 Alamofire 请求中获取 Data
格式的 JSON 字符串,而不是反序列化字典,以将其传递给 JSONDecoder
do {
let decoder = JSONDecoder()
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
decoder.dateDecodingStrategy = .formatted(formatter)
let result = try decoder.decode(Root.self, from: data)
print(result)
} catch { print(error) }
编辑:我添加了代码以将两个日期解码为Date
关于ios - 解析不同类型的 json 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48203822/