gpt4 book ai didi

json - 带有嵌套 json 作为字符串的 Swift Codable

转载 作者:可可西里 更新时间:2023-10-31 23:49:51 36 4
gpt4 key购买 nike

我用于后端调用的服务返回所有这些 json 结构:

{
"status" : "OK",
"payload" : **something**
}

something 可以是一个简单的字符串:

{
"status" : "OK",
"payload" : "nothing changed"
}

或嵌套的 json(具有任何属性的任何 json),例如:

{
"status" : "OK",
"payload" : {
"someInt" : 2,
"someString" : "hi",
...
}
}

这是我的结构:

struct GenericResponseModel: Codable {

let status:String?
let payload:String?
}

我想始终将“payload”解码为字符串。所以在第二种情况下,我希望我的“GenericResponseModel”的有效负载属性包含该字段的 json 字符串,但是如果我尝试解码该响应,我会收到错误消息:

Type 'String' mismatch: Expected to decode String but found a dictionary instead

可以存档我想要的吗?

非常感谢

最佳答案

这个怎么样……

声明一个PayloadType协议(protocol)...

protocol PayloadType: Decodable { }

并使Stringstruct Payload符合它……

extension String: PayloadType { }

struct Payload: Decodable, PayloadType {
let someInt: Int
let someString: String
}

然后使 GenericResponseModel 通用...

struct GenericResponseModel<T: PayloadType>: Decodable {

let status: String
let payload: T

enum CodingKeys: CodingKey {
case status, payload
}

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
status = try container.decode(String.self, forKey: .status)
payload = try container.decode(T.self, forKey: .payload)
}
}

然后你可以解码如下...

let data = """
{
"status" : "OK",
"payload" : "nothing changed"
}
""".data(using: .utf8)!

print(try JSONDecoder().decode(GenericResponseModel<String>.self, from: data))

// GenericResponseModel<String>(status: "OK", payload: "nothing changed")

let data2 = """
{
"status" : "OK",
"payload" : {
"someInt" : 2,
"someString" : "hi"
}
}
""".data(using: .utf8)!

print(try JSONDecoder().decode(GenericResponseModel<Payload>.self, from: data2))

// GenericResponseModel<Payload>(status: "OK", payload: Payload(someInt: 2, someString: "hi"))


当然,这依赖于你提前知道payload类型。如果负载类型错误,您可以通过抛出特定错误来解决这个问题……

enum GenericResponseModelError: Error {
case wrongPayloadType
}

然后……

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
status = try container.decode(String.self, forKey: .status)

do {
payload = try container.decode(T.self, forKey: .payload)
} catch {
throw GenericResponseModelError.wrongPayloadType
}
}

然后在你解码的时候处理这​​个错误...

let data = """
{
"status" : "OK",
"payload" : {
"someInt" : 2,
"someString" : "hi"
}
}
""".data(using: .utf8)!

do {
let response = try JSONDecoder().decode(GenericResponseModel<String>.self, from: data) // Throws
print(response)
} catch let error as GenericResponseModelError where error == .wrongPayloadType {
let response = try JSONDecoder().decode(GenericResponseModel<Payload>.self, from: data2) // Success!
print(response)
}

关于json - 带有嵌套 json 作为字符串的 Swift Codable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52851792/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com