【问题标题】:Contextual closure type '(Data?, URLResponse?, Error?) -> Void' expects 3 arguments, but 1 was used in closure body上下文闭包类型 '(Data?, URLResponse?, Error?) -> Void' 需要 3 个参数,但 1 在闭包主体中使用
【发布时间】:2021-01-11 02:19:59
【问题描述】:

我正在学习本教程,但收到此错误:

上下文闭包类型 '(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()
}

【问题讨论】:

  • @Rob 我修复了 URLSession 预期的参数,但现在错误是 switch 语句上的“在范围内找不到'结果'”
  • 这更有意义@Rob 非常感谢!

标签: ios swift closures nsurlsession urlsession


【解决方案1】:

dataTask 的这个闭包需要三个参数:Data?URLResponse?Error?。你的代码写得好像这个闭包只有一个参数,Result。看起来您认为它是 Result&lt;(Data, URLResponse), Error&gt;,但事实并非如此。这个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()
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-21
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    相关资源
    最近更新 更多