Ios 无法转换类型为';(或<;嵌套类型>;)->;无效';到预期的参数类型';(要么<;[[uu]>;)->;无效';
我正在尝试使用Codable with protocols来处理API请求和响应。我查询的API在键“results”下响应一个项目数组: 因此,我希望构造一个嵌套的可编码类型 从下面的代码中,使用完成处理程序中的项可以工作,但使用NestedType或TestResponse无法工作,并返回以下错误:Ios 无法转换类型为';(或<;嵌套类型>;)->;无效';到预期的参数类型';(要么<;[[uu]>;)->;无效';,ios,swift,xcode,swift4,swift4.1,Ios,Swift,Xcode,Swift4,Swift4.1,我正在尝试使用Codable with protocols来处理API请求和响应。我查询的API在键“results”下响应一个项目数组: 因此,我希望构造一个嵌套的可编码类型 从下面的代码中,使用完成处理程序中的项可以工作,但使用NestedType或TestResponse无法工作,并返回以下错误: Cannot convert value of type '(Either<NestedType>) -> Void' to expected argument type '(
Cannot convert value of type '(Either<NestedType>) -> Void' to expected argument type '(Either<[_]>) -> Void'
无法将类型为“(任一)->Void”的值转换为预期的参数类型“(任一)->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
}
<代码>导入基础
枚举{
成功案例(T)
案例错误(错误)
}
枚举APIError:错误{
案例未知,错误响应,jsonDecoder
}
协议客户端{
var会话:URLSession{get}
func get(请求:URLRequest,完成:@escaping(或)->Void)
}
扩展客户端{
var会话:URLSession{
返回URLSession.shared
}
func get(请求:URLRequest,完成:@escaping(或)->Void){
让task=session.dataTask(with:request){(data,response,error)在
保护错误==nil else{
完成(.error(error!))
返回
}
guard let response=响应为?HTTPURLResponse,200..Void){
let request=endpoint.request
打印(请求所有HttpHeaderFields)
打印(“端点请求”,端点)
获取(带:请求,完成:完成)
}
}
typealias项目=[SingleItem]
typealias NestedType=TestResponse
结构TestResponse:Codable{
let结果:[SingleItem]
}
结构SingleItem:可编码{
let id:String
}
您的
fetch
方法的完成处理程序需要声明为接受other
,而不是other
,因为您的get
方法需要接受数组的other
的完成处理程序
顺便说一句,您调用的类型
或者,我们通常调用。解决了这个问题,但我的完成处理程序现在以类似的方式失败了:“Result”中的成员“success”生成“Result”类型的结果,但上下文期望“Result”—这些错误消息只是传递错误类型的情况吗。啊,这是beca我想我没有把它从[t].self改成t.self
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
}