Swift 完成处理程序中的泛型
Swift generics in completion handler
我正在尝试重构 dat 获取函数以使其适用于多种 Decodable 结构类型。
func fetchData<T: Decodable>(_ fetchRequest: FetchRequestType, completion: @escaping ((Result<T, Error>) -> Void)) {
guard !isFetching else { return }
isFetching = true
guard let url = getURL(fetchRequest) else { assertionFailure("Could not compose URL"); return }
let urlRequest = URLRequest(url: url)
self.session.dataTask(with: urlRequest) { [unowned self] (data, response, error) in
guard let response = response as? HTTPURLResponse,
response.statusCode == 200 else {
self.isFetching = false
completion(.failure(NSError()))
return
}
guard let data = data else { assertionFailure("No data"); return }
if let jsonData = try? JSONDecoder().decode(T.self, from: data) {
self.isFetching = false
completion(.success(jsonData))
} else {
assertionFailure("Could not decode JSON data"); return
}
}.resume()
}
但是当我使用一种 Decodable 类型从控制器调用 func 时,出现编译错误
Generic parameter 'T' could not be inferred
networkClient.fetchData(.accountsSearch(searchLogin: text, pageNumber: 1)) { [unowned self] result in
switch result {
case .success(let dataJSON):
let accountsListJSON = dataJSON as! AccountsListJSON
let fetchedAccounts = accountsListJSON.items
.map({ AccountGeneral(login: [=12=].login, id: [=12=].id, avatarURLString: [=12=].avatarURL, type: [=12=].type) })
self.accounts = fetchedAccounts
case .failure(_):
assertionFailure("Fetching error!")
}
}
请帮我找出发生了什么并解决问题。
如果该方法没有可以指定静态类型的 return 类型,您必须添加一个参数
func fetchData<T: Decodable>(_ fetchRequest: FetchRequestType, type: T.Type, completion: @escaping (Result<T, Error>) -> Void) { ...
并调用它
networkClient.fetchData(.accountsSearch(searchLogin: text, pageNumber: 1), type: AccountsListJSON.self) { [unowned self] result in
并删除沮丧 as! AccountsListJSON
通常可以通过提供 result
类型来帮助编译器推断 T
类型,当您像这样调用 fetchData(_:completion:)
函数时:
networkClient.fetchData(
.accountsSearch(searchLogin: text, pageNumber: 1)
) { [unowned self] (result: Result<AccountsListJSON, Error>) in
...
}
我正在尝试重构 dat 获取函数以使其适用于多种 Decodable 结构类型。
func fetchData<T: Decodable>(_ fetchRequest: FetchRequestType, completion: @escaping ((Result<T, Error>) -> Void)) {
guard !isFetching else { return }
isFetching = true
guard let url = getURL(fetchRequest) else { assertionFailure("Could not compose URL"); return }
let urlRequest = URLRequest(url: url)
self.session.dataTask(with: urlRequest) { [unowned self] (data, response, error) in
guard let response = response as? HTTPURLResponse,
response.statusCode == 200 else {
self.isFetching = false
completion(.failure(NSError()))
return
}
guard let data = data else { assertionFailure("No data"); return }
if let jsonData = try? JSONDecoder().decode(T.self, from: data) {
self.isFetching = false
completion(.success(jsonData))
} else {
assertionFailure("Could not decode JSON data"); return
}
}.resume()
}
但是当我使用一种 Decodable 类型从控制器调用 func 时,出现编译错误
Generic parameter 'T' could not be inferred
networkClient.fetchData(.accountsSearch(searchLogin: text, pageNumber: 1)) { [unowned self] result in
switch result {
case .success(let dataJSON):
let accountsListJSON = dataJSON as! AccountsListJSON
let fetchedAccounts = accountsListJSON.items
.map({ AccountGeneral(login: [=12=].login, id: [=12=].id, avatarURLString: [=12=].avatarURL, type: [=12=].type) })
self.accounts = fetchedAccounts
case .failure(_):
assertionFailure("Fetching error!")
}
}
请帮我找出发生了什么并解决问题。
如果该方法没有可以指定静态类型的 return 类型,您必须添加一个参数
func fetchData<T: Decodable>(_ fetchRequest: FetchRequestType, type: T.Type, completion: @escaping (Result<T, Error>) -> Void) { ...
并调用它
networkClient.fetchData(.accountsSearch(searchLogin: text, pageNumber: 1), type: AccountsListJSON.self) { [unowned self] result in
并删除沮丧 as! AccountsListJSON
通常可以通过提供 result
类型来帮助编译器推断 T
类型,当您像这样调用 fetchData(_:completion:)
函数时:
networkClient.fetchData(
.accountsSearch(searchLogin: text, pageNumber: 1)
) { [unowned self] (result: Result<AccountsListJSON, Error>) in
...
}