Home > Blockchain >  How to cancel/invalidate timer of type AnyPublisher<Date,Never> in SwiftUI?
How to cancel/invalidate timer of type AnyPublisher<Date,Never> in SwiftUI?

Time:08-20

I'm new in the Combine world and i have var timer: AnyPublisher<Date,Never> to 're-use' the timer i have in the ContentView for my SecondView, do i have to invalidate/cancel the timer when i no longer need it? If yes, how to do it?

In the previous code with a timer of type Timer.TimerPublisher if i had to cancel it I did it using: timer.upstream.connect().cancel() and now of course it keeps giving me this error: Value of type 'AnyPublisher<Date, Never>' has no member 'upstream'

CodePudding user response:

Maybe something like this can help?

private var timerSubscription: AnyCancellable?

func setupTimer(every interval: TimeInterval, repeats: Bool, onReceive: @escaping (() -> Void)) {
    invalidateTimer()

    timerSubscription = Timer
        .publish(every: interval, on: .main, in: .common)
        .autoconnect()
        .sink { _ in
            onReceive()
            if !repeats {
                self.invalidateTimer()
            }
        }
}

func invalidateTimer() {
    timerSubscription?.cancel()
}

full service:

final class CombineTimerService {

// MARK: - Public Properties

var isCancelled: Bool {
    return timerSubscription == nil
}

// MARK: - Private Properties

private var timerSubscription: AnyCancellable?
private var onReceive: (() -> Void)?

// MARK: - Public

func setupTimer(every interval: TimeInterval, repeats: Bool, onReceive: @escaping (() -> Void)) {
    invalidateTimer()
    self.onReceive = onReceive

    timerSubscription = Timer
        .publish(every: interval, on: .main, in: .common)
        .autoconnect()
        .sink { _ in
            onReceive()
            if !repeats {
                self.invalidateTimer()
            }
        }
}

func invalidateTimer() {
    timerSubscription?.cancel()
    onReceive = nil
}

func fire() {
    onReceive?()
}
}
  • Related