我花了很多时间在SO / web上看这些例子,但是我看不出我做错了什么。
我有一个REST服务器返回以下JSON:
{
"data":{
"customers":
[
{
"customerId":27,
"customerName":"Dispatch Tool Customer 1"
}
]
},
"error":"<null>",
"ok":1
}
以及以下表示此数据的类:
public class ResponseBase : Codable
{
public var ok : Int?
public var error : String?
}
public class CustomersResponse : ResponseBase
{
public class Customer : Codable
{
public var customerName : String?
public var customerId : Int?
enum CodingKeys: String, CodingKey {
case customerId = "customerId"
case customerName = "customerName"
}
required public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
customerId = try values.decodeIfPresent(Int.self, forKey: .customerId)
customerName = try values.decodeIfPresent(String.self, forKey: .customerName)
}
}
public class Data : Codable
{
public var customers : [Customer]?
enum CodingKeys: String, CodingKey {
case customers = "customers"
}
required public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
customers = try values.decodeIfPresent([Customer].self, forKey: .customers)
}
}
public var data : Data?
enum CodingKeys: String, CodingKey {
case data = "data"
case error = "error"
case ok = "ok"
}
required public init(from decoder: Decoder) throws {
super.init()
data = try Data(from: decoder)
}
}
以下代码使用Alamofire 4.0调用服务器,然后使用Swift中的JSON解码功能处理响应:
Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: [:]).responseJSON
{
response in
print(response)
print("=============================================================")
do {
let decoder = JSONDecoder()
let model = try decoder.decode(CustomersResponse.self, from: response.data!)
print("done model")
} catch let error {
print("ERROR")
print(error)
}
}
“ ok”和“ error”已正确解码。 “数据”也被解码,但是“客户”始终为零。最初,我有没有初始化程序和CodingKeys的类,但是,我当然得到了相同的结果。
我正在打印响应,我可以看到JSON正确下降了(尽管我不明白为什么它没有以标准JSON格式打印出来-为什么Alamofire为什么用[和:代替[ with =?来自服务器的JSON格式正确(JSON)。
我不确定我还能尝试什么。
答案 0 :(得分:0)
这是对我有用的解决方案。感谢那些回答并指出我正确方向的人:
struct Customer: Decodable
{
let customerId: Int?
let customerName: String?
}
struct CustomerData : Decodable
{
let customers : Array<Customer>?
}
struct ServerResponse<T:Decodable> : Decodable
{
let data : T?
let error : String?
let ok : Bool?
}
typealias CustomersResponse = ServerResponse<CustomerData>
(注意:最初的问题中我有一个Int,但实际上是一个Bool)
答案 1 :(得分:-1)
首先,您正在使用Alamofire的json响应,这意味着结果已被转换为json对象或可可约定的字典。 通过使用可编码进行解码/编码,输入/输出值应为数据类型。这就是为什么您看到带有已解码内容的值的原因。
第二,我不确定您要实现什么目标,所以我将介绍最简单的格式。
struct Customer: Decodable{
let customerId: Int
let customerName: String
}
struct ServerResponse: Decodable {
let ok: Int
let error: String?
let data: [Customer]
}
这是解码响应的最简单方法。对于ServerResponse,我也建议您使用Generic类型,而不是对其进行子类化,
struct ServerResponse<T>: Decodable {
let ok: Int
let error: String?
let data: T
}
typealias CustomerResponse = ServerResponse<[Customer]>
解码任何服务器响应(仅当所有服务器响应格式正确时,才适用coz)