从 API 端点发出解析/解码 JSON 到结构对象
Issue Parsing / Decoding JSON from API Endpoint Into Struct Object
我正在编写一个 Swift 5.x 应用程序,使用 Alamofire 5 从我编写的 API 中获取文件列表。 API returns 文件列表作为 JSON 数据对象。然后我想将这些数据放入我创建的结构中。我无法使它正常工作。这是一个示例 JSON 字符串,当您点击 API 端点时,我的服务器发送过来:
[{
"ID": "0d37ee7a-39bf-4eca-b3ec-b3fe840500b5",
"Name": "File01.iso",
"Size": 6148
}, {
"ID": "656e0396-257d-4604-a85c-bdd0593290cd",
"Name": "File02.iso",
"Size": 224917843
}, {
"ID": "275fdf66-3584-4899-8fac-ee387afc2044",
"Name": "File04.iso",
"Size": 5549504
}, {
"ID": "1c73f857-56b5-475b-afe4-955c9d2d87fe",
"Name": "File05.iso",
"Size": 15476866871
}, {
"ID": "bfebbca2-49de-43d7-b5d0-3461b4793b62",
"Name": "File06.iso",
"Size": 37254264
}]
我在 swift 中创建了以下数据模型来保存它:
struct Files: Decodable {
let root: [File]
}
struct File: Decodable, Identifiable {
var id: UUID
var name: String
var size: Int
}
enum CodingKeys: String, CodingKey {
case id = "ID"
case name = "Name"
case size = "Size"
}
然后我使用 Alamofire 5.x 调用 API 端点并尝试解码 JSON 并将其放入有问题的对象中:
func getPackageFilesJSON() {
AF.request("http://localhost:8080/api/v1/list/pkgs").responseDecodable(of: Files.self) { response in
guard let serverFiles = response.value else {
print("Error Decoding JSON")
return
}
let self.serverFilesList = serverFiles
}
}
这失败了。如果我调试打印响应,我得到的结果是:
[Result]: failure(Alamofire.AFError.responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.decodingFailed(error: Swift.DecodingError.typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil)))))
我从来都不擅长创建这些数据模型并将 JSON 解码到其中。我确定我错过了一些愚蠢的东西。我希望有人比我更有见识,或者第二双眼睛可以帮助我完成这项工作。
谢谢,
埃德
JSON 中没有键 root
。 root对象是一个数组
删除
struct Files: Decodable {
let root: [File]
}
并解码
AF.request("http://localhost:8080/api/v1/list/pkgs").responseDecodable(of: [File].self) { response in ...
并将 CodingKeys
枚举移动到 File
结构
struct File: Decodable, Identifiable {
var id: UUID
var name: String
var size: Int
enum CodingKeys: String, CodingKey {
case id = "ID"
case name = "Name"
case size = "Size"
}
}
我正在编写一个 Swift 5.x 应用程序,使用 Alamofire 5 从我编写的 API 中获取文件列表。 API returns 文件列表作为 JSON 数据对象。然后我想将这些数据放入我创建的结构中。我无法使它正常工作。这是一个示例 JSON 字符串,当您点击 API 端点时,我的服务器发送过来:
[{
"ID": "0d37ee7a-39bf-4eca-b3ec-b3fe840500b5",
"Name": "File01.iso",
"Size": 6148
}, {
"ID": "656e0396-257d-4604-a85c-bdd0593290cd",
"Name": "File02.iso",
"Size": 224917843
}, {
"ID": "275fdf66-3584-4899-8fac-ee387afc2044",
"Name": "File04.iso",
"Size": 5549504
}, {
"ID": "1c73f857-56b5-475b-afe4-955c9d2d87fe",
"Name": "File05.iso",
"Size": 15476866871
}, {
"ID": "bfebbca2-49de-43d7-b5d0-3461b4793b62",
"Name": "File06.iso",
"Size": 37254264
}]
我在 swift 中创建了以下数据模型来保存它:
struct Files: Decodable {
let root: [File]
}
struct File: Decodable, Identifiable {
var id: UUID
var name: String
var size: Int
}
enum CodingKeys: String, CodingKey {
case id = "ID"
case name = "Name"
case size = "Size"
}
然后我使用 Alamofire 5.x 调用 API 端点并尝试解码 JSON 并将其放入有问题的对象中:
func getPackageFilesJSON() {
AF.request("http://localhost:8080/api/v1/list/pkgs").responseDecodable(of: Files.self) { response in
guard let serverFiles = response.value else {
print("Error Decoding JSON")
return
}
let self.serverFilesList = serverFiles
}
}
这失败了。如果我调试打印响应,我得到的结果是:
[Result]: failure(Alamofire.AFError.responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.decodingFailed(error: Swift.DecodingError.typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil)))))
我从来都不擅长创建这些数据模型并将 JSON 解码到其中。我确定我错过了一些愚蠢的东西。我希望有人比我更有见识,或者第二双眼睛可以帮助我完成这项工作。
谢谢, 埃德
JSON 中没有键 root
。 root对象是一个数组
删除
struct Files: Decodable {
let root: [File]
}
并解码
AF.request("http://localhost:8080/api/v1/list/pkgs").responseDecodable(of: [File].self) { response in ...
并将 CodingKeys
枚举移动到 File
结构
struct File: Decodable, Identifiable {
var id: UUID
var name: String
var size: Int
enum CodingKeys: String, CodingKey {
case id = "ID"
case name = "Name"
case size = "Size"
}
}