【问题标题】:Swift 5 URLSession API Class Throwing Weird ErrorsSwift 5 URLSession API 类抛出奇怪的错误
【发布时间】:2021-03-16 23:14:14
【问题描述】:

立即使用 SwiftUI 学习 Swift。我正在尝试构建一个处理 API 但有很多困难的类。

所以我有一个股票价格函数,我想在有人加载视图时从这个 API 调用它,然后我希望这个函数返回正确的股票价格对象列表,以便我可以将它呈现到图表中。

由于某种原因,我遇到了 Result 没有 .success 函数的问题。

很想知道这里的想法!

这是我现在的代码:

final class StockAPI{


func fetchData(symbol: String, completion: @escaping (Result) -> Void) {
    let url = URL(string: "https://google.com")!
    
    var request = URLRequest(url: url)
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpMethod = "POST"
    let json: [String: Any] = ["symbol": symbol]
    
    let jsonData = try? JSONSerialization.data(withJSONObject: json)

    request.httpBody = jsonData


    let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
        if let error = error {
            //completion(.error(error.localizedDescription as! Error), error)
            return
      }

        do{
            let stockPrices = try? JSONDecoder().decode([StockPrice].self, from: data!)
            
            DispatchQueue.main.async {
                // update our UI
                print("Dispatching request")
                completion(.success(from: stockPrices as! Decoder))
            }
            
        } catch let jsonError {
            return
        }
      
    })
    
    task.resume()
  }

【问题讨论】:

  • 好的,所以我用完成替换了错误,但我得到的结果'对于 func 定义行上的这种上下文中的类型查找是不明确的。
  • 好吧,这真的让我感到沮丧。所以我确实这样做了,并且 swift 拒绝构建这个: func getTheList(completion: @escaping (Result) -> Void) 上面的结果中的“结果”对于这种情况下的类型查找是模棱两可的 不能专门化非-generic type 'Result' 移除 ''
  • 然后当我删除它时,它会告诉我重新添加参数。不知道发生了什么
  • 天哪,你刚刚救了我!这有效,感谢您的示例!这是一次有趣的学习经历。你有什么好书/参考资料可以用于 Swift 吗?
  • 我的荣幸。而且,不,我没有跟上文献,所以我不确定我是否可以为您推荐书名。我个人是一个视觉学习者,所以我尝试查找视频资源,如果过时,我会推荐斯坦福和 LinkedIn 学习。 (而且,不幸的是,它被认为是 S.O. 的主题,所以如果你尝试发布一个询问这些资源的问题,你会被喊下来。)

标签: swift swiftui swift5 urlsession


【解决方案1】:

在您的两种错误情况(网络错误和解析错误)中,您应该使用.failure 和错误来调用您的完成闭包。现在你在瞎飞。

Result 的使用很奇怪,因为它是泛型的,通常采用Result<[StockPrice], Error> 的形式(即指定成功类型是什么,即[StockPrice],以及失败类型是什么,即Error)。 Result 是一个泛型,您要指定 .success.failure 的关联类型是什么类型。

所以,它可能是这样的:

func fetchData(symbol: String, completion: @escaping (Result<[StockPrice], Error>) -> Void) { // if you have compilation error here, try `Swift.Result<[StockPrice], Error>` instead
    let url = URL(string: "https://google.com")!

    var request = URLRequest(url: url)
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpMethod = "POST"
    let object = ["symbol": symbol]

    request.httpBody = try! JSONEncoder().encode(object) // or wrap this in `do`-`catch` block and use `try` without the `!`
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            completion(.failure(error))
            return
        }

        do {
            let stockPrices = try JSONDecoder().decode([StockPrice].self, from: data!)

            DispatchQueue.main.async {
                // update our UI
                print("Dispatching request")
                completion(.success(stockPrices))
            }
        } catch let jsonError {
            completion(.failure(jsonError))
        }
    }

    task.resume()
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    • 2017-07-25
    • 2018-05-11
    • 1970-01-01
    • 1970-01-01
    • 2015-10-25
    相关资源
    最近更新 更多