使用通用参数创建 async/await 函数
Create async/await function with Generic Parameter
我正在尝试将我的工作完成处理函数转换为新的 async/await 语法,但我在为使用通用参数 (T) 的函数找到正确语法时遇到问题:
我之前用过的和有效的:
typealias CurrentWeatherCompletionHandler = (CurrentWeather?, Error?) -> Void
private func weatherDownload<T: Codable>(weatherType: String, completionHandler completion: @escaping (_ object: T?,_ error: Error?) -> ()) {
let storage = Storage.storage()
let pathReference = storage.reference(withPath: "\(weatherType)"+"-de.json")
pathReference.getData(maxSize: 1 * 1024 * 1024) { data, error in
if let error = error {
print("Error beim \(weatherType) Download: \(error)")
completion(nil, error)
} else {
do {
let weather = try self.decoder.decode(T.self, from: data!)
completion(weather, nil)
} catch let error {
completion(nil, error)
}
}
}
}
func getCurrentWeather(completionHandler completion: @escaping CurrentWeatherCompletionHandler) {
weatherDownload(weatherType: Constants.currentWeatherFolder) { (weather: CurrentWeather?, error) in
completion(weather, error)
}
}
我试过但没有奏效的方法:
private func weatherDownload<T: Codable>(weatherType: String) async -> (weather: T?, error: Error?) {
//same network code as before but with return instead of completion:
return (weather, nil) // Compiler Error: 'nil' requires a contextual type / Unexpected non-void return value in void function
}
func getCurrentWeather() async -> (weather: CurrentWeather?, error: Error?) {
return await weatherDownload(weatherType: Constans.currentWeatherFolder)
}
欢迎任何想法。
本质上,如果您使用的 SDK 不支持并发 API,您可以使用它的唯一方法是调用 withCheckedContinuation
或 withCheckedThrowingContinuation
(用于错误处理).您的代码的问题是我提到的问题,和/或 Swift 没有正确地从 return 类型推断出 T
类型的事实。
希望以下模式对您有用:
private func weatherDownload<T: Codable>(_ type: T.Type, weatherType: String) async throws -> T {
return try await withCheckedThrowingContinuation { continuation in
// Your original code from before,
// with the following difference instead of calling the completion handler:
...
do {
let weather = try self.decoder.decode(T.self, from: data)
continuation.resume(returning: weather)
} catch {
continuation.resume(throwing: error)
}
}
}
我正在尝试将我的工作完成处理函数转换为新的 async/await 语法,但我在为使用通用参数 (T) 的函数找到正确语法时遇到问题:
我之前用过的和有效的:
typealias CurrentWeatherCompletionHandler = (CurrentWeather?, Error?) -> Void
private func weatherDownload<T: Codable>(weatherType: String, completionHandler completion: @escaping (_ object: T?,_ error: Error?) -> ()) {
let storage = Storage.storage()
let pathReference = storage.reference(withPath: "\(weatherType)"+"-de.json")
pathReference.getData(maxSize: 1 * 1024 * 1024) { data, error in
if let error = error {
print("Error beim \(weatherType) Download: \(error)")
completion(nil, error)
} else {
do {
let weather = try self.decoder.decode(T.self, from: data!)
completion(weather, nil)
} catch let error {
completion(nil, error)
}
}
}
}
func getCurrentWeather(completionHandler completion: @escaping CurrentWeatherCompletionHandler) {
weatherDownload(weatherType: Constants.currentWeatherFolder) { (weather: CurrentWeather?, error) in
completion(weather, error)
}
}
我试过但没有奏效的方法:
private func weatherDownload<T: Codable>(weatherType: String) async -> (weather: T?, error: Error?) {
//same network code as before but with return instead of completion:
return (weather, nil) // Compiler Error: 'nil' requires a contextual type / Unexpected non-void return value in void function
}
func getCurrentWeather() async -> (weather: CurrentWeather?, error: Error?) {
return await weatherDownload(weatherType: Constans.currentWeatherFolder)
}
欢迎任何想法。
本质上,如果您使用的 SDK 不支持并发 API,您可以使用它的唯一方法是调用 withCheckedContinuation
或 withCheckedThrowingContinuation
(用于错误处理).您的代码的问题是我提到的问题,和/或 Swift 没有正确地从 return 类型推断出 T
类型的事实。
希望以下模式对您有用:
private func weatherDownload<T: Codable>(_ type: T.Type, weatherType: String) async throws -> T {
return try await withCheckedThrowingContinuation { continuation in
// Your original code from before,
// with the following difference instead of calling the completion handler:
...
do {
let weather = try self.decoder.decode(T.self, from: data)
continuation.resume(returning: weather)
} catch {
continuation.resume(throwing: error)
}
}
}