【发布时间】:2019-07-29 03:37:46
【问题描述】:
我正在为我的 API 调用创建一个通用的帖子正文,我的帖子正文大部分是相同的,只是不同 API 调用的数据参数不同,数据充当不同要求的填充物,低于 JSON 帖子正文。
示例 1:
{
"timeStampUtc": "2019-07-29T03:29:21.729Z",
...
"geoLocationInfo": {
"latitude": 0,
"longitude": 0,
...
},
"data": {
"loginIdentity": "string",
"loginPassword": "string"
}
}
示例 2:
{
"timeStampUtc": "2019-07-29T03:29:21.729Z",
...
"geoLocationInfo": {
"latitude": 0,
"longitude": 0,
...
},
"data": {
"wazId": 0,
"regionId": 0
}
}
示例 3:
{
"timeStampUtc": "2019-07-29T03:29:21.729Z",
...
"geoLocationInfo": {
"latitude": 0,
"longitude": 0,
...
},
"data": {
"loginIdentity": "string",
"wazID": 0
}
}
我正在使用可编码和泛型来克服这个要求,我能够完成前两个场景,但是当数据具有不同类型的值时,我会遇到第三个场景。 以下是示例代码,可以在 Playground 中直接试用
struct PostBody<T : Codable>: Codable
{
var deviceInfo = ""
var geoLocationInfo = ""
var data = Dictionary<String, T>()
enum CodingKeys: String, CodingKey
{
case deviceInfo, geoLocationInfo, data
}
init(dataDict : Dictionary<String, T>) {
self.data = dataDict
}
init(from decoder : Decoder) throws {
let container = try decoder.container(keyedBy : CodingKeys.self)
deviceInfo = try container.decode(String.self, forKey: .deviceInfo)
geoLocationInfo = try container.decode(String.self, forKey: .geoLocationInfo)
data = try container.decode(Dictionary.self, forKey: .data)
}
func encode(to encoder : Encoder)
{
var container = encoder.container(keyedBy : CodingKeys.self)
do
{
try container.encode(deviceInfo, forKey : .deviceInfo)
try container.encode(geoLocationInfo, forKey : .geoLocationInfo)
try container.encode(data, forKey : .data)
}
catch
{
fatalError("Should never happen")
}
}
}
let postBody = PostBody<String>(dataDict : ["1" : "1", "2" : "2"])
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
try encoder.encode(postBody)
let encodedDataDict2 = try encoder.encode(postBody)
print(String(data : encodedDataDict2, encoding : .utf8)!)
let postBody1 = PostBody(dataDict : ["1" : 1, "2" : 2])
let encoder1 = JSONEncoder()
encoder1.outputFormatting = .prettyPrinted
try encoder1.encode(postBody1)
let encodedDataDict3 = try encoder1.encode(postBody1)
print(String(data : encodedDataDict3, encoding : .utf8)!)
【问题讨论】: