上下文闭包类型“(Data?, URLResponse?, Error?) -> Void”需要 3 个参数,但在闭包主体中使用了 1 个
Contextual closure type '(Data?, URLResponse?, Error?) -> Void' expects 3 arguments, but 1 was used in closure body
我正在学习本教程,但出现此错误:
Contextual closure type '(Data?, URLResponse?, Error?) -> Void' expects 3 arguments, but 1 was used in closure body
行: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()
}
我正在学习本教程,但出现此错误:
Contextual closure type '(Data?, URLResponse?, Error?) -> Void' expects 3 arguments, but 1 was used in closure body
行: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()
}