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 blog image

The Visual Studio App Center’s retiring

But sadly….you’re not. See how to make the switch to Sentry for all your crash reporting needs.

Read more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay