首页 > 解决方案 > 使用 JSONDecoder 的 Swift Codable JSON 解析错误

问题描述

我正在尝试使用 Codable 处理 JSON,但是当我使用 JSONDecoder().decode 对其进行解码时出现解析错误。

{
    "data": [
        {
            "id": "90",
            "symbol": "BTC",
            "name": "Bitcoin",
            "nameid": "bitcoin",
            "rank": 1,
            "price_usd": "50513.75",
            "percent_change_24h": "3.03",
            "percent_change_1h": "-0.50",
            "percent_change_7d": "-9.91",
            "price_btc": "1.00",
            "market_cap_usd": "942710364520.73",
            "volume24": 70745042591.75044,
            "volume24a": 107034995571.4168,
            "csupply": "18662452.00",
            "tsupply": "18662452",
            "msupply": "21000000"
        },
        {
            "id": "80",
            "symbol": "ETH",
            "name": "Ethereum",
            "nameid": "ethereum",
            "rank": 2,
            "price_usd": "4052.44",
            "percent_change_24h": "10.17",
            "percent_change_1h": "-0.78",
            "percent_change_7d": "17.75",
            "price_btc": "0.084812",
            "market_cap_usd": "466734637594.73",
            "volume24": 53134000887.50444,
            "volume24a": 87082811090.79503,
            "csupply": "115173595.00",
            "tsupply": "115173595",
            "msupply": ""
        }
    ],
    "info": {
        "coins_num": 5949,
        "time": 1621022046
    }
}

json 就像上面一样,我编写了所有模型,如下所示。

class CoinModel: Codable {
    var data: [Coin]?
    var info: CoinInfo?
    
    enum CodingKeys: String, CodingKey {
        case data
        case info
    }
}

class CoinInfo: Codable {
    var coinsNum: Int?
    var time: TimeInterval?
    
    enum CodingKeys: String, CodingKey {
        case coinsNum = "coins_num"
        case time = "time"
    }
}
class Coin: Codable{
    var csupply: String?
    var id: String?
    var marketCapUsd: String?
    var msupply: Int?
    var name: String?
    var nameid: String?
    var percentChange1h: String?
    var percentChange24h: String?
    var percentChange7d: String?
    var priceBtc: String?
    var priceUsd: String?
    var rank: Int?
    var symbol: String?
    var tsupply: Int?
    var volume24: Double?
    var volume24a: Double?

    enum CodingKeys: String, CodingKey {
        case csupply = "csupply"
        case id = "id"
        case marketCapUsd = "market_cap_usd"
        case msupply = "msupply"
        case name = "name"
        case nameid = "nameid"
        case percentChange1h = "percent_change_1h"
        case percentChange24h = "percent_change_24h"
        case percentChange7d = "percent_change_7d"
        case priceBtc = "price_btc"
        case priceUsd = "price_usd"
        case rank = "rank"
        case symbol = "symbol"
        case tsupply = "tsupply"
        case volume24 = "volume24"
        case volume24a = "volume24a"
    }
}

我的网络功能如下所示。

URLSession.shared.dataTask(with: url) { (data, response, error) in
    guard error == nil else {
        completion(.failure(error!))
        return
    }
    
    guard let data = data else {
        completion(.failure(error ?? NSError()))
        return
    }
    
    let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String: Any]
    
    guard let model = try? JSONDecoder().decode(CoinModel.self, from: data) else {
        completion(.success([]))
        return
    }
    
    completion(.success(model.data ?? []))
    
}.resume()

正如我之前所说,json 对象不是 nil,我得到如下所示。

[({
    csupply = "435032301.00";
    id = 33285;
    "market_cap_usd" = "435337535.24";
    msupply = "";
    name = "USD Coin";
    nameid = "usd-coin";
    "percent_change_1h" = "0.01";
    "percent_change_24h" = "0.19";
    "percent_change_7d" = "0.16";
    "price_btc" = "0.000023";
    "price_usd" = "1.00";
    rank = 100;
    symbol = USDC;
    tsupply = 435032301;
    volume24 = "11520659193.03477";
    volume24a = "13684311331.83874";
}
)
, "info": {
    "coins_num" = 5952;
    time = 1621160044;
}]

我可以使用 JSONSerialization 处理 JSON,但我找不到任何解析错误的原因JSONDecoder。我想我没有看到问题。感谢您的任何建议和帮助。

编辑:

我在我的 Codable 类中进行了一些更改来解决它,我在描述模型时犯了一个错误idcsupply等等。

var csupply: String?
var msupply: String?
var tsupply: String?

标签: iosjsonswiftcodable

解决方案


您在定义对象时有几个错误。例如,您定义id,msupply是一个整数,但它们是字符串。您已经定义了volume24andvolume24a是字符串,但它们不是。您需要解决所有这些问题,这可能就是您无法解析它的原因。

对于硬币对象和您需要转换为的对象,所有错误定义的参数都是id, mSupply, volume24, 。volume24atSupplyinfotimeInt


推荐阅读