为JSON创建模型,其中键是一个值 [英] Creating model for JSON where key is a value
问题描述
JSON :
{
"rows" :
[
{
"_id": "5cdc0ede5c3dcb04bdb3a972",
"emp_code": 187,
"log_id": 361711,
"punch_time": "2019-05-07T04:00:33.000Z",
"pin_type": 1,
"status": 4,
"__v": 0
},
{
"_id": "5cdc40de5c3dcb04bdb3a972",
"emp_code": 111,
"log_id": 361701,
"punch_time": "2019-05-07T04:00:35.000Z",
"pin_type": 101,
"status": 4,
"__v": 0
}
],
"pin_type_text": {
"1": "In Fingerprint",
"4": "In Card",
"101": "Out Fingerprint",
"104": "Out Card"
}
}
每行 pin_type 的值是指 pin_type_text 中与其键对应的记录.
The value of pin_type in each row refers to the record in pin_type_text mapped with it's key.
我正在使用 AlamofireObjectMapper 创建模型,这是PinTypeText模型:
I am using AlamofireObjectMapper for creating models, and here is the PinTypeText model :
class PinTypeText : Mappable {
var inFingerprint: String?
var inCard: String?
var outFingerprint: String?
var outCard: String?
required init?(map: Map) {
}
func mapping(map: Map) {
self.inFingerprint <- map["1"]
self.inCard <- map["4"]
self.outFingerprint <- map["101"]
self.outCard <- map["104"]
}
}
问题:假设将来pin_type值- 1、4、101、104 在后端发生变化,如何在不更改模型的情况下处理这种情况? .按照这种模型结构,每当后端模型更改时,我都需要更改模型类
Issue : Suppose in future, the pin_type values - 1, 4, 101, 104 change in the backend, how can I handle such a case without changing my model. As per this model structure, I need to change my model class every time the backend model changes
推荐答案
在这里,您可以使用Codable
作为解决方案,
Here is how you can use Codable
as a solution,
1..创建一个模型Row
,该模型将包含json
的rows
数组中的一行的数据,即
1. Create a model Row
that will contain the data of a single row in rows
array of json
, i.e.
class Row: Decodable {
var id: String?
var pinType: String?
var pinId: Int?
enum CodingKeys: String, CodingKey {
case id = "_id"
case pinId = "pin_type"
}
}
在上面的模型中,我使用了2个不同的属性-pinType and pinId
.
In the above model, I've used 2 different properties - pinType and pinId
.
-
pinId
将在row
pinType
将包含与pinId
相对应的实际值.稍后我们将填充该值.
pinType
will contain the actual value corresponding to pinId
. We'll fill this value later.
此外,我只使用了row
的一小部分键.您可以根据需要添加更多内容.
Also, I've only used a small set of keys of the row
. You can add more as required.
2..接下来,创建另一个模型Response
,该模型将包含Row
的array
,即
2. Next create another model Response
that will contain an array
of Row
, i.e.
class Response: Decodable {
var rows: [Row]?
enum CodingKeys: String, CodingKey {
case rows, pin_type_text
}
required init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
rows = try values.decodeIfPresent([Row].self, forKey: .rows)
let pinTypeText = try values.decodeIfPresent([String:String].self, forKey: .pin_type_text)
rows?.forEach({ (row) in
if let pinId = row.pinId {
row.pinType = pinTypeText?[String(pinId)]
}
})
}
}
在上述模型中,
-
rows
数组被解析为[Row]
.
json
中的 pinTypeText
dictionary
被解析为[String:String]
类型.
[Row]
以使用pinId
和pinTypeText dictionary
在每个row
中填充pinType
.
[Row]
is enumerated to fill pinType
in each row
using pinId
and pinTypeText dictionary
.
使用时,需要使用Row
对象的pinType
属性.
When using, you need to use pinType
property of a Row
object.
response?.rows?.forEach({ print($0.pinType) }) //This line will print - "In Fingerprint" and "Out Fingerprint"
如果遇到实施此方法的问题,请告诉我.
Let me know in case you face issue implementing this approach.
这篇关于为JSON创建模型,其中键是一个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!