首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在触发计时器发布程序时调用URLSession发布程序

如何在触发计时器发布程序时调用URLSession发布程序
EN

Stack Overflow用户
提问于 2021-06-14 20:31:12
回答 2查看 59关注 0票数 1

我想每隔60分钟调用一个基于计时器发布器的URLSession发布器。

看起来这应该是可能的,但不知道该怎么做:

例如:

代码语言:javascript
运行
复制
struct Response: Codable {
    // ... some fields here
}


class MyClass: ObservableObject {
  @Published var response: Response? = nil
  var cancelable : AnyCancelable? 
  func connectPoller() {
    let timer = Timer.TimerPublisher(interval: 60 * 60, runLoop: .main, mode: .default)
    // how to chain this?
    // want to connect the timer to invoke the data task
    URLSession.shared.dataTaskPublisher(for: URL(string: "some-url-here")!).tryMap() { element -> Data in
            guard let httpResponse = element.response as? HTTPURLResponse,
                httpResponse.statusCode == 200 else {
                    throw URLError(.badServerResponse)
                }
            return element.data
        }.decode(type: Response?.self, decoder: JSONDecoder()).eraseToAnyPublisher()
        .replaceError(with: nil).assign(to: \.response, on: self)
    }
}
EN

回答 2

Stack Overflow用户

发布于 2021-06-14 23:33:51

代码语言:javascript
运行
复制
class MyClass: ObservableObject {
    @Published var response: Response? = nil
    
    var cancelable : AnyCancellable?
    
    func connectPoller() {
        let timer = Timer.TimerPublisher(interval: 60 * 60, runLoop: .main, mode: .default)
            .autoconnect()  //<= here
        
        cancelable = timer
            .flatMap { _ in
                URLSession.shared.dataTaskPublisher(for: URL(string: "some-url-here")!).tryMap() { element -> Data in
                    guard let httpResponse = element.response as? HTTPURLResponse,
                          httpResponse.statusCode == 200 else {
                        throw URLError(.badServerResponse)
                    }
                    return element.data
                }
                .decode(type: Response?.self, decoder: JSONDecoder()).eraseToAnyPublisher()
                .replaceError(with: nil)
            }
            .receive(on: RunLoop.main) //<= here
            .assign(to: \.response, on: self)
    }
}
票数 0
EN

Stack Overflow用户

发布于 2021-06-14 23:37:18

为了将Timer发布程序转换为URLSession dataTask发布程序,您需要使用flatMap。此外,您需要确保发布器链不能完成,因为计时器将在该点停止触发。因此,您需要对flatMap内部的错误进行更积极的清理,以便它们不会进一步向下传播。

代码语言:javascript
运行
复制
class MyClass: ObservableObject {
  @Published var response: Response? = nil
  var cancellable : AnyCancellable?
  func connectPoller() {
    cancellable = Timer.publish(every: 5, on: .main, in: .default)
        .autoconnect()
        .flatMap { _ in
            URLSession.shared.dataTaskPublisher(for: URL(string: "https://google.com")!)
                .flatMap { element -> AnyPublisher<Data,Never> in
                    guard let httpResponse = element.response as? HTTPURLResponse,
                                    httpResponse.statusCode == 200 else {
                        return Just(Data()).eraseToAnyPublisher()
                                    }
                    return Just(element.data).eraseToAnyPublisher()
                }
                .decode(type: Response?.self, decoder: JSONDecoder())
                .replaceError(with: nil)
        }
        .print()
        .receive(on: RunLoop.main)
        .assign(to: \.response, on: self)
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67970269

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档