Swift5:如何将此JSON响应处理到Swift数据模型中



我是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提供了非JSON数据,在这种情况下,这个答案或使用AlamoFire对其进行解码都不起作用。然而,根据我对其含义的最佳猜测,将以上内容格式化为JSON将给出:

let json = """
{
"id": 1,
"count": "",
"data": [
{
"key1": "value1",
"key2": "value2"
}
],
"message": "SUCCESS",
"response_code": 1
}
"""

在这一点上,更明显的是,data键下的内容不是上面定义的Test的数组,而是字典的数组(在示例中,数组中只有一个enry(。因此,有必要重新指定数据模型。对于如此简单的事情,对于提到的用例,没有真正的理由选择多种类型,所以我们将重新定义Getdata(尽管我不喜欢你的命名,但我仍然坚持它(:

struct Getdata: Decodable {
let all : [[String:String]]

enum CodingKeys: String, CodingKey {
case all = "data"
}
}

为了测试解码,让我们使用标准的JSONDecoder(我手边没有AlamoFire的游乐场,因为我从来不会使用它(:


do {
let wrapper = try JSONDecoder().decode(Getdata.self, from: Data(json.utf8))
print(wrapper.all)
} catch {
print("Decoding error (error.localizedDescription)")
}

此输出

[["key1":"value1","key2":"value 2"]]

正如预期的那样。

现在有了一个有效的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"]]

相关内容

  • 没有找到相关文章

最新更新