无法转换类型'的值(<nestedtype>) - &gt; Void'到预期的参数类型'(Either&lt; [_]&gt;) - &gt;虚空”

时间:2018-04-25 21:05:39

标签: ios swift xcode swift4 swift4.1

我正在尝试使用Codable协议来处理API请求和响应。我正在查询的API以“结果”键下的一系列项目作出响应:

{ results: ["id": "1", "id": "2"] }

因此,我希望构建一个嵌套的Codable类型。

从下面的代码中,使用完成处理程序中的Items可以正常工作,但使用NestedType或TestResponse不起作用并返回以下错误:

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
}

1 个答案:

答案 0 :(得分:2)

您的fetch方法的完成处理程序需要声明为Either<[NestedType]>,而不是Either<NestedType>,因为您的get方法需要一个带Either的完成处理程序1}}一个数组。

顺便提一下,您调用Either的类型,我们通常会调用Result