Swift5:如何将此 JSON 响应处理为 Swift 数据模型
Swift5 : How to handle this JSON response into Swift Data Model
我是 Swift 的新手,所以如果这是一个愚蠢的问题,请原谅我
如何将这种类型的响应处理成数据模型,响应是这样的形式:
{
"id" = 1;
count = "";
data = "[{"key":"value","key":"value".......}]";
message = SUCCESS;
"response_code" = 1;
}
AlamofireRequest 获取响应并打印它但是当使用 responseDecodable 时,没有任何反应,Alamofire 请求的代码如下:
let request = AF.request(urlString!,method: .get)
request.responseJSON { (data) in
print(data)
}
request.responseDecodable(of: Test.self) { (response) in
guard let getData = response.value else {return}
print(getData.all[0].firstName) //Nothing prints
}
这就是数据模型的样子:
struct Test: Decodable {
let firstName: String
enum CodingKeys: String, CodingKey {
case firstName = "first_name"
//firstname is inside data of json
}
}
struct Getdata: Decodable {
let all : [Test]
enum CodingKeys: String, CodingKey {
case all = "data"
}
}
想要访问数据中的值并打印它。请说明一下!
尝试解决上面的问题和评论,首先要获得一些有效的 JSON。可能是您的 API 正在提供 non-JSON 数据,在这种情况下,此答案或使用 AlamoFire 对其进行解码都不起作用。然而,将上面的格式设置为 JSON,在我最好的猜测中,将给出:
let json = """
{
"id": 1,
"count": "",
"data": [
{
"key1": "value1",
"key2": "value2"
}
],
"message": "SUCCESS",
"response_code": 1
}
"""
此时更明显的是data
键下的内容不是上面定义的Test
数组,而是一个字典数组(数组中只有一个条目在示例中)。因此,有必要重新指定数据模型。对于这么简单的事情,对于提到的用例,没有真正的理由去使用多种类型,所以我们将重新定义 Getdata(尽管不喜欢,我还是坚持你的命名):
struct Getdata: Decodable {
let all : [[String:String]]
enum CodingKeys: String, CodingKey {
case all = "data"
}
}
为了测试解码,让我们使用标准的 JSON解码器(我手头没有 AlamoFire 的 Playground,因为我从来没有用过它):
do {
let wrapper = try JSONDecoder().decode(Getdata.self, from: Data(json.utf8))
print(wrapper.all)
} catch {
print("Decoding error \(error.localizedDescription)")
}
这输出
[["key1": "value1", "key2": "value2"]]
符合预期。
现在有一个有效的 JSON 解码解决方案,如果您愿意,将它放入 AlamoFire API 应该很容易。尽管如果后端确实提供了所讨论的格式错误的 JSON,这将不起作用,您将不得不更改后端,使用您自己的解码器对其进行解码,或者将其分解为有效的 JSON。
原题犯了很多愚蠢的错误,还有很长的路要走
按照@flanker 的建议,我确实将数据模型重新指定为
struct Test : Codable {
let id : String?
let message : String?
let data : String?
let count : String?
let response_code : String?
enum CodingKeys: String, CodingKey {
case id = "$id"
case message = "message"
case data = "data"
case count = "count"
case response_code = "response_code"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
id = try values.decodeIfPresent(String.self, forKey: .id)
message = try values.decodeIfPresent(String.self, forKey: .message)
data = try values.decodeIfPresent(String.self, forKey: .data)
count = try values.decodeIfPresent(String.self, forKey: .count)
response_code = try values.decodeIfPresent(String.self, forKey: .response_code)
}
现在好像可以了
现在得到了想要的输出
[["key1": "value1", "key2": "value2"]]
我是 Swift 的新手,所以如果这是一个愚蠢的问题,请原谅我 如何将这种类型的响应处理成数据模型,响应是这样的形式:
{
"id" = 1;
count = "";
data = "[{"key":"value","key":"value".......}]";
message = SUCCESS;
"response_code" = 1;
}
AlamofireRequest 获取响应并打印它但是当使用 responseDecodable 时,没有任何反应,Alamofire 请求的代码如下:
let request = AF.request(urlString!,method: .get)
request.responseJSON { (data) in
print(data)
}
request.responseDecodable(of: Test.self) { (response) in
guard let getData = response.value else {return}
print(getData.all[0].firstName) //Nothing prints
}
这就是数据模型的样子:
struct Test: Decodable {
let firstName: String
enum CodingKeys: String, CodingKey {
case firstName = "first_name"
//firstname is inside data of json
}
}
struct Getdata: Decodable {
let all : [Test]
enum CodingKeys: String, CodingKey {
case all = "data"
}
}
想要访问数据中的值并打印它。请说明一下!
尝试解决上面的问题和评论,首先要获得一些有效的 JSON。可能是您的 API 正在提供 non-JSON 数据,在这种情况下,此答案或使用 AlamoFire 对其进行解码都不起作用。然而,将上面的格式设置为 JSON,在我最好的猜测中,将给出:
let json = """
{
"id": 1,
"count": "",
"data": [
{
"key1": "value1",
"key2": "value2"
}
],
"message": "SUCCESS",
"response_code": 1
}
"""
此时更明显的是data
键下的内容不是上面定义的Test
数组,而是一个字典数组(数组中只有一个条目在示例中)。因此,有必要重新指定数据模型。对于这么简单的事情,对于提到的用例,没有真正的理由去使用多种类型,所以我们将重新定义 Getdata(尽管不喜欢,我还是坚持你的命名):
struct Getdata: Decodable {
let all : [[String:String]]
enum CodingKeys: String, CodingKey {
case all = "data"
}
}
为了测试解码,让我们使用标准的 JSON解码器(我手头没有 AlamoFire 的 Playground,因为我从来没有用过它):
do {
let wrapper = try JSONDecoder().decode(Getdata.self, from: Data(json.utf8))
print(wrapper.all)
} catch {
print("Decoding error \(error.localizedDescription)")
}
这输出
[["key1": "value1", "key2": "value2"]]
符合预期。
现在有一个有效的 JSON 解码解决方案,如果您愿意,将它放入 AlamoFire API 应该很容易。尽管如果后端确实提供了所讨论的格式错误的 JSON,这将不起作用,您将不得不更改后端,使用您自己的解码器对其进行解码,或者将其分解为有效的 JSON。
原题犯了很多愚蠢的错误,还有很长的路要走
按照@flanker 的建议,我确实将数据模型重新指定为
struct Test : Codable {
let id : String?
let message : String?
let data : String?
let count : String?
let response_code : String?
enum CodingKeys: String, CodingKey {
case id = "$id"
case message = "message"
case data = "data"
case count = "count"
case response_code = "response_code"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
id = try values.decodeIfPresent(String.self, forKey: .id)
message = try values.decodeIfPresent(String.self, forKey: .message)
data = try values.decodeIfPresent(String.self, forKey: .data)
count = try values.decodeIfPresent(String.self, forKey: .count)
response_code = try values.decodeIfPresent(String.self, forKey: .response_code)
}
现在好像可以了
现在得到了想要的输出
[["key1": "value1", "key2": "value2"]]