上下文闭包类型 '(Data?, URLResponse?, Error?) -> Void' 需要 3 个参数,但在闭包主体中使用了 1 个参数

问题描述

我正在关注本教程,但出现此错误

上下文闭包类型 '(Data?,URLResponse?,Error?) -> Void' 需要 3 个参数,但在闭包主体中使用了 1 个

在行:urlSession.dataTask(with: url) { (result) in

private func fetchResources<T: Decodable>(url: URL,completion: @escaping (Result<T,APIServiceError>) -> Void) {
    guard var urlComponents = URLComponents(url: url,resolvingAgainstBaseURL: true) else {
        completion(.failure(.invalidEndpoint))
        return
    }
    let queryItems = [URLQueryItem(name: "api_key",value: apiKey)]
    urlComponents.queryItems = queryItems
    guard let url = urlComponents.url else {
        completion(.failure(.invalidEndpoint))
        return
    }

    urlSession.dataTask(with: url) { (result)  in
        switch result {
            case .success(let (response,data)):
                guard let statusCode = (response as? HTTPURLResponse)?.statusCode,200..<299 ~= statusCode else {
                    completion(.failure(.invalidResponse))
                    return
                }
                do {
                    let values = try self.jsonDecoder.decode(T.self,from: data)
                    completion(.success(values))
                } catch {
                    completion(.failure(.decodeError))
                }
            case .failure(let error):
                completion(.failure(.apiError))
            }
     }.resume()
}

解决方法

这个 dataTask 的闭包需要三个参数,一个 Data?、一个 URLResponse? 和一个 Error?。您编写的代码就像这个闭包只有一个参数,一个 Result。看起来您认为它是一个 Result<(Data,URLResponse),Error>,但事实并非如此。这个 Result 枚举是我们在自己的代码中使用的枚举,但 URLSession 没有使用它。

因此,更改 dataTask 以使用带有三个参数的闭包:

private func fetchResources<T: Decodable>(url: URL,completion: @escaping (Result<T,APIServiceError>) -> Void) {
    guard var urlComponents = URLComponents(url: url,resolvingAgainstBaseURL: true) else {
        completion(.failure(.invalidEndpoint))
        return
    }
    urlComponents.queryItems = [URLQueryItem(name: "api_key",value: apiKey)]
    guard let url = urlComponents.url else {
        completion(.failure(.invalidEndpoint))
        return
    }

    urlSession.dataTask(with: url) { data,response,error in
        guard error == nil else {
            completion(.failure(.apiError))
            return
        }

        guard 
            let data = data,let response = response as? HTTPURLResponse,200...299 ~= response.statusCode 
        else {
            completion(.failure(.invalidResponse))
            return
        }

        do {
            let values = try self.jsonDecoder.decode(T.self,from: data)
            completion(.success(values))
        } catch {
            completion(.failure(.decodeError))
        }
    }.resume()
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...