无法将类型“(Either<NestedType>) -> Void”的值转换为预期的参数类型“(Either<[_]>) -> Void”
Cannot convert value of type '(Either<NestedType>) -> Void' to expected argument type '(Either<[_]>) -> Void'
我正在尝试将 Codable 与协议一起使用来处理 API 请求和响应。我正在查询的 API 响应键 "results":
下的一组项目
{ results: ["id": "1", "id": "2"] }
因此,我希望构建一个嵌套的 Codable 类型。
从下面的代码来看,在完成处理程序中使用 Items 有效,但使用 NestedType 或 TestResponse 无效,returns 出现以下错误:
Cannot convert value of type '(Either<NestedType>) -> Void' to expected argument type '(Either<[_]>) -> Void'
我不确定为什么这不起作用。尝试使用 Swift 4 和 Swift 4.1
import Foundation
enum Either<T> {
case success(T)
case error(Error)
}
enum APIError: Error {
case unknown, badResponse, jsonDecoder
}
protocol APIClient {
var session: URLSession { get }
func get<T: Codable>(with request: URLRequest, completion: @escaping (Either<[T]>) -> Void)
}
extension APIClient {
var session: URLSession {
return URLSession.shared
}
func get<T: Codable>(with request: URLRequest, completion: @escaping (Either<[T]>) -> Void) {
let task = session.dataTask(with: request) { (data, response, error) in
guard error == nil else {
completion(.error(error!))
return
}
guard let response = response as? HTTPURLResponse, 200..<300 ~= response.statusCode else {
completion(.error(APIError.badResponse))
return
}
guard let value = try? JSONDecoder().decode([T].self, from: data!) else {
completion(.error(APIError.jsonDecoder))
return
}
DispatchQueue.main.async {
completion(.success(value))
}
}
task.resume()
}
}
class TestClient: APIClient {
func fetch(with endpoint: TestEndpoint, completion: @escaping (Either<NestedType>) -> Void) {
let request = endpoint.request
print(request.allHTTPHeaderFields)
print("endpoint request", endpoint)
get(with: request, completion: completion)
}
}
typealias Items = [SingleItem]
typealias NestedType = TestResponse
struct TestResponse: Codable {
let result: [SingleItem]
}
struct SingleItem: Codable {
let id: String
}
您的 fetch
方法的完成处理程序需要声明为采用 Either<[NestedType]>
,而不是 Either<NestedType>
,因为您的 get
方法需要一个完成处理程序,该处理程序采用Either
个数组。
顺便说一句,你所说的类型Either
,我们一般都叫Result
。
我正在尝试将 Codable 与协议一起使用来处理 API 请求和响应。我正在查询的 API 响应键 "results":
下的一组项目{ results: ["id": "1", "id": "2"] }
因此,我希望构建一个嵌套的 Codable 类型。
从下面的代码来看,在完成处理程序中使用 Items 有效,但使用 NestedType 或 TestResponse 无效,returns 出现以下错误:
Cannot convert value of type '(Either<NestedType>) -> Void' to expected argument type '(Either<[_]>) -> Void'
我不确定为什么这不起作用。尝试使用 Swift 4 和 Swift 4.1
import Foundation
enum Either<T> {
case success(T)
case error(Error)
}
enum APIError: Error {
case unknown, badResponse, jsonDecoder
}
protocol APIClient {
var session: URLSession { get }
func get<T: Codable>(with request: URLRequest, completion: @escaping (Either<[T]>) -> Void)
}
extension APIClient {
var session: URLSession {
return URLSession.shared
}
func get<T: Codable>(with request: URLRequest, completion: @escaping (Either<[T]>) -> Void) {
let task = session.dataTask(with: request) { (data, response, error) in
guard error == nil else {
completion(.error(error!))
return
}
guard let response = response as? HTTPURLResponse, 200..<300 ~= response.statusCode else {
completion(.error(APIError.badResponse))
return
}
guard let value = try? JSONDecoder().decode([T].self, from: data!) else {
completion(.error(APIError.jsonDecoder))
return
}
DispatchQueue.main.async {
completion(.success(value))
}
}
task.resume()
}
}
class TestClient: APIClient {
func fetch(with endpoint: TestEndpoint, completion: @escaping (Either<NestedType>) -> Void) {
let request = endpoint.request
print(request.allHTTPHeaderFields)
print("endpoint request", endpoint)
get(with: request, completion: completion)
}
}
typealias Items = [SingleItem]
typealias NestedType = TestResponse
struct TestResponse: Codable {
let result: [SingleItem]
}
struct SingleItem: Codable {
let id: String
}
您的 fetch
方法的完成处理程序需要声明为采用 Either<[NestedType]>
,而不是 Either<NestedType>
,因为您的 get
方法需要一个完成处理程序,该处理程序采用Either
个数组。
顺便说一句,你所说的类型Either
,我们一般都叫Result
。