且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

当密钥根据用户输入更改时,如何从json解码变量?

更新时间:2023-01-24 16:51:47

您可以通过为结构创建自定义的init(from:)方法,然后使用两组编码键(包含所有键的enum)来解码动态键在编译时是已知的,另外一个struct您可以使用通过用户输入(包含货币名称)生成的动态键进行初始化.

You can decode the dynamic key by creating a custom init(from:) method for your struct, then using two set of coding keys, an enum containing all keys that are known at compile time and another struct that you initialize using the dynamic keys that are generated using user input (contain the name of the currency).

在您的自定义init(from:)方法中,您只需要使用它们各自的键对每个属性进行解码即可.

In your custom init(from:) method you just need to decode each property using their respective keys.

let chosenCurrency = "gbp"

struct CurrencyResponse: Decodable {
    let name:String
    let symbol:String
    let price:String
    private static var priceKey:String {
        return "price_\(chosenCurrency)"
    }

    private enum SimpleCodingKeys: String, CodingKey {
        case name, symbol
    }

    private struct PriceCodingKey : CodingKey {
        var stringValue: String
        init?(stringValue: String) {
            self.stringValue = stringValue
        }
        var intValue: Int?
        init?(intValue: Int) {
            return nil
        }
    }

    init(from decoder:Decoder) throws {
        let values = try decoder.container(keyedBy: SimpleCodingKeys.self)
        name = try values.decode(String.self, forKey: .name)
        symbol = try values.decode(String.self, forKey: .symbol)
        let priceValue = try decoder.container(keyedBy: PriceCodingKey.self)
        price = try priceValue.decode(String.self, forKey: PriceCodingKey(stringValue:CurrencyResponse.priceKey)!)
    }
}

do {
    let cryptoCurrencies = try JSONDecoder().decode([CurrencyResponse].self, from: priceJSON.data(using: .utf8)!)
} catch {
    print(error)
}

测试JSON:

let priceJSON = """
    [
    {
    "id": "bitcoin",
    "name": "Bitcoin",
    "symbol": "BTC",
    "rank": "1",
    "price_\(chosenCurrency)": "573.137",
    "price_btc": "1.0",
    "24h_volume_\(chosenCurrency)": "72855700.0",
    "market_cap_\(chosenCurrency)": "9080883500.0",
    "available_supply": "15844176.0",
    "total_supply": "15844176.0",
    "percent_change_1h": "0.04",
    "percent_change_24h": "-0.3",
    "percent_change_7d": "-0.57",
    "last_updated": "1472762067"
    },
    {
    "id": "ethereum",
    "name": "Ethereum",
    "symbol": "ETH",
    "rank": "2",
    "price_\(chosenCurrency)": "12.1844",
    "price_btc": "0.021262",
    "24h_volume_\(chosenCurrency)": "24085900.0",
    "market_cap_\(chosenCurrency)": "1018098455.0",
    "available_supply": "83557537.0",
    "total_supply": "83557537.0",
    "percent_change_1h": "-0.58",
    "percent_change_24h": "6.34",
    "percent_change_7d": "8.59",
    "last_updated": "1472762062"
}
]
"""