首页 > 解决方案 > 在单个发布者链中执行多个 URLSessionDataTask

问题描述

我很确定这应该是可能的,我只是在寻找错误的东西,但我要做的是在同一个发布者链中执行 2 个网络请求。

基本上,我正在尝试获取 JSON Web 令牌(从 Web 或本地),然后使用该 JWT 执行请求的获取。

我创建了一个自定义订阅和发布者来获取我的 JWT,它在本地存储令牌并检查它是否有效,以便可以重用、续订或首次请求。但是,我无法弄清楚如何将其与 fetch 一起使用。

这就是我所在的位置(请暂时忽略强制展开):

JWTState.publisher(JWTState.urlRequest!)
    .tryMap { (jwtState) -> String in
        guard jwtState.isValid == true else {
            throw JWTError.invalidJWT
        }
        return jwtState.jwt
    }
    .map { (jwt) -> URLRequest in
        URLRequest.jsonRequest(url: url, jwt: jwt)
    }

那时我有一个URLRequst使用有效 JWT 的有效获取,但我无法弄清楚我如何调用下一个URLSession.shared.dataTaskPublisherURLSession.shared.dataTask在链中。

我希望我错过了一些发布者或功能,或者有人可以引导我朝着正确的方向前进。我还猜测我可能必须创建另一个自定义订阅和发布者对,但目前我看不出这样做有什么帮助。

提前致谢。

标签: iosswiftswiftuicombine

解决方案


这是flatMap为了什么。flatMap作用于每个值,但不是将其映射到另一个值,而是将其映射到发布者,在您的情况下,这将是第二个 url 请求。

总体思路是:

let jwtRequest = URLRequest(...)

let fetchDataPublisher = URLSession.shared
   .dataTaskPublisher(for: jwtRequest)
   .map(\.data)
   .decode(type: Token.self, decoder: JSONDecoder()) // get the token
   .flatMap { token -> AnyPublisher<Data, Error> in
       let apiRequest = URLRequest(...) // with token
       
       return URLSession.shared
                 .dataTaskPublisher(for: apiRequest)
                 .map(\.data)
                 .mapError { $0 as Error }
                 .eraseToAnyPublisher()
   }
   .decode(type: Something.self, decoder: JSONDecoder())

这是一个简化的示例,因为我没有处理错误并且对您提取令牌的方式采取了随意性。


推荐阅读