misc watch stuff including taps, sounds, maybe working

This commit is contained in:
Trey t
2024-06-21 14:34:23 -05:00
parent 7ce996e451
commit cee84d7776
9 changed files with 61 additions and 36 deletions

View File

@@ -6,12 +6,16 @@
//
import AVKit
import AVFoundation
class AudioEngine {
// var audioPlayer: AVAudioPlayer?
// var avPlayer: AVPlayer?
static let shared = AudioEngine()
private init() { }
static func playRemoteAudio(fromURL url: URL) {
var audioPlayer: AVAudioPlayer?
var avPlayer: AVPlayer?
func playRemoteAudio(fromURL url: URL) {
#if os(iOS)
let playerItem = AVPlayerItem(url: url)
do {
@@ -20,15 +24,15 @@ class AudioEngine {
options: [.mixWithOthers])
try AVAudioSession.sharedInstance().setActive(true)
let avPlayer = AVPlayer(playerItem: playerItem)
avPlayer.play()
avPlayer = AVPlayer(playerItem: playerItem)
avPlayer?.play()
} catch {
print("ERROR")
}
#endif
}
static func playBeep() {
func playBeep() {
#if os(iOS)
if let path = Bundle.main.path(forResource: "short_beep", ofType: "m4a") {
do {
@@ -37,8 +41,8 @@ class AudioEngine {
options: [.mixWithOthers])
try AVAudioSession.sharedInstance().setActive(true)
let audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
audioPlayer.play()
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
audioPlayer?.play()
} catch {
print("ERROR")
}
@@ -46,7 +50,7 @@ class AudioEngine {
#endif
}
static func playFinished() {
func playFinished() {
#if os(iOS)
if let path = Bundle.main.path(forResource: "long_beep", ofType: "m4a") {
do {
@@ -55,8 +59,8 @@ class AudioEngine {
options: [.mixWithOthers])
try AVAudioSession.sharedInstance().setActive(true)
let audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
audioPlayer.play()
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
audioPlayer?.play()
} catch {
print("ERROR")
}

View File

@@ -42,11 +42,11 @@ extension BridgeModule {
switch audioQueue.audioType {
case .shortBeep:
AudioEngine.playBeep()
AudioEngine.shared.playBeep()
case .finishBeep:
AudioEngine.playFinished()
AudioEngine.shared.playFinished()
case .remoteURL(let url):
AudioEngine.playRemoteAudio(fromURL: url)
AudioEngine.shared.playRemoteAudio(fromURL: url)
}
}
}

View File

@@ -14,28 +14,22 @@ extension BridgeModule: WCSessionDelegate {
func sendResetToWatch() {
let watchModel = PhoneToWatchActions.reset
let data = try! JSONEncoder().encode(watchModel)
// user transferUserInfo b/c its guranteed to reach
// and end the workout
self.session.transferUserInfo(["package": data])
send(data)
// self.session.transferUserInfo(["package": data])
}
func sendStartWorkoutToWatch() {
let model = PhoneToWatchActions.startWorkout
let data = try! JSONEncoder().encode(model)
// user transferUserInfo b/c its guranteed to reach
// and start the workout
self.session.transferUserInfo(["package": data])
send(data)
// self.session.transferUserInfo(["package": data])
}
func sendWorkoutCompleteToWatch() {
let model = PhoneToWatchActions.endWorkout
let data = try! JSONEncoder().encode(model)
// user transferUserInfo b/c its guranteed to reach
// and end the workout
self.session.transferUserInfo(["package": data])
send(data)
// self.session.transferUserInfo(["package": data])
}
func sendCurrentExerciseToWatch() {
@@ -43,6 +37,7 @@ extension BridgeModule: WCSessionDelegate {
let duration = currentExercise.duration ,
duration > 0 {
let watchModel = WatchPackageModel(currentExerciseName: currentExercise.exercise.name,
currentExerciseID: currentExercise.id ?? -1,
currentTimeLeft: currentExerciseTimeLeft,
workoutStartDate: workoutStartDate ?? Date())
let model = PhoneToWatchActions.inExercise(watchModel)
@@ -55,7 +50,7 @@ extension BridgeModule: WCSessionDelegate {
// if not a timer we need to set the watch display with number of reps
// if timer it will set when timer updates
let watchModel = WatchPackageModel(currentExerciseName: currentExercise.exercise.name, currentTimeLeft: reps, workoutStartDate: self.workoutStartDate ?? Date())
let watchModel = WatchPackageModel(currentExerciseName: currentExercise.exercise.name, currentExerciseID: currentExercise.id ?? -1, currentTimeLeft: reps, workoutStartDate: self.workoutStartDate ?? Date())
let model = PhoneToWatchActions.inExercise(watchModel)
let data = try! JSONEncoder().encode(model)
self.send(data)
@@ -68,7 +63,7 @@ extension BridgeModule: WCSessionDelegate {
switch model {
case .nextExercise:
nextExercise()
AudioEngine.playFinished()
AudioEngine.shared.playFinished()
case .workoutComplete(let data):
DispatchQueue.main.async {
let model = try! JSONDecoder().decode(WatchFinishWorkoutModel.self, from: data)

View File

@@ -77,8 +77,6 @@ extension BridgeModule {
currentWorkoutRunTimer = nil
isPaused = false
sendStartWorkoutToWatch()
if let superetExercise = currentExerciseInfo.currentExercise {
updateCurrent(exercise: superetExercise)
startWorkoutTimer()
@@ -88,6 +86,7 @@ extension BridgeModule {
if WCSession.isSupported() {
session.delegate = self
session.activate()
sendStartWorkoutToWatch()
}
}
}

View File

@@ -9,6 +9,7 @@ import Foundation
struct WatchPackageModel: Codable {
var currentExerciseName: String
var currentExerciseID: Int
var currentTimeLeft: Int
var workoutStartDate: Date
var workoutEndDate: Date?

View File

@@ -57,6 +57,7 @@ struct ActionsView: View {
.foregroundColor(.white)
} else {
Button(action: {
AudioEngine.shared.playFinished()
nextExercise()
}, label: {
Image(systemName: "arrow.forward")
@@ -68,6 +69,7 @@ struct ActionsView: View {
.foregroundColor(.white)
Button(action: {
AudioEngine.shared.playFinished()
bridgeModule.pauseWorkout()
}, label: {
bridgeModule.isPaused ?
@@ -84,6 +86,7 @@ struct ActionsView: View {
.foregroundColor(.white)
Button(action: {
AudioEngine.shared.playFinished()
completedWorkout?()
}, label: {
Image(systemName: "checkmark")

View File

@@ -44,9 +44,15 @@ struct WatchControlView: View {
Button(action: {
vm.pauseWorkout()
}, label: {
Image(systemName: "pause")
.font(.title)
.frame(maxWidth: .infinity, maxHeight: .infinity)
if vm.isPaused {
Image(systemName: "play")
.font(.title)
.frame(maxWidth: .infinity, maxHeight: .infinity)
} else {
Image(systemName: "pause")
.font(.title)
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
})
.buttonStyle(BorderedButtonStyle(tint: .blue))

View File

@@ -51,6 +51,8 @@ extension WatchMainViewModel {
}
}
isInWorkout = true
isPaused = false
WKInterfaceDevice.current().play(.start)
} else {
print("did not init workout")
}
@@ -69,6 +71,7 @@ extension WatchMainViewModel {
self.hkBuilder = nil
self.heartRates.removeAll()
self.isInWorkout = false
self.isPaused = false
guard let id = workout?.uuid else {
return

View File

@@ -20,13 +20,14 @@ class WatchMainViewModel: NSObject, ObservableObject {
@Published var heartValue: Int?
static var defualtPackageModle: WatchPackageModel {
WatchPackageModel(currentExerciseName: "", currentTimeLeft: -1, workoutStartDate: Date())
WatchPackageModel(currentExerciseName: "", currentExerciseID: -1, currentTimeLeft: -1, workoutStartDate: Date())
}
let healthStore = HKHealthStore()
var hkWorkoutSession: HKWorkoutSession?
var hkBuilder: HKLiveWorkoutBuilder?
var heartRates = [Int]()
@Published var isPaused = false
override init() {
session = WCSession.default
@@ -56,38 +57,51 @@ class WatchMainViewModel: NSObject, ObservableObject {
let nextExerciseAction = WatchActions.nextExercise
let data = try! JSONEncoder().encode(nextExerciseAction)
send(data)
WKInterfaceDevice.current().play(.start)
}
func restartExercise() {
let nextExerciseAction = WatchActions.restartExercise
let data = try! JSONEncoder().encode(nextExerciseAction)
send(data)
WKInterfaceDevice.current().play(.start)
}
func previousExercise() {
let nextExerciseAction = WatchActions.previousExercise
let data = try! JSONEncoder().encode(nextExerciseAction)
send(data)
WKInterfaceDevice.current().play(.start)
}
func completeWorkout() {
let nextExerciseAction = WatchActions.stopWorkout
let data = try! JSONEncoder().encode(nextExerciseAction)
send(data)
WKInterfaceDevice.current().play(.start)
}
func pauseWorkout() {
let nextExerciseAction = WatchActions.pauseWorkout
let data = try! JSONEncoder().encode(nextExerciseAction)
send(data)
isPaused = !isPaused
WKInterfaceDevice.current().play(.start)
}
func dataToAction(messageData: Data) {
if let model = try? JSONDecoder().decode(PhoneToWatchActions.self, from: messageData) {
DispatchQueue.main.async {
switch model {
case .inExercise(let data):
self.watchPackageModel = data
case .inExercise(let newWatchPackageModel):
if !self.isInWorkout {
self.startWorkout()
}
if self.watchPackageModel.currentExerciseID != newWatchPackageModel.currentExerciseID {
self.isPaused = false
WKInterfaceDevice.current().play(.start)
}
self.watchPackageModel = newWatchPackageModel
case .reset:
self.isInWorkout = false
self.watchPackageModel = WatchMainViewModel.defualtPackageModle