Я пытаюсь реализовать стратегию refre sh token в Swift 5 и Combine Framework для iOS.
. Я не планирую использовать какой-либо сторонний пакет, просто использую то, что предоставляемые фреймворком `URLSession.dataTaskPublisher`, поэтому цель состоит в том, чтобы:
- Сделать запрос
- Если запрос не выполнен с 401, обновить sh токен аутентификации ( это еще один запрос)
- После того, как токен refre sh завершен, повторите первый запрос
- Если он не сработает, выведите ошибку, которая будет обработана вызывающей стороной
Это очень тривиальный вариант использования, но, кажется, его очень сложно реализовать в Combine, что делает его действительно трудным для использования в любом реальном сценарии.
Любая помощь будет приветствоваться!
Это моя попытка, которая, к сожалению, не работает
private func dataTaskPublisherWithAuth(for request: URLRequest) -> URLSession.DataTaskPublisher {
return session.dataTaskPublisher(for: request)
.tryCatch { error -> URLSession.DataTaskPublisher in
guard error.errorCode == 401 else {
throw error
}
var components = URLComponents(url: self.baseUrl, resolvingAgainstBaseURL: true)
components?.path += "/refresh"
components?.queryItems = [
URLQueryItem(name: "refresh_token", value: KeychainHelper.RefreshToken),
]
let url = components?.url
var loginRequest = URLRequest(url: url!)
loginRequest.httpMethod = "GET"
loginRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
return session.dataTaskPublisher(for: loginRequest)
.decode(type: LoginResponse.self, decoder: JSONDecoder())
.map { result in
if result.accessToken != nil {
// Save access token
KeychainHelper.AccessToken = result.accessToken!
KeychainHelper.RefreshToken = result.refreshToken!
KeychainHelper.ExpDate = Date(timeIntervalSinceNow: TimeInterval(result.expiresIn!))
}
return result
}
.flatMap { data -> URLSession.DataTaskPublisher in
session.dataTaskPublisher(for: request)
}
}.eraseToAnyPublsiher()
}