smu*_*uka 5 json swift swift4 codable
我用于后端调用的服务返回所有这些 json 结构:
{
"status" : "OK",
"payload" : **something**
}
Run Code Online (Sandbox Code Playgroud)
哪里的东西可以是一个简单的字符串:
{
"status" : "OK",
"payload" : "nothing changed"
}
Run Code Online (Sandbox Code Playgroud)
或嵌套的 json(具有任何属性的任何 json),例如:
{
"status" : "OK",
"payload" : {
"someInt" : 2,
"someString" : "hi",
...
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的结构:
struct GenericResponseModel: Codable {
let status:String?
let payload:String?
}
Run Code Online (Sandbox Code Playgroud)
我想始终将“有效负载”解码为字符串。因此,在第二种情况下,我希望“GenericResponseModel”的有效负载属性包含该字段的 json 字符串,但是如果我尝试解码该响应,则会收到错误消息:
Type 'String' mismatch: Expected to decode String but found a dictionary instead
Run Code Online (Sandbox Code Playgroud)
可以存档我想要的吗?
非常感谢
这个\xe2\x80\xa6怎么样
\n\n声明PayloadType协议\xe2\x80\xa6
protocol PayloadType: Decodable { }\nRun Code Online (Sandbox Code Playgroud)\n\n并 make String,并struct Payload符合它\xe2\x80\xa6
extension String: PayloadType { }\n\nstruct Payload: Decodable, PayloadType {\n let someInt: Int\n let someString: String\n}\nRun Code Online (Sandbox Code Playgroud)\n\n然后制作GenericResponseModelgeneric\xe2\x80\xa6
struct GenericResponseModel<T: PayloadType>: Decodable {\n\n let status: String\n let payload: T\n\n enum CodingKeys: CodingKey {\n case status, payload\n }\n\n init(from decoder: Decoder) throws {\n let container = try decoder.container(keyedBy: CodingKeys.self)\n status = try container.decode(String.self, forKey: .status) \n payload = try container.decode(T.self, forKey: .payload)\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n然后就可以解码如下\xe2\x80\xa6
\n\nlet data = """\n{\n"status" : "OK",\n"payload" : "nothing changed"\n}\n""".data(using: .utf8)!\n\nprint(try JSONDecoder().decode(GenericResponseModel<String>.self, from: data))\n\n// GenericResponseModel<String>(status: "OK", payload: "nothing changed")\nRun Code Online (Sandbox Code Playgroud)\n\n和
\n\nlet data2 = """\n{\n"status" : "OK",\n"payload" : {\n"someInt" : 2,\n"someString" : "hi"\n}\n}\n""".data(using: .utf8)!\n\nprint(try JSONDecoder().decode(GenericResponseModel<Payload>.self, from: data2))\n\n// GenericResponseModel<Payload>(status: "OK", payload: Payload(someInt: 2, someString: "hi"))\nRun Code Online (Sandbox Code Playgroud)\n\n
\n当然,这依赖于你payload提前知道类型。如果有效负载类型错误,您可以通过抛出特定错误来解决此问题\xe2\x80\xa6
enum GenericResponseModelError: Error {\n case wrongPayloadType\n}\nRun Code Online (Sandbox Code Playgroud)\n\n然后\xe2\x80\xa6
\n\ninit(from decoder: Decoder) throws {\n let container = try decoder.container(keyedBy: CodingKeys.self)\n status = try container.decode(String.self, forKey: .status)\n\n do {\n payload = try container.decode(T.self, forKey: .payload)\n } catch {\n throw GenericResponseModelError.wrongPayloadType\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n然后在解码\xe2\x80\xa6时处理这个错误
\n\nlet data = """\n{\n"status" : "OK",\n"payload" : {\n"someInt" : 2,\n"someString" : "hi"\n}\n}\n""".data(using: .utf8)!\n\ndo {\n let response = try JSONDecoder().decode(GenericResponseModel<String>.self, from: data) // Throws\n print(response) \n} catch let error as GenericResponseModelError where error == .wrongPayloadType {\n let response = try JSONDecoder().decode(GenericResponseModel<Payload>.self, from: data2) // Success!\n print(response)\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1604 次 |
| 最近记录: |