Skip to content

Instantly share code, notes, and snippets.

@tkersey
Created April 14, 2024 18:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tkersey/4c5fd81a0047aaa4065c572621673c92 to your computer and use it in GitHub Desktop.
Save tkersey/4c5fd81a0047aaa4065c572621673c92 to your computer and use it in GitHub Desktop.
An example of using AsyncStream
import Combine
import Foundation
import os
@MainActor public final class PollingDataModel<DataModels: Sendable> {
private let logger = Logger(subsystem: "Polling", category: "PollingDataModel")
private var pollingTask: Task<Void, Never>?
private var currentlyPolling = false
public init() {}
public func startPolling(
interval: TimeInterval = 10,
triggerInitially: Bool = false,
dataModels: [DataModels],
action: @escaping ([DataModels]) async -> ([DataModels], TimeInterval?),
update: @escaping ([DataModels]) -> Void
) {
guard !currentlyPolling else { return }
currentlyPolling = true
pollingTask = Task {
for await dataModels in await polling(
interval: interval,
triggerInitially: triggerInitially,
dataModels: dataModels,
action: action
) {
update(dataModels)
}
}
}
public func stopPolling() {
guard currentlyPolling else { return }
pollingTask?.cancel()
currentlyPolling = false
}
private func polling(
interval: TimeInterval?,
triggerInitially: Bool = false,
dataModels: [DataModels],
action: @escaping ([DataModels]) async -> ([DataModels], TimeInterval?)
) async -> AsyncStream<[DataModels]> {
AsyncStream { continuation in
var dataModels = dataModels
var interval = interval
Task {
if triggerInitially {
(dataModels, interval) = await action(dataModels)
}
if let currentInterval = interval {
let intervals = Timer.publish(every: currentInterval, on: .main, in: .common)
.autoconnect()
.values
for await _ in intervals {
(dataModels, interval) = await action(dataModels)
continuation.yield(dataModels)
}
}
}
return continuation.finish()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment