@@ -14,33 +14,79 @@ final class Interceptor: RequestInterceptor {
1414 private let retryLimit = 1
1515 private var subscriptions : Set < AnyCancellable > = [ ]
1616
17+ private let lock = NSLock ( )
18+ @Published private var isRefreshing = false
19+
1720 func adapt( _ urlRequest: URLRequest ,
1821 for session: Session ,
1922 completion: @escaping ( Result < URLRequest , any Error > ) -> Void ) {
2023
21- var urlRequest = urlRequest
22- if let token = KeychainWorker . shared. read ( key: . access) {
23- urlRequest. setValue ( " Bearer \( token) " , forHTTPHeaderField: " Authorization " )
24+ lock. lock ( )
25+ defer {
26+ lock. unlock ( )
27+ }
28+
29+ switch isRefreshing {
30+ case true :
31+ $isRefreshing
32+ . filter { $0 == false }
33+ . first ( )
34+ . sink { _ in
35+ var urlRequest = urlRequest
36+ if let token = KeychainWorker . shared. read ( key: . access) {
37+ urlRequest. setValue ( " Bearer \( token) " , forHTTPHeaderField: " Authorization " )
38+ }
39+ completion ( . success( urlRequest) )
40+ }
41+ . store ( in: & subscriptions)
42+ case false :
43+ var urlRequest = urlRequest
44+ if let token = KeychainWorker . shared. read ( key: . access) {
45+ urlRequest. setValue ( " Bearer \( token) " , forHTTPHeaderField: " Authorization " )
46+ }
47+ completion ( . success( urlRequest) )
2448 }
25- completion ( . success( urlRequest) )
2649 }
2750
2851 func retry( _ request: Request ,
2952 for session: Session ,
3053 dueTo error: any Error ,
3154 completion: @escaping @Sendable ( RetryResult ) -> Void ) {
3255
33- guard let responseCode = error . asAFError ? . responseCode ,
56+ guard let responseCode = request . response ? . statusCode ,
3457 responseCode == 401 ,
3558 request. retryCount < retryLimit,
3659 let _ = KeychainWorker . shared. read ( key: . refresh) else {
3760 completion ( . doNotRetryWithError( error) )
3861 return
3962 }
4063
41- refreshToken ( ) . sink ( receiveValue: { isRefreshed in
42- completion ( isRefreshed ? . retry : . doNotRetryWithError( error) )
43- } ) . store ( in: & subscriptions)
64+ lock. lock ( )
65+ defer {
66+ lock. unlock ( )
67+ }
68+
69+ switch isRefreshing {
70+ case true :
71+ $isRefreshing
72+ . filter { $0 == false }
73+ . first ( )
74+ . sink { _ in
75+ completion ( . retry)
76+ }
77+ . store ( in: & subscriptions)
78+ case false :
79+ isRefreshing = true
80+ refreshToken ( ) . sink ( receiveValue: { [ weak self] isRefreshed in
81+ guard let self else { return }
82+
83+ lock. lock ( )
84+ isRefreshing = false
85+ lock. unlock ( )
86+
87+ completion ( isRefreshed ? . retry : . doNotRetryWithError( error) )
88+ } ) . store ( in: & subscriptions)
89+ }
4490 }
4591}
4692
0 commit comments