Search code examples
swiftcombine

Combine Timer.TimerPublisher not starting


I'm creating a login token validity timer, and I figured it needs to be a singleton that ticks and every second (or every minute or whatever), checks to see whether the login token is still valid.

But I can't even get the singleton to print a message every second. Why not?

import SwiftUI
import Combine

class TokenObserver: ObservableObject {
    private let publisher = Timer.TimerPublisher(interval: 1.0, runLoop: .main, mode: .default)
    private let cancellable: AnyCancellable?
    static let instance = TokenObserver()
    let uuid = UUID()

    private init() {
        NSLog("TokenObserver.init()")
        self.cancellable = self.publisher.sink(receiveCompletion: { completion in
            NSLog("TokenObserver \(completion)")
        }, receiveValue: { date in
            NSLog("TokenObserver timestamp=" + ISO8601DateFormatter().string(from: date))
        })
    }

    deinit {
        NSLog("TokenObserver.deinit()")
        self.cancellable?.cancel()
    }
}

struct ContentView: View {
    var body: some View {
        Text("Hello, world! Instance = " + TokenObserver.instance.uuid.uuidString)
            .padding()
    }
}

Solution

  • You have to call autoconnect() on the Timer publisher to fire it.

    private init() {
        NSLog("TokenObserver.init()")
        self.cancellable = self.publisher.autoconnect().sink(receiveCompletion: { completion in
           NSLog("TokenObserver \(completion)")
       }, receiveValue: { date in
            NSLog("TokenObserver timestamp=" + ISO8601DateFormatter().string(from: date))
        })
    }