-
-
Save davidebettio/01448bcf33d28a92cba4dd47d75ba5fb to your computer and use it in GitHub Desktop.
RXMoya renew token
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
provider.request(.requestMessages) | |
.filterSuccessfulStatusCodes() | |
.retryWithAuthIfNeeded() | |
.subscribe { ev in | |
switch ev { | |
case .next(let r): | |
print(r) | |
case .error(let e): | |
self.showFailAlertForOperation(error: e) | |
default: | |
break | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//MARK: – Renew token | |
public extension ObservableType where E == Response { | |
/// Tries to refresh auth token on 401, 403 errors and retry the request. | |
/// If the refresh fails, the signal errors. | |
public func retryWithAuthIfNeeded() -> Observable<E> { | |
return catchError { error -> Observable<Response> in | |
if let moyaError: MoyaError = error as? MoyaError { | |
if let response:Response = moyaError.response { | |
if (response.statusCode == 403 || response.statusCode == 401) { | |
return self.retryAuth() | |
} | |
} | |
} | |
return Observable.error(error) | |
} | |
} | |
private func retryAuth() -> Observable<E> { | |
return self.retryWhen { errorObservable -> Observable<Response> in | |
Observable.zip(errorObservable, Observable.range(start: 1, count: 1), resultSelector: { $1 }).flatMap { event -> Observable<Response> in | |
guard let login: String = AccountManager.getLogin(), let password: String = AccountManager.getPassword() else { | |
self.authError() | |
return errorObservable.flatMap { Observable.error($0) } | |
} | |
return provider.request(.login(login: login, password: password)) | |
.filterSuccessfulStatusCodes() | |
.catchError { error -> Observable<Response> in | |
self.authError() | |
return errorObservable.flatMap { Observable.error($0) } | |
} | |
.flatMapLatest { event -> Observable<Response> in | |
if let resp: HTTPURLResponse = event.response as! HTTPURLResponse? { | |
let cookie = HTTPCookie.cookies(withResponseHeaderFields: resp.allHeaderFields as! [String : String], for: resp.url!) | |
if (cookie.count > 0) && AccountManager.saveToken(cookie[0].value) { | |
return Observable.just(event) | |
} else { | |
self.authError() | |
return errorObservable.flatMap { Observable.error($0) } | |
} | |
} | |
self.authError() | |
return errorObservable.flatMap { Observable.error($0) } | |
} | |
} | |
} | |
} | |
private func authError() { | |
Utils.resetToLoginScreen() | |
let ac = UIAlertController(title: NSLocalizedString("common.error", comment: ""), message: NSLocalizedString("auth.error", comment: ""), preferredStyle: .alert) | |
ac.addAction(UIAlertAction(title: NSLocalizedString("common.ok", comment: ""), style: .default)) | |
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { | |
UIApplication.shared.keyWindow?.rootViewController?.present(ac, animated: true, completion: nil) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment