Files
WerkoutIOS/Werkout_ios/BridgeModule.swift
Trey t 48f23f8e77 WIP
2023-06-23 13:34:29 -05:00

184 lines
5.4 KiB
Swift

//
// TimerModule.swift
// Werkout_ios
//
// Created by Trey Tartt on 6/14/23.
//
import Foundation
import WatchConnectivity
enum WatchActions: String, Codable {
case nextExercise
}
class BridgeModule: NSObject, ObservableObject {
private let kMessageKey = "message"
static let shared = BridgeModule()
@Published var isShowingOnExternalDisplay = false
private var timer: Timer?
@Published var timeLeft: Int = 0
@Published var currentExercise: ExerciseElement?
var currentWorkout: Workout?
var currentExerciseIdx: Int = -1
var workoutStartDate: Date?
var workoutEndDate: Date?
@Published var currentWorkoutRunTimeInSeconds: Int = -1
private var currentWorkoutRunTimer: Timer?
@Published var isInWorkout = false
func start(workout: Workout, atExerciseIndex: Int = 0) {
self.currentWorkout = workout
currentWorkoutRunTimeInSeconds = 0
currentWorkoutRunTimer?.invalidate()
currentWorkoutRunTimer = nil
currentExerciseIdx = 0
let exercise = workout.exercises[currentExerciseIdx]
updateCurrent(exercise: exercise)
startWorkoutTimer()
workoutStartDate = Date()
isInWorkout = true
if WCSession.isSupported() {
WCSession.default.delegate = self
WCSession.default.activate()
}
}
func resetCurrentWorkout() {
currentWorkoutRunTimeInSeconds = 0
currentWorkoutRunTimer?.invalidate()
currentWorkoutRunTimer = nil
currentWorkoutRunTimer?.invalidate()
currentWorkoutRunTimer = nil
currentWorkoutRunTimeInSeconds = -1
currentExerciseIdx = -1
currentExercise = nil
currentWorkout = nil
if isInWorkout {
let watchModel = WatchPackageModel(currentExerciseName: currentExercise?.exercise.name ?? "-", currentTimeLeft: timeLeft, workoutStartDate: workoutStartDate ?? Date(), workoutEndDate: Date())
let data = try! JSONEncoder().encode(watchModel)
send(data)
}
isInWorkout = false
workoutStartDate = nil
workoutEndDate = nil
}
private func startWorkoutTimer() {
currentWorkoutRunTimer?.invalidate()
currentWorkoutRunTimer = nil
currentWorkoutRunTimer = Timer.scheduledTimer(timeInterval: 1,
target: self,
selector: #selector(addOneToWorkoutRunTime),
userInfo: nil,
repeats: true)
currentWorkoutRunTimer?.fire()
}
private func startTimerWith(duration: Int) {
timer?.invalidate()
timer = nil
timeLeft = duration
timer = Timer.scheduledTimer(timeInterval: 1,
target: self,
selector: #selector(updateCounter),
userInfo: nil,
repeats: true)
timer?.fire()
}
@objc func updateCounter() {
if timeLeft > 0 {
timeLeft -= 1
let watchModel = WatchPackageModel(currentExerciseName: currentExercise?.exercise.name ?? "-", currentTimeLeft: timeLeft, workoutStartDate: workoutStartDate ?? Date())
let data = try! JSONEncoder().encode(watchModel)
send(data)
} else {
timer?.invalidate()
timer = nil
nextExercise()
}
}
func nextExercise() {
currentExerciseIdx += 1
if let currentWorkout = currentWorkout {
if currentExerciseIdx < currentWorkout.exercises.count {
let nextExercise = currentWorkout.exercises[currentExerciseIdx]
updateCurrent(exercise: nextExercise)
} else {
}
}
}
@objc func addOneToWorkoutRunTime() {
currentWorkoutRunTimeInSeconds += 1
}
func updateCurrent(exercise: ExerciseElement) {
self.currentExercise = exercise
if let duration = exercise.duration {
startTimerWith(duration: duration)
}
}
}
extension BridgeModule: WCSessionDelegate {
func session(_ session: WCSession, didReceiveMessageData messageData: Data) {
if let model = try? JSONDecoder().decode(WatchActions.self, from: messageData) {
switch model {
case .nextExercise:
nextExercise()
}
}
}
func session(_ session: WCSession,
activationDidCompleteWith activationState: WCSessionActivationState,
error: Error?) {}
#if os(iOS)
func sessionDidBecomeInactive(_ session: WCSession) {}
func sessionDidDeactivate(_ session: WCSession) {
session.activate()
}
#endif
func send(_ data: Data) {
guard WCSession.default.activationState == .activated else {
return
}
#if os(iOS)
guard WCSession.default.isWatchAppInstalled else {
return
}
#else
guard WCSession.default.isCompanionAppInstalled else {
return
}
#endif
WCSession.default.sendMessageData(data, replyHandler: nil)
{ error in
print("Cannot send message: \(String(describing: error))")
}
}
}