GSON java 库是否具有为 swift Codable 中存在的键提供替代值的功能?
Is there GSON java libraries feature of providing alternative value for key present in swift Codable?
我遇到了一个 API,我必须重用我现有的 Codable 模型之一来解析 JSON。但是,“service_name”的键在新的 API 中被命名为“name”。我问我的 android 开发人员他是如何使用相同的模型设法解析 JSON 的。他告诉我在 android 中用于解析的 GSON 库中也支持相同的功能。代码如下
@SerializedName(value = "service_name", alternate = ["name"])
我想知道这是否可以在 Codable 中以直接的方式实现。我知道这可以通过变通办法来实现。但是 Swift Codable 开箱即用地支持这个
我的要求:
API JSON 响应 1
API 2 JSON 回应
我正在使用下面的模型进行解析
// MARK: - CustomerOtherServiceResponseModel
struct CustomerOtherServiceResponseModel:Decodable {
let name:String
let externalLink:String?
let type:ServiceType
}
是否可以为两者使用相同的模型API?。编码键只能映射到一个 属性 对吗?。或者有没有其他方法可以使用相同的模型来做同样的事情。
这可以通过实现自定义 init(from:)
来解决,我们首先尝试解码“name”键,如果不起作用,我们尝试使用“service_name”键。
对于第二个密钥,我们使用与为我们合成的不同的 CodingKey 枚举创建一个新的容器对象。
struct Service: Codable {
let name: String
let id: Int
let type: String
enum OtherApiKeys: String, CodingKey {
case name = "service_name"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Int.self, forKey: .id)
if let value = try? container.decodeIfPresent(String.self, forKey: .name) {
name = value
} else {
let otherContainer = try decoder.container(keyedBy: OtherApiKeys.self)
name = try otherContainer.decode(String.self, forKey: .name)
}
type = try container.decode(String.self, forKey: .type)
}
}
由于 json 和你发布的结构代码不匹配,我在这里使用了我自己的结构和 json 但它应该很容易翻译。下面是我的测试数据和代码
let data1 = """
{
"id": 157,
"name": "Some name",
"type": "hair"
}
""".data(using: .utf8)!
let data2 = """
{
"id": 158,
"service_name": "Some name",
"type": "hair"
}
""".data(using: .utf8)!
do {
let decoder = JSONDecoder()
for data in [data1, data2] {
let result = try decoder.decode(Service.self, from: data)
print(result)
}
} catch {
print(error)
}
我遇到了一个 API,我必须重用我现有的 Codable 模型之一来解析 JSON。但是,“service_name”的键在新的 API 中被命名为“name”。我问我的 android 开发人员他是如何使用相同的模型设法解析 JSON 的。他告诉我在 android 中用于解析的 GSON 库中也支持相同的功能。代码如下
@SerializedName(value = "service_name", alternate = ["name"])
我想知道这是否可以在 Codable 中以直接的方式实现。我知道这可以通过变通办法来实现。但是 Swift Codable 开箱即用地支持这个
我的要求:
API JSON 响应 1
API 2 JSON 回应
我正在使用下面的模型进行解析
// MARK: - CustomerOtherServiceResponseModel
struct CustomerOtherServiceResponseModel:Decodable {
let name:String
let externalLink:String?
let type:ServiceType
}
是否可以为两者使用相同的模型API?。编码键只能映射到一个 属性 对吗?。或者有没有其他方法可以使用相同的模型来做同样的事情。
这可以通过实现自定义 init(from:)
来解决,我们首先尝试解码“name”键,如果不起作用,我们尝试使用“service_name”键。
对于第二个密钥,我们使用与为我们合成的不同的 CodingKey 枚举创建一个新的容器对象。
struct Service: Codable {
let name: String
let id: Int
let type: String
enum OtherApiKeys: String, CodingKey {
case name = "service_name"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Int.self, forKey: .id)
if let value = try? container.decodeIfPresent(String.self, forKey: .name) {
name = value
} else {
let otherContainer = try decoder.container(keyedBy: OtherApiKeys.self)
name = try otherContainer.decode(String.self, forKey: .name)
}
type = try container.decode(String.self, forKey: .type)
}
}
由于 json 和你发布的结构代码不匹配,我在这里使用了我自己的结构和 json 但它应该很容易翻译。下面是我的测试数据和代码
let data1 = """
{
"id": 157,
"name": "Some name",
"type": "hair"
}
""".data(using: .utf8)!
let data2 = """
{
"id": 158,
"service_name": "Some name",
"type": "hair"
}
""".data(using: .utf8)!
do {
let decoder = JSONDecoder()
for data in [data1, data2] {
let result = try decoder.decode(Service.self, from: data)
print(result)
}
} catch {
print(error)
}