【问题标题】:Refresh token with SwiftUI Combine使用 SwiftUI 组合刷新令牌
【发布时间】:2020-01-13 15:12:24
【问题描述】:

我正在尝试在 Swift 5 和 iOS 的组合框架中实现刷新令牌策略。

我不打算使用任何第三方包,只是使用框架提供的,`URLSession.dataTaskPublisher`,所以我的目标是:

  1. 提出请求
  2. 如果请求失败并返回 401,请刷新身份验证令牌(这是另一个请求)
    1. 刷新令牌完成后,重试第一个请求
    2. 如果失败则抛出错误,由调用者处理

​

这是一个非常微不足道的用例,但似乎很难在 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()

}

【问题讨论】:

  • 我正在尝试实现完全相同的用例。请问您是否成功实现了这一目标?

标签: swift swiftui combine


【解决方案1】:

您应该在发布者here 上使用.tryCatch 方法。这使您可以将错误替换为另一个发布者(例如将错误 401 替换为刷新请求,然后是 map switchToLastest auth 请求)或另一个错误(在这种情况下,如果它不是 401,则只需抛出原始错误)。

请注意,您可能不应该在这里使用 flatMap,因为它与 Rx 中的 .flatMapLatest 或 Reactive Swift 中的 .flatmap(.latest) 不同。你想养成在Combine 中使用.map 和switchToLatest 的习惯(即苹果决定展平和映射是两个独立的运算符)。如果您不这样做,您将在某些生成多个内部发布者的地方遇到麻烦,例如在您键入时进行搜索,因为您不会获得最新的内部值,而是会以任意顺序获得所有这些内容,因为网络请求在不确定的时间内完成。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2015-10-31
  • 2019-06-29
  • 2022-10-31
  • 2020-07-12
  • 1970-01-01
  • 2016-04-23
  • 2019-10-26
  • 2020-06-12
相关资源
最近更新 更多