RxSwift-递归可观察量?

时间:2019-08-19 11:23:48

标签: ios rx-swift

学习RxSwift-这是我的问题:

我有一个Web服务,只要令牌过期,它就会使用活动访问令牌来获取数据,然后首先调用令牌生成api,然后调用当前请求以再次运行。以便它具有有效结果的有效访问令牌。

但是我在获取令牌响应时遇到问题,然后调用上一个。请求?

所以我尝试添加一个可观察的请求,然后作为响应检查令牌是否无效,然后调用另一个可观察的返回活动令牌,一旦收到令牌,再次调用较旧的请求。

func apirequest(_ urlConvertible:URLRequestConvertible) -> Observable<[String:AnyObject]> {
  return Observable.create({ observer  -> Disposable in
         let _ = Alamofire.request(urlConvertible).responseJSON  
                      { response in 
         if isTokenExpired() {
             self.generateToken().subscribe(onNext: response {
               self.apirequest(oldRequest)
          })
        }
      }
      return Disposables.create()
   })
}

我期望像任何Rx运算符或任何想法尝试吗?

谢谢

1 个答案:

答案 0 :(得分:0)

我写了一篇有关如何执行此操作的文章:https://medium.com/@danielt1263/retrying-a-network-request-despite-having-an-invalid-token-b8b89340d29

将网络调用代码包装成这样:

/// Builds and makes network requests using the token provided by the service. Will request a new token and retry if the result is an unauthorized (401) error.
///
/// - Parameters:
///   - response: A function that sends requests to the network and emits responses. Can be for example `URLSession.shared.rx.response`
///   - tokenAcquisitionService: The object responsible for tracking the auth token. All requests should use the same object.
///   - request: A function that can build the request when given a token.
///   - Returns: response of a guaranteed authorized network request.
public func getData<T>(response: @escaping (URLRequest) -> Observable<(response: HTTPURLResponse, data: Data)>, tokenAcquisitionService: TokenAcquisitionService<T>, request: @escaping (T) throws -> URLRequest) -> Observable<(response: HTTPURLResponse, data: Data)> {
return Observable
        .deferred { tokenAcquisitionService.token.take(1) }
        .map { try request($0) }
        .flatMap { response($0) }
        .map { response in
            guard response.response.statusCode != 401 else { throw TokenAcquisitionError.unauthorized }
            return response
        }
        .retryWhen { $0.renewToken(with: tokenAcquisitionService) }
}

本文和随附的要点展示了如何编写tokenAcquisitionService并包括单元测试。