获得以下数据模型:
class ResponseMultipleElements<Element: Decodable>: Decodable {
let statuscode: Int
let response_type: Int
let errormessage: String?
let detailresponse: Element?
}
class Element<T: Decodable>: Decodable {
let count: String;
let element: T?
}
对于以下API响应结构:
{
"statuscode": 200,
"response_type": 3,
"errormessage": null,
"detailresponse": {
"count": "1",
"campaigns": [
{
"id": 1,
"name": "Foo",
"targetagegroup": null,
"creator":...
...
}
}
}
我正在像这样触发JSONDecoder:
class APIService: NSObject {
func getCampaignList(completion: @escaping(Result<[Campaign], APIError>) -> Void) {
guard let endpoint = URL(string: apiBaseUrlSecure + "/campaignlist") else {fatalError()}
var request = URLRequest(url: endpoint)
request.addValue("Bearer " + UserDefaults.standard.string(forKey: "authtoken")!, forHTTPHeaderField: "Authorization")
request.httpMethod = "GET"
let dataTask = URLSession.shared.dataTask(with: request) { data, response, error in
guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200, let jsonData = data
else { print("ERROR: ", error ?? "unknown error"); completion(.failure(.responseError)); return }
do {
let response = try JSONDecoder().decode(ResponseMultipleElements<[Campaign]>.self, from: jsonData)
completion(.success(response.detailresponse!))
} catch {
print("Error is: ", error)
completion(.failure(.decodingError))
}
}
dataTask.resume()
}
...
}
而且我终于想像这样利用已解码的广告系列对象
class CoopOverviewViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
//do stuff
// load Campaigns
self.apiService.getCampaignList(completion: {result in
switch result {
case .success(let campaigns):
DispatchQueue.main.async {
print("CAMPAIGN DATA: ", campaigns[0].name)
}
case .failure(let error):
print("An error occured \(error.localizedDescription)")
}
})
...
}
现在我有2个问题:
1)
let element: T?
实际上在此调用的api响应中称为“广告系列”。但是,也可以是其他api响应中具有相同的ResponseMultipleElements周围结构的合作,付款等。有没有办法在这里使密钥可交换,就像我使用泛型对值所做的那样?如果没有,我还能怎么解决这个问题?
2)我收到此错误:
typeMismatch(Swift.Array<Any>,
Swift.DecodingError.Context(codingPath:
[CodingKeys(stringValue: "detailresponse", intValue: nil)],
debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))
我已经告诉Swift,detailresponse的“广告系列”部分是一组广告系列对象-至少这是我在查看api响应时的理解。但是,错误似乎表明这是一本字典。首先,我不明白为什么会这样,我真的很想了解它。其次,我不知道如何告诉它应该期待一个字典而不是一个数组-在这里与泛型有些混淆。
非常感谢您的提前帮助!
您传递了[Campaign]
,这将使let detailresponse:[Campaign]
成为解码器,当它是字典时,解码器将考虑detailresponse
一个数组
let response = try JSONDecoder().decode(ResponseMultipleElements<Campaign>.self, from: jsonData)
class ResponseMultipleElements<Element: Decodable>: Decodable {
let statuscode: Int
let response_type: Int
let errormessage: String?
let detailresponse: Item<Element>?
}
class Item<T: Decodable>: Decodable {
let count: String;
let campaigns: [T]?
}