向服务器发出请求时,有时需要数据作为结果(例如GET),有时则不需要(例如PUT).在我的例子中,我有一个WebSocket连接,它用于告诉服务器事情(不返回数据),但也用于请求数据(返回的数据).
我已经为服务器定义了一个带有不同类型的请求(事件)的枚举:
public enum OutgoingEvent: String, Codable {
case user
case identification
// ... more events
var objectType: Codable.Type? {
switch(self) {
case .user:
User.self
// ... more cases
default:
nil
}
}
}
objectType
表示预期作为请求结果的对象类型(用于解码接收到的JSON).对于一些事件,这是一些可解码的,对于其他事件,这是空的(没有预期的数据作为返回).
How do I write a function that I can call for all kinds of events, and get as a return either the kind of object specified by 100, or nothing at all (depending on the event)?此外,由于socketIO库的缘故,我需要从基于回调的函数调用转换为Async/AWait语法(但这本身与泛型部分不同).
我试过这个:
func sendWithAck<T: Codable>(event: OutgoingEvent, data: [[String : Any]], completion: @escaping (Result<T?, Error>) -> ()) throws {
// getting data from socket ...
guard let resultType = event.objectType else {
completion(.success(nil))
return
}
guard let decodedObject = try? self.decodeFromDict(object: result, type: resultType) as? T else {
completion(.failure(ServerCommunicationError.invalidDataFromServer("Could not decode result data.")))
return
}
completion(.success(decodedObject))
}
func sendWithAck<T: Codable>(event: OutgoingEvent, data: [[String : Any]]) async throws -> T? {
return try await withCheckedThrowingContinuation { continuation in
do {
try sendWithAck(event: event, data: data) { (result: Result<T?, ServerCommunicationError>) in
continuation.resume(with: result)
}
} catch(let error) {
continuation.resume(throwing: error)
}
}
}
但当你打电话的时候:
let User : User = try await ServerService.shared.sendWithAck(event: event, data: [updateData])
我得到"Generic parameter 'T' could not be inferred"和"Cannot convert value of type 'T?' to specified type 'User'"