【问题标题】:How to retry a request after performing authentication?执行身份验证后如何重试请求?
【发布时间】:2019-09-22 07:46:52
【问题描述】:

我正在通过制作应用程序来学习 Swift´s Combine,尝试解决现实世界的用例。

一个常见的情况,我正在执行一个请求,并且身份验证令牌已过期。如果请求失败并出现 401,我想刷新令牌。

类似:

fetchData()
   .flatMap { data, response
      if response.statusCode == 401 {
         refreshToken()
            .fetchData()
      } else {
         Just(data)
      }
   }
   .keepDoingThings()

请记住,这只是伪代码。

我确实尝试了一些东西,但它是一团糟。 :)

如何做到这一点?

谢谢!

【问题讨论】:

  • 通常文档会提前告诉你token什么时候过期。因此,您应该在令牌过期之前刷新它。这将减少您发出的网络请求数。

标签: swift combine


【解决方案1】:

我尝试将我的 RxSwift 版本移植到 Combine,但后者缺少一些关键运算符(retryWhenflatMapFirst)。因此,一种解决方案是将 RxCombine 和 RxSwift 引入您的项目,以便您可以在项目中使用我的 RxSwift 解决方案。

这是我的实现:https://medium.com/@danielt1263/retrying-a-network-request-despite-having-an-invalid-token-b8b89340d29

RxCombine:https://github.com/freak4pc/RxCombine

RxSwift:https://github.com/ReactiveX/RxSwift

我不希望这个答案被认为是正确的,但在将必要的运算符添加到 Combine 之前,它可能是一种解决方法。

【讨论】:

  • 在创建自定义 retryWhen 运算符后,您是否按照 RetryingTokenNetworkService 的要点进行了合并?将它们转换为(本机)组合等价物的要点中有一些要点。
  • @JAHelia 不,我没有。我仍然必须支持 11.4+,所以我还没有使用 Combine。也就是说,唯一的难点是flatMapFirst。也许问如何在 Combine 中做到这一点?
【解决方案2】:

您可以使用tryMap()refreshToken 之前抛出错误,然后执行retry

fetchData()
   .tryMap { data, response in
      if response.statusCode == 401 {
         refreshToken()
            .fetchData()
         throw __MYERROR__.invalidServerResponse
      } else {
         return data
      }
   }
   .retry(3)
   .keepDoingThings()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 1970-01-01
    • 2023-03-10
    • 2014-01-15
    相关资源
    最近更新 更多