Ios 如何在swift中在数组中包装(类型擦除)泛型/协议闭包
我有一个协议Ios 如何在swift中在数组中包装(类型擦除)泛型/协议闭包,ios,swift,generics,closures,type-erasure,Ios,Swift,Generics,Closures,Type Erasure,我有一个协议请求和刷新令牌服务 protocol Request { associatedtype EndPointType: EndPoint associatedtype Response: Decodable var url: URL { get } var method: HTTPMethod { get } var headers: HTTPHeaders? { get } var parameters: Parameters?
请求
和刷新令牌服务
protocol Request {
associatedtype EndPointType: EndPoint
associatedtype Response: Decodable
var url: URL { get }
var method: HTTPMethod { get }
var headers: HTTPHeaders? { get }
var parameters: Parameters? { get }
var contentType: ContentType { get }
var adapters: [RequestAdapter] { get }
var decisions: [Decision] { get }
}
协议决策{
func应该应用(请求:Req,数据:data,响应:HTTPURLResponse)->Bool
函数应用(
请求:Req,
数据:数据,
响应:HTTPURLResponse,
结束:@escaping(DecisionAction)->Void)
}
枚举决策操作{
案例延续(数据,HTTPURLResponse)
案例重新启动([决定])
案例错误(错误)
案例完成(请求响应)
}
为了在刷新令牌时阻止另一个api调用,
我必须存储完成(使用泛型类型/协议关闭),然后在刷新令牌之后,
我可以为每个完成,这里的问题是,如何存储与数组中关联类型的闭包
final class RefreshTokenService {
typealias Completion<Req: Request> = (DecisionAction<Req>) -> Void
static let shared = RefreshTokenService()
private let httpClient = HTTPClient()
private let lock = NSLock()
var networkError: Error?
var completions = [Completion]() // Error: Generic parameter Req could not be inferred
func refreshToken<Req>(
request: Req,
data: Data,
response: HTTPURLResponse,
done completion: @escaping (DecisionAction<Req>) -> Void
) where Req : Request {
completions.append(completion)
lock.lock()
// Refresh Token API
let refreshTokenRequest = RefreshTokenRequest()
httpClient.send(refreshTokenRequest) { [weak self] (result) in
guard let self = self else {
return
}
//..... for each completion
}
}
final类刷新令牌服务{
typealias完成=(DecisionAction)->Void
静态let shared=RefreshTokenService()
私有let httpClient=httpClient()
私有let lock=NSLock()
var networkError:错误?
var completions=[Completion]()//错误:无法推断通用参数Req
func刷新令牌(
请求:Req,
数据:数据,
响应:HTTPURLResponse,
完成:@escaping(DecisionAction)->Void
)where-Req:请求{
补全。追加(补全)
lock.lock()
//刷新令牌API
让refreshTokenRequest=refreshTokenRequest()
httpClient.send(refreshTokenRequest){[weak self](结果)输入
保护自己=保护自己{
返回
}
//……每次完工
}
}
您不应该使用闭包。您应该使用NotificationCenter。还有其他方法可以限制同步网络连接。如果您使用URLSession,则可以指定URLSessionConfiguration.httpMaximumConnectionsPerHost=1
final class RefreshTokenService {
typealias Completion<Req: Request> = (DecisionAction<Req>) -> Void
static let shared = RefreshTokenService()
private let httpClient = HTTPClient()
private let lock = NSLock()
var networkError: Error?
var completions = [Completion]() // Error: Generic parameter Req could not be inferred
func refreshToken<Req>(
request: Req,
data: Data,
response: HTTPURLResponse,
done completion: @escaping (DecisionAction<Req>) -> Void
) where Req : Request {
completions.append(completion)
lock.lock()
// Refresh Token API
let refreshTokenRequest = RefreshTokenRequest()
httpClient.send(refreshTokenRequest) { [weak self] (result) in
guard let self = self else {
return
}
//..... for each completion
}
}