【问题标题】:Combine: Outputting Decoded Data from URLSession.shared.dataTaskPublisher组合:从 URLSession.shared.dataTaskPublisher 输出解码数据
【发布时间】:2021-11-22 20:13:50
【问题描述】:

目前,我正在使用此 Combine 代码从 API 获取数据:

        URLSession.shared.dataTaskPublisher(for: url)
            // fetch on background thread
            .subscribe(on: DispatchQueue.global(qos: .background))
            // receive response on main thread
            .receive(on: DispatchQueue.main)
            // ensure there is data
            .tryMap { (data, response) in
                guard
                    let httpResponse = response as? HTTPURLResponse,
                    httpResponse.statusCode == 200 else {
                    throw URLError(.badServerResponse)
                }
                NetworkTimer.shared.stop()
                return data
            }
            // decode JSON data to WeatherAPIDecoder
            .decode(type: WeatherAPIDecoder.self, decoder: JSONDecoder())
            // Handle results
            .sink { (result) in
                // will return success or failure
                //                NSLog("completion: \(result)")
            } receiveValue: { [self] (weatherAPI) in
                // if success, will return wsWeather
                // here you can update your view
                //                NSLog("value: \(wsWeather)")
                processWeatherData(weatherAPI)
            }
            // After receiving response, the URLSession is no longer needed & we can cancel the publisher
            .cancel()

这工作正常,但现在我需要发出两个网络请求,一个用于当前数据,一个用于历史数据。然后我想等待这两个请求的结果并将它们放在一个结构中,我无法解决如何更改URLSession.shared.dataTaskPublisher 以仅返回解码数据。我打算使用 Async Await 从另一个函数调用dataTaskPublisher,然后从数据中创建一个对象并将其传递。任何援助将不胜感激。这必须适用于 iOS 14+。

编辑:

我还没有代码,我的想法是这样的:

函数更新(){ async let (current, _) = URLSession.shared.dataTaskPublisher(for: currentURL) async let (historical, _) = URLSession.shared.dataTaskPublisher(for:historyURL)

guard let combineData = CombinedData(current: current, history: historical) else { throw error } ... }

【问题讨论】:

  • async/await 和 Combine 有点相反。你能多介绍一下你在说什么吗?
  • 更新问题

标签: swift combine


【解决方案1】:

您可以使用MergeMany publisher 来实现。

let requestA = URLSession.shared.dataTaskPublisher(for: URL(string: "")!)
let requestB = URLSession.shared.dataTaskPublisher(for: URL(string: "")!)

Publishers.MergeMany([requestA, requestB]).collect().tryMap {...}

您可能还想看看这篇博文(不是我的)。

https://mattcomi.tumblr.com/post/627300779277025280/waiting-on-multiple-publishers-using-mergemany

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多