提取 API 时解码失败 | Swift

Decoding failed while fetching API | Swift

当我打印 self.getTokenBalancesModel 时,它给我一个解码失败的错误。我做错了什么?

ViewModel

import Foundation
import Alamofire

final class TokenBalancesClassAViewModel: ObservableObject {
    
    @Published var getTokenBalancesModel: [GetTokenBalancesItemsModel] = [GetTokenBalancesItemsModel]()
    
    func makeApiRequest() {
        let url = "https://api.covalenthq.com/v1/1/address/0x726A73081C4134b2f639b821377482c71864EBc8/balances_v2/?&key=ckey_4eeea29a22c14701a9844f01151"
        
        AF.request(url).responseData(completionHandler: { data in
            if let apiJsonData = try? JSONDecoder().decode(TokenBalancesModel.self, from: data.data!){
                self.getTokenBalancesModel = apiJsonData.data.items
                print(self.getTokenBalancesModel)
            } else {
                print("Decoding failed")
            }
        })
    }
}

型号

struct TokenBalancesModel: Codable, Hashable {
    let data: TokenBalancesDataModel
    let error: Bool
}

struct TokenBalancesDataModel: Codable, Hashable {
    let address: String
    let quote_currency: String
    let items: [TokenBalancesItemsModel]
}

struct TokenBalancesItemsModel: Codable, Hashable {
    let contract_name: String
    let contract_ticker_symbol: String
//    let logo_url: String
    let balance: Int
    let quote_rate: Float
    let quote: Float
}

很明显在解码部分:

if let apiJsonData = try? JSONDecoder().decode(TokenBalancesModel.self, from: data.data!){

我在哪里犯了错误,但我不明白为什么

相反 try? 如果您发现错误,您将获得更多信息。

在调试常见的捕获链时,我将使用 is

} catch let DecodingError.dataCorrupted(context) {
    print(context)
} catch let DecodingError.keyNotFound(key, context) {
    print("Key '\(key)' not found:", context.debugDescription)
    print("codingPath:", context.codingPath)
} catch let DecodingError.valueNotFound(value, context) {
    print("Value '\(value)' not found:", context.debugDescription)
    print("codingPath:", context.codingPath)
} catch let DecodingError.typeMismatch(type, context) {
    print("Type '\(type)' mismatch:", context.debugDescription)
    print("codingPath:", context.codingPath)
} catch {
    print("error: ", error)
}

使用上面的方法你会看到下面的错误

Type 'Int' mismatch: Expected to decode Int but found a string/data instead. codingPath: [CodingKeys(stringValue: "data", intValue: nil), CodingKeys(stringValue: "items", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "balance", intValue: nil)]

这会让您注意到 TokenBalancesItemsModel.balance 字段的类型不正确。

使用这个,注意选项:

struct TokenBalancesModel: Codable, Hashable {
    let data: TokenBalancesDataModel
    let error: Bool
}

struct TokenBalancesDataModel: Codable, Hashable {
    let address: String?
    let quote_currency: String?
    let items: [TokenBalancesItemsModel]
}

struct TokenBalancesItemsModel: Codable, Hashable {
    let contract_name: String?
    let contract_ticker_symbol: String?
//    let logo_url: String
    let balance:  String?    // <-- here no Int
    let quote_rate: Float?
    let quote: Float?
}