Swift 从URLRequest dataTask返回泛型类型

Swift 从URLRequest dataTask返回泛型类型,swift,swift-playground,Swift,Swift Playground,我试图构建一个泛型函数,以便在URLSession的dataTask完成后返回给定类型的数组 我有一个可解码的: struct Todo:可散列、可编码、可识别{ 变量id:Int 变量标题:字符串 完成变量:Bool } 这个功能是: func loadFrom(url:String,memberType:T,completionHandler:(T?)->Void){ guard let url=url(字符串:url)else{ completionHandler(无) } URLSes

我试图构建一个泛型函数,以便在URLSession的dataTask完成后返回给定类型的数组

我有一个可解码的:

struct Todo:可散列、可编码、可识别{
变量id:Int
变量标题:字符串
完成变量:Bool
}
这个功能是:

func loadFrom(url:String,memberType:T,completionHandler:(T?)->Void){
guard let url=url(字符串:url)else{
completionHandler(无)
}
URLSession.shared.dataTask(with:url){data,response,中的错误
guard let data=其他数据{
fatalError(“未返回数据”)
}
做{
let decoder=JSONDecoder()
让结果=尝试解码器。解码(T.self,from:data)
completionHandler(结果)
}抓住{
fatalError(“无法分析数据”)
}
}1.简历()
}
loadFrom(url:)https://jsonplaceholder.typicode.com/todos?completed=true,memberType:Todo){中的响应
...
}
错误:Swift草稿行。错误:61:88:错误:参数类型“Todo.type”不符合预期的类型“Decodable”

我见过类似的问题,这些问题表明编译器无法综合可解码协议一致性所需的方法,但构建一个类似的方法,将其分配给可解码类型,而不是将其指定为参数:

func加载文件(文件:字符串)->T{
...
}
var todos:[Todo]=loadFile(文件:“todos.json”)
打印(待办事项[0]。标题)=>“待办事项标题”
我假设原因是我的
loadFrom
没有指定其返回类型,但我不明白为什么。 是否有可能为这段代码提供足够的编译上下文

你必须申报

func loadFrom<T: Decodable>(url: String, memberType: T.Type, completionHandler: @escaping (T?) -> Void) {

并添加一个更好的结果类型,以在调用该方法之前能够返回错误并捕获错误URL,而不是不愉快的致命错误

func loadFrom<T: Decodable>(url: URL, memberType: T.Type, completionHandler: @escaping (Result<T,Error>) -> Void) {
    URLSession.shared.dataTask(with: url) {data, _, error in
        if let error = error {
            completionHandler(.failure(error))
        } else {
           completionHandler( Result{ try JSONDecoder().decode(T.self, from: data!)})
        }
    }.resume()
} 
func loadFrom(url:url,memberType:T.Type,completionHandler:@escaping(Result)->Void){
URLSession.shared.dataTask(with:url){data,\中出现错误
如果let error=error{
completionHandler(.failure(error))
}否则{
completionHandler(结果{try JSONDecoder().decode(T.self,from:data!))
}
}1.简历()
} 
loadFrom(url:memberType:completionHandler:)
方法中

1.使用
T.Type
而不是
T
作为
memberType

2.
@转义添加到
完成处理程序中

func loadFrom<T: Decodable>(url: String, memberType: T.Type, completionHandler: @escaping ((T?)->())) 
另外,在
guard
语句中添加
return

guard let url = URL(string: url) else {
    completionHandler(nil)
    return //here...
}
loadFrom(url: "https://jsonplaceholder.typicode.com/todos?completed=true", memberType: Todo.self) {response in
     ...
}
guard let url = URL(string: url) else {
    completionHandler(nil)
    return //here...
}