DEV Community

Avelyn Hyunjeong Choi
Avelyn Hyunjeong Choi

Posted on

TimerApp with watchOS in Swift

In this blog, I will be implementing TimerApp with Combine.

ContentView

import SwiftUI
import Combine

struct ContentView: View {
    @State private var timerDuration: TimeInterval = 60
    @State private var timerActive = false
    @State private var timeRemaining: TimeInterval = 60
    @State private var timerCancellable: AnyCancellable? // subscriber

    // publish event in every second as a publisher
    let timer = Timer.publish(every: 1, on: .main, in: .common)

    var body: some View {
        VStack {
            Text("Timer \(timeString(time:timeRemaining))")
                .font(.title2)

            if(timerActive) {
                Button("Stop Timer") {
                    self.timerActive = false
                    self.timerCancellable?.cancel()
                }
            } else {
                Button("Start Timer") {
                    self.timerCancellable?.cancel()  // cancel any existing timer before start the timer
                    self.timeRemaining = self.timerDuration
                    self.timerActive = true
                    // subscribe to publisher, timer
                    self.timerCancellable = timer.autoconnect().sink { _ in
                        // whenver event is triggered (every second), this callback is called
                        self.updateTimer()
                    }
                }
            }

            // giver users options (1, 5, 10 minutes) using Picker View
            Picker("Duration", selection: $timerDuration) {
                Text("1 Minute").tag(TimeInterval(60))
                Text("5 Minute").tag(TimeInterval(300))
                Text("10 Minute").tag(TimeInterval(600))
            }
        }
        .onDisappear {
            self.timerCancellable?.cancel()
        }
    }

    private func timeString(time: TimeInterval) -> String {
        let intTime = Int(time)
        let minutes = intTime / 60
        let seconds = intTime % 60

        return String(format: "%02i:%02i", minutes, seconds)
    }

    private func updateTimer() {
        if(timerActive && timeRemaining > 0) {
            timeRemaining -= 1
        } else {
            timerActive = false
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Demo

Image description

Sentry mobile image

Is your mobile app slow? Improve performance with these key strategies.

Improve performance with key strategies like TTID/TTFD & app start analysis.

Read the blog post

Top comments (0)

Sentry mobile image

Improving mobile performance, from slow screens to app start time

Based on our experience working with thousands of mobile developer teams, we developed a mobile monitoring maturity curve.

Read more