如何修复使用 combine 解析 json 期间描述的错误?
Posted
技术标签:
【中文标题】如何修复使用 combine 解析 json 期间描述的错误?【英文标题】:How do I fix the error described during json parsing using combine? 【发布时间】:2022-01-04 04:25:29 【问题描述】:我正在尝试使用组合框架解析来自网站 alphavantage.com 的股票数据。尽管我的数据模型具有与 json 匹配的正确值,但我仍不断收到此 error Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"bestMatches\", intValue: nil) (\"bestMatches\").", underlyingError: nil))
。我该如何解决这个问题?
struct SearchResults: Decodable
let bestMatches : [SearchResult]
enum CodingKeys: String, CodingKey
case bestMatches = "bestMatches"
struct SearchResult : Decodable
let symbol : String?
let name : String?
let type : String?
let currency :String?
enum CodingKeys:String, CodingKey
case symbol = "1. symbol"
case name = "2. name"
case type = "3. type"
case currency = "8. currency"
struct APIservice
let apiKey = "U893NJLDIREGERHB"
func fetchSymbols(keyword:String)-> AnyPublisher<SearchResults,Error>
let urlSTring = "https://www.alphavantage.co/query?function=\(keyword)H&keywords=tesco&apikey=U893NJLDIREGERHB"
let url = URL(string: urlSTring)!
return URLSession.shared.dataTaskPublisher(for: url)
.map($0.data)
.decode(type: SearchResults.self, decoder: JSONDecoder())
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
func performSearch()
apiSerivice.fetchSymbols(keyword: "S&P500").sink (completion) in
switch completion
case .failure(let error):
print(error)
case . finished:
break
receiveValue: (SearchResults) in
print(SearchResults.bestMatches)
.store(in: &subcribers)
【问题讨论】:
这不是一个有效的查询。您要使用的“功能”是什么? performSearch 功能是我想要使用的。它在 viewdidload 中被调用 正如@George 所说:It's not a valid query
。 P.S:请勿发布您的密钥。
【参考方案1】:
您的查询不正确。检查symbol search 的文档,您的URL 必须传入SYMBOL_SEARCH
以进行function
查询。
您对关键字的查询也未按应有的方式进行 URL 编码,因此"S&P 500"
存在在插入字符串时创建无效查询的问题。更好的方法是使用URLComponents
,以便安全地为您处理。
代码:
func fetchSymbols(keyword: String) -> AnyPublisher<SearchResults, Error>
guard var components = URLComponents(string: "https://www.alphavantage.co/query") else
return Fail(
outputType: SearchResults.self,
failure: APIError.invalidComponents
).eraseToAnyPublisher()
components.queryItems = [
URLQueryItem(name: "function", value: "SYMBOL_SEARCH"),
URLQueryItem(name: "keywords", value: keyword),
URLQueryItem(name: "apikey", value: apiKey)
]
guard let url = components.url else
return Fail(
outputType: SearchResults.self,
failure: APIError.invalidURL
).eraseToAnyPublisher()
return URLSession.shared.dataTaskPublisher(for: url)
.map(\.data)
.decode(type: SearchResults.self, decoder: JSONDecoder())
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
enum APIError: Error
case invalidComponents
case invalidURL
我将查询从"S&P500"
更改为"S&P 500"
,因为否则没有结果。您也可以删除SearchResults
中多余的CodingKeys
,因为这没有任何效果。
注意:不要暴露你的 API 密钥!
【讨论】:
感谢您的解决方案以上是关于如何修复使用 combine 解析 json 期间描述的错误?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 localStorage 修复 Vuex 中的 JSON 解析错误