使用 Swift 解码包裹在字典中的 JSON 数组 5
Decoding JSON array wrapped inside dictionary using Swift 5
{
"records": [
{
"id": 1,
"customers_name": "Acme 1"
},
{
"id": 2,
"customers_name": "Acme2"
}
]
}
这是我非常简单的 JSON 方案,但我无法让 JSONDecoder() 工作。
我的错误代码是:
Expected to decode Array but found a dictionary instead.
这是我目前正在使用的两个文件:
Customer.swift
struct Customer: Decodable, Identifiable {
public var id: String
public var customers_name: String
enum CodingKeys: String, CodingKey {
case id = "id"
case customers_name = "customers_name"
}
init(from decoder: Decoder) throws{
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(String.self, forKey: .id)
customers_name = (try container.decodeIfPresent(String.self, forKey: .customers_name)) ?? "Unknown customer name"
}
}
CustomerFetcher.swift
import Foundation
public class CustomerFetcher: ObservableObject {
@Published var customers = [Customer]()
init(){
load()
}
func load() {
let url = URL(string: "https://somedomain.com/customers.json")!
URLSession.shared.dataTask(with: url) {(data,response,error) in
do {
if let d = data {
print(d)
let decodedLists = try JSONDecoder().decode([Customer].self, from: d)
DispatchQueue.main.async {
self.customers = decodedLists
}
} else {
print("No Data")
}
} catch {
print (error)
}
}.resume()
}
}
我相信是因为这个嵌套的 JSON 结构并尝试了很多东西,但仍然无法正常工作。
非常感谢,如果有人能帮助我!
您忘记了包装对象:
struct RecordList<T: Decodable>: Decodable {
let records: [T]
}
let decodedLists = try JSONDecoder().decode(RecordList<Customer>.self, from: d)
DispatchQueue.main.async {
self.customers = decodedLists.records
}
另请注意,Customer
可以简化为:
struct Customer: Decodable, Identifiable {
public var id: String
public var customersName: String
enum CodingKeys: String, CodingKey {
case id
case customersName = "customers_name"
}
}
您还可以将 JSONDecoder
设置为自动将下划线转换为驼峰式大小写。那么你甚至不需要 CodingKeys
.
{
"records": [
{
"id": 1,
"customers_name": "Acme 1"
},
{
"id": 2,
"customers_name": "Acme2"
}
]
}
这是我非常简单的 JSON 方案,但我无法让 JSONDecoder() 工作。 我的错误代码是:
Expected to decode Array but found a dictionary instead.
这是我目前正在使用的两个文件:
Customer.swift
struct Customer: Decodable, Identifiable {
public var id: String
public var customers_name: String
enum CodingKeys: String, CodingKey {
case id = "id"
case customers_name = "customers_name"
}
init(from decoder: Decoder) throws{
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(String.self, forKey: .id)
customers_name = (try container.decodeIfPresent(String.self, forKey: .customers_name)) ?? "Unknown customer name"
}
}
CustomerFetcher.swift
import Foundation
public class CustomerFetcher: ObservableObject {
@Published var customers = [Customer]()
init(){
load()
}
func load() {
let url = URL(string: "https://somedomain.com/customers.json")!
URLSession.shared.dataTask(with: url) {(data,response,error) in
do {
if let d = data {
print(d)
let decodedLists = try JSONDecoder().decode([Customer].self, from: d)
DispatchQueue.main.async {
self.customers = decodedLists
}
} else {
print("No Data")
}
} catch {
print (error)
}
}.resume()
}
}
我相信是因为这个嵌套的 JSON 结构并尝试了很多东西,但仍然无法正常工作。
非常感谢,如果有人能帮助我!
您忘记了包装对象:
struct RecordList<T: Decodable>: Decodable {
let records: [T]
}
let decodedLists = try JSONDecoder().decode(RecordList<Customer>.self, from: d)
DispatchQueue.main.async {
self.customers = decodedLists.records
}
另请注意,Customer
可以简化为:
struct Customer: Decodable, Identifiable {
public var id: String
public var customersName: String
enum CodingKeys: String, CodingKey {
case id
case customersName = "customers_name"
}
}
您还可以将 JSONDecoder
设置为自动将下划线转换为驼峰式大小写。那么你甚至不需要 CodingKeys
.