我有方法:
func getUsers(completion: @escaping (_ users: [User]?,_ error: String?)->()) { router.request(.getUsers) { (data, response, error) in
var users = [User]()
users = try JSONDecoder().decode(Array<User>.self, from: responseData)
}
但我想把这个功能做得更通用。 我试过:
func getUsers<T: Decodable>(completion: @escaping (_ users: [T]?,_ error: String?)->()) { router.request(.getUsers) { (data, response, error) in
var users = [T]()
users = try JSONDecoder().decode(Array<T>.self, from: responseData)
completion(users, nil)
}
但是当我从转义关闭调用此func用户数组时是[_]。如果我只使用T用户数组是[User.Type]并且它不符合Decodable,那么我可以JSONDecoder().decode
。怎么看?
答案 0 :(得分:1)
阵列&LT;用户&gt;不能转换为&#39; [_]?&#39;
这是因为 _ users:[T]?类型 可选
您的方法工作正常,您只需要定义可选数组。
self.getUsers{ (res:Array<User>?, error) in
}
我创建了一个类似的
func getUsers<T: Decodable>(completion: @escaping (_ users: [T]?,_ error: String?)->()) {
URLSession.shared.dataTask(with: URL(string: "test")!) { (data, res, error) in
guard let resData = data else {completion(nil,"data is nil"); return}
do {
var users = [T]()
users = try JSONDecoder().decode(Array<T>.self, from:resData)
completion(users, nil)
} catch {
completion(nil, error.localizedDescription)
}
}
并称之为
self.getUsers{ (res:Array<User>?, error) in
}
这是struct
struct User :Codable {
var name:String?
}
答案 1 :(得分:0)
嘿Hds你已经正确地完成了大部分工作,只有一个缺失点是关于Decodables如何工作的知识。
Decodable数组也是可解码的。所以我想说的是你不需要明确提到要解码Array<T>.self
,只要你传递给你自己的函数你就可以把它自己期待Array<T>.self
所以T =&gt; Array<T>
因此,在您调用此函数并将[User]
作为通用参数传递时,T
在解码时将为Array<User>.self
。所以代码应该是这样的。我不确定代码是否会100%编译,因为我有一些缺少的组件,但它可以解决这个问题。
func get<T:Deocdable>(completion: @escaping (_ object: T?,_ error: String?) -> ()) {
router.request(.getUsers) { (data, response, error) in
do {
let object = try JSONDecoder().decode(T.self, from: responseData)
} catch {
fatalError("Decoding failed because: ", error.localizedDescription)
}
}
我还添加了do catch块,因为try JSONDecoder()
会抛出。
另外要添加如何调用方法,如下所示:
get { (users: [User]?, error) in
}
希望这会有所帮助。