iOS汇率转换器:动态JSON解析与折线图数据适配问题
iOS汇率转换器开发问题解决方案
问题1:动态解析API返回的货币对字段
quicktype生成的硬编码结构体没法适配动态货币对,直接改成动态字典存储或自定义Codable解析即可:
方案1:简化为字典存储
修改APIResult结构体,把固定字段换成字典:
struct APIResult: Codable { let quotes: [String: Double] // 保留其他必要字段,比如timestamp、baseCurrency等 }
使用时直接通过用户选择的货币对拼接字符串取值:
// 假设用户选择了fromCurrency(如USD)和toCurrency(如EUR) let targetPair = "\(fromCurrency.uppercased())\(toCurrency.uppercased())" if let rate = apiResult.quotes[targetPair] { // 拿到对应汇率,做后续处理 }
方案2:自定义Codable支持动态字段
如果想保留结构体形式,可通过自定义解码逻辑实现:
struct Quote: Codable { private var rateMap: [String: Double] subscript(currencyPair: String) -> Double? { rateMap[currencyPair.uppercased()] } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: DynamicKey.self) var tempMap = [String: Double]() for key in container.allKeys { let rate = try container.decode(Double.self, forKey: key) tempMap[key.stringValue] = rate } rateMap = tempMap } private struct DynamicKey: CodingKey { let stringValue: String init?(stringValue: String) { self.stringValue = stringValue } var intValue: Int? { nil } init?(intValue: Int) { nil } } }
调用时通过下标直接获取目标汇率:
let targetPair = "\(fromCurrency)\(toCurrency)" if let rate = quote[targetPair] { // 使用汇率 }
问题2:日期-汇率字典映射到LineChart(基于Charts库)
假设你的数据是[String: Double]格式(键为日期字符串,值为汇率),按以下步骤处理:
- 对日期-汇率数据排序
// 假设数据源是dateRateDict: [String: Double] let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd" // 匹配API返回的日期格式,按需调整 let sortedEntries = dateRateDict.sorted { guard let date1 = dateFormatter.date(from: $0.key), let date2 = dateFormatter.date(from: $1.key) else { return false } return date1 < date2 }
- 生成LineChart所需的ChartDataEntry数组
var chartEntries = [ChartDataEntry]() for (index, (dateStr, rate)) in sortedEntries.enumerated() { // X轴用索引占位,后续通过格式化器转成日期 let entry = ChartDataEntry(x: Double(index), y: rate) entry.data = dateStr as NSString // 存储原始日期字符串,供X轴格式化用 chartEntries.append(entry) }
- 配置LineChartView显示
let dataSet = LineChartDataSet(entries: chartEntries, label: "\(fromCurrency) → \(toCurrency) 汇率走势") dataSet.lineWidth = 2 dataSet.circleRadius = 4 dataSet.setCircleColor(.systemBlue) dataSet.setColor(.systemBlue) let chartData = LineChartData(dataSet: dataSet) lineChartView.data = chartData // 自定义X轴显示日期 let xAxis = lineChartView.xAxis xAxis.valueFormatter = IndexAxisValueFormatter(values: sortedEntries.map { $0.key }) xAxis.granularity = 1 // 确保每个刻度都显示 xAxis.labelRotationAngle = -45 // 旋转标签避免重叠 xAxis.position = .bottom // 隐藏多余元素(可选) lineChartView.legend.enabled = false lineChartView.rightAxis.enabled = false
内容的提问来源于stack exchange,提问作者asduskun
相关产品推荐
相关产品推荐

