Swift解码数组中1957个字典数据的技术求助
Binance Ticker批量解码问题解决方案
原代码核心问题
- Binance的
/ticker/price接口返回的是JSON数组,原代码试图解码为单个PriceApiModel对象,直接导致解码失败。 PriceApiModel模型定义完全错误:- 接口返回字段是
symbol和price,但模型里写的是askPrice,字段不匹配。 - 自定义解码初始化器逻辑混乱,存在无效转换和未定义的
CustomError,编译都通不过。 - 属性声明和赋值不一致(声明
price,最后赋值self.askPrice)。
- 接口返回字段是
修正后的代码
PriceApiModel.swift
import Foundation // 完全匹配Binance /ticker/price接口返回的字段结构 struct PriceApiModel: Hashable, Codable { let symbol: String let price: String // 如果需要将price转为Decimal,可以添加计算属性 var priceDecimal: Decimal? { Decimal(string: price) } }
CallApi.swift
import UIKit class ViewController: UIViewController { let headers = [ "X-RapidAPI-Key": "你的API密钥", "X-RapidAPI-Host": "binance43.p.rapidapi.com" ] func getData() { // 把请求创建放在方法内,避免可变请求的线程安全问题 guard let url = URL(string: "https://binance43.p.rapidapi.com/ticker/price") else { print("无效的URL") return } var request = URLRequest(url: url, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "GET" request.allHTTPHeaderFields = headers let session = URLSession.shared let dataTask = session.dataTask(with: request) { [weak self] data, response, error in guard let self = self else { return } if let error = error { print("请求错误: \(error.localizedDescription)") return } guard let data = data else { print("未获取到数据") return } do { // 解码为数组类型,对应接口返回的JSON数组 let tickers = try JSONDecoder().decode([PriceApiModel].self, from: data) // 遍历所有ticker,自动处理全部1957个数据 for ticker in tickers { print("\(ticker.symbol): \(ticker.price)") // 如果需要用Decimal类型 if let decimalPrice = ticker.priceDecimal { print("\(ticker.symbol) 转换为Decimal: \(decimalPrice)") } } } catch { print("解码失败: \(error.localizedDescription)") // 打印错误详情方便调试 print("错误详情: \(error)") } } dataTask.resume() } }
关键修正点说明
- 模型匹配接口字段:直接使用接口返回的
symbol和price字段,利用Codable默认实现完成解码,不需要自定义初始化器。 - 解码数组类型:将
JSONDecoder().decode(PriceApiModel.self, ...)改为[PriceApiModel].self,对应接口返回的数组结构。 - 修复请求创建逻辑:把
NSMutableURLRequest改为方法内创建的URLRequest,避免类属性可变对象的潜在问题。 - 添加错误详情打印:解码失败时打印具体错误信息,方便调试。
- 批量处理数据:通过遍历解码后的数组,自动处理所有ticker数据,无需手动逐个编写名称。
内容的提问来源于stack exchange,提问作者carl walters
相关产品推荐
相关产品推荐

