【问题标题】:How do I fix the error described during json parsing using combine?如何修复使用 combine 解析 json 期间描述的错误?
【发布时间】: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:请勿发布您的密钥。

标签: json swift combine


【解决方案1】:

您的查询不正确。检查symbol search 的文档,您的URL 必须传入SYMBOL_SEARCH 以进行function 查询。

您对关键字的查询也未按应有的方式进行 URL 编码,因此"S&amp;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&amp;P500" 更改为"S&amp;P 500",因为否则没有结果。您也可以删除SearchResults 中多余的CodingKeys,因为这没有任何效果。

注意:不要暴露你的 API 密钥!

【讨论】:

  • 感谢您的解决方案
猜你喜欢
  • 2021-06-02
  • 2019-02-09
  • 2022-12-13
  • 1970-01-01
  • 2014-09-09
  • 1970-01-01
  • 2016-11-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多