【问题标题】:Perform multiple URLSessionDataTask in a single publisher chain [duplicate]在单个发布者链中执行多个 URLSessionDataTask [重复]
【发布时间】:2020-10-16 15:11:45
【问题描述】:

我很确定这应该是可能的,我只是在寻找错误的东西,但我要做的是在同一个发布者链中执行 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

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

提前致谢。 ????

【问题讨论】:

  • URLRequest.jsonRequest 是什么?
  • 这只是一个自定义扩展,它从 url 和 jwt 形成 JSONRequest。

标签: ios swift swiftui combine


【解决方案1】:

这就是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())

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

【讨论】:

  • 我发誓我试过这个,但我无法让它工作,但也许我也做错了什么。我尝试了很多东西。 ? 不过谢谢,我稍后再试一下,看看它是否有效。 ?‍♂️
  • 对,我试过了,但我只是得到Value of protocol type 'Publisher' cannot conform to 'Publisher'; only struct/enum/class types can conform to protocols1. Required by instance method 'flatMap(maxPublishers:_:)' where 'P' = 'Publisher' ? 我从上面的代码中得到的唯一变化是我在.map(\.data) 之间有一个.decode() 步骤和.flatMap
  • 哦,我忘了添加 .decode... 是的,.flatMap 需要一些手动操作才能让编译器正确推断类型(不过,您的错误暗示着别的东西)。我更新了我的答案 - 看看这是否有帮助。
  • 宾果游戏,做到了。我知道它一定是这样简单的。谢谢您的帮助。 ?
  • @NewDev 好的,我认为我发现了一个更接近的平行作为一个副本......我在我的在线书籍apeth.com/UnderstandingCombine/operators/…中调整了这个讨论
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-13
  • 1970-01-01
相关资源
最近更新 更多