WIP
This commit is contained in:
@@ -43,6 +43,7 @@
|
||||
1CD0C6672A5CA19600970E52 /* BaseURLs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD0C6662A5CA19600970E52 /* BaseURLs.swift */; };
|
||||
1CD0C6682A5CA1A200970E52 /* BaseURLs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD0C6662A5CA19600970E52 /* BaseURLs.swift */; };
|
||||
1CD0C66C2A5E4EA100970E52 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1CD0C66B2A5E4EA100970E52 /* LaunchScreen.storyboard */; };
|
||||
1CEF74AB2A89937800C1AE6A /* HealthKitHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CEF74AA2A89937800C1AE6A /* HealthKitHelper.swift */; };
|
||||
1CF65A262A3972840042FFBD /* Werkout_iosApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A252A3972840042FFBD /* Werkout_iosApp.swift */; };
|
||||
1CF65A282A3972840042FFBD /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A272A3972840042FFBD /* Persistence.swift */; };
|
||||
1CF65A2B2A3972840042FFBD /* Werkout_ios.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 1CF65A292A3972840042FFBD /* Werkout_ios.xcdatamodeld */; };
|
||||
@@ -160,6 +161,7 @@
|
||||
1CD0C6622A5AF62900970E52 /* WorkoutOverviewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorkoutOverviewView.swift; sourceTree = "<group>"; };
|
||||
1CD0C6662A5CA19600970E52 /* BaseURLs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseURLs.swift; sourceTree = "<group>"; };
|
||||
1CD0C66B2A5E4EA100970E52 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
1CEF74AA2A89937800C1AE6A /* HealthKitHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthKitHelper.swift; sourceTree = "<group>"; };
|
||||
1CF65A222A3972840042FFBD /* Werkout_ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Werkout_ios.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1CF65A252A3972840042FFBD /* Werkout_iosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Werkout_iosApp.swift; sourceTree = "<group>"; };
|
||||
1CF65A272A3972840042FFBD /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = "<group>"; };
|
||||
@@ -293,6 +295,7 @@
|
||||
1CF65A292A3972840042FFBD /* Werkout_ios.xcdatamodeld */,
|
||||
1CF65A312A3972850042FFBD /* Preview Content */,
|
||||
1CF65A862A4400E10042FFBD /* ToDo */,
|
||||
1CEF74AA2A89937800C1AE6A /* HealthKitHelper.swift */,
|
||||
);
|
||||
path = Werkout_ios;
|
||||
sourceTree = "<group>";
|
||||
@@ -612,6 +615,7 @@
|
||||
1C5190CC2A589D0000885849 /* CountdownView.swift in Sources */,
|
||||
1CF65A2B2A3972840042FFBD /* Werkout_ios.xcdatamodeld in Sources */,
|
||||
1C31C8872A55B2CC00350540 /* PlayerUIView.swift in Sources */,
|
||||
1CEF74AB2A89937800C1AE6A /* HealthKitHelper.swift in Sources */,
|
||||
1CF65A2D2A3972840042FFBD /* MainView.swift in Sources */,
|
||||
1CF65A7D2A41275D0042FFBD /* Network.swift in Sources */,
|
||||
1C485C8A2A492BB400A6F896 /* LoginView.swift in Sources */,
|
||||
|
||||
@@ -50,8 +50,7 @@ class BridgeModule: NSObject, ObservableObject {
|
||||
// workoutEndDate fills out WatchPackageModel.workoutEndDate which
|
||||
// tells the watch app to stop the workout
|
||||
public private(set) var workoutEndDate: Date?
|
||||
public private(set) var totalCaloire: Float?
|
||||
public private(set) var heartRates: [Int]?
|
||||
public private(set) var healthKitUUID: UUID?
|
||||
|
||||
var audioPlayer: AVAudioPlayer?
|
||||
var avPlayer: AVPlayer?
|
||||
@@ -315,8 +314,7 @@ extension BridgeModule: WCSessionDelegate {
|
||||
playFinished()
|
||||
case .workoutComplete(let data):
|
||||
let model = try! JSONDecoder().decode(WatchFinishWorkoutModel.self, from: data)
|
||||
totalCaloire = Float(model.totalBurnedEnergery)
|
||||
heartRates = model.allHeartRates
|
||||
healthKitUUID = model.healthKitUUID
|
||||
completedWorkout?()
|
||||
case .restartExercise:
|
||||
restartExercise()
|
||||
|
||||
@@ -53,7 +53,6 @@ class CurrentWorkoutInfo {
|
||||
currentRound = 1
|
||||
|
||||
if supersetIndex >= supersets.count {
|
||||
complete?()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
126
Werkout_ios/HealthKitHelper.swift
Normal file
126
Werkout_ios/HealthKitHelper.swift
Normal file
@@ -0,0 +1,126 @@
|
||||
//
|
||||
// HealthKitHelper.swift
|
||||
// Werkout_ios
|
||||
//
|
||||
// Created by Trey Tartt on 8/13/23.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import HealthKit
|
||||
|
||||
struct HealthKitWorkoutData {
|
||||
var caloriesBurned: Double?
|
||||
var minHeartRate: Double?
|
||||
var maxHeartRate: Double?
|
||||
var avgHeartRate: Double?
|
||||
}
|
||||
|
||||
class HealthKitHelper {
|
||||
// this is dirty and i dont care
|
||||
var returnCount = 0
|
||||
let healthStore = HKHealthStore()
|
||||
|
||||
var healthKitWorkoutData = HealthKitWorkoutData(
|
||||
caloriesBurned: nil,
|
||||
minHeartRate: nil,
|
||||
maxHeartRate: nil,
|
||||
avgHeartRate: nil)
|
||||
|
||||
var completion: ((HealthKitWorkoutData) -> Void)?
|
||||
|
||||
func getDetails(forHealthKitUUID uuid: UUID, completion: @escaping ((HealthKitWorkoutData) -> Void)) {
|
||||
self.completion = completion
|
||||
self.returnCount = 0
|
||||
|
||||
print("get details \(uuid.uuidString)")
|
||||
|
||||
let predicate = HKQuery.predicateForObject(with: uuid)
|
||||
let query = HKSampleQuery(sampleType: HKWorkoutType.workoutType(),
|
||||
predicate: predicate,
|
||||
limit: 0,
|
||||
sortDescriptors: nil)
|
||||
{ (sampleQuery, results, error ) -> Void in
|
||||
|
||||
if let queryError = error {
|
||||
print( "There was an error while reading the samples: \(queryError.localizedDescription)")
|
||||
} else {
|
||||
for samples: HKSample in results! {
|
||||
let workout: HKWorkout = (samples as! HKWorkout)
|
||||
self.getTotalBurned(forWorkout: workout)
|
||||
self.getHeartRateStuff(forWorkout: workout)
|
||||
print("got workout")
|
||||
}
|
||||
}
|
||||
}
|
||||
healthStore.execute(query)
|
||||
}
|
||||
|
||||
func getHeartRateStuff(forWorkout workout: HKWorkout) {
|
||||
print("get heart")
|
||||
let heartType = HKQuantityType.quantityType(forIdentifier: .heartRate)
|
||||
let heartPredicate: NSPredicate? = HKQuery.predicateForSamples(withStart: workout.startDate,
|
||||
end: workout.endDate,
|
||||
options: HKQueryOptions.strictEndDate)
|
||||
|
||||
let heartQuery = HKStatisticsQuery(quantityType: heartType!,
|
||||
quantitySamplePredicate: heartPredicate,
|
||||
options: [.discreteAverage, .discreteMin, .discreteMax],
|
||||
completionHandler: {(query: HKStatisticsQuery, result: HKStatistics?, error: Error?) -> Void in
|
||||
if let result = result,
|
||||
let minValue = result.minimumQuantity(),
|
||||
let maxValue = result.maximumQuantity(),
|
||||
let avgValue = result.averageQuantity() {
|
||||
|
||||
let _minHeartRate = minValue.doubleValue(
|
||||
for: HKUnit(from: "count/min")
|
||||
)
|
||||
|
||||
let _maxHeartRate = maxValue.doubleValue(
|
||||
for: HKUnit(from: "count/min")
|
||||
)
|
||||
|
||||
let _avgHeartRate = avgValue.doubleValue(
|
||||
for: HKUnit(from: "count/min")
|
||||
)
|
||||
self.healthKitWorkoutData.avgHeartRate = _avgHeartRate
|
||||
self.healthKitWorkoutData.minHeartRate = _minHeartRate
|
||||
self.healthKitWorkoutData.maxHeartRate = _maxHeartRate
|
||||
print("got heart")
|
||||
DispatchQueue.main.async {
|
||||
self.shitReturned()
|
||||
}
|
||||
}
|
||||
})
|
||||
healthStore.execute(heartQuery)
|
||||
}
|
||||
|
||||
func getTotalBurned(forWorkout workout: HKWorkout) {
|
||||
print("get total burned")
|
||||
let calType = HKQuantityType.quantityType(forIdentifier: .activeEnergyBurned)
|
||||
let calPredicate: NSPredicate? = HKQuery.predicateForSamples(withStart: workout.startDate,
|
||||
end: workout.endDate,
|
||||
options: HKQueryOptions.strictEndDate)
|
||||
|
||||
let calQuery = HKStatisticsQuery(quantityType: calType!,
|
||||
quantitySamplePredicate: calPredicate,
|
||||
options: [.cumulativeSum],
|
||||
completionHandler: {(query: HKStatisticsQuery, result: HKStatistics?, error: Error?) -> Void in
|
||||
if let result = result {
|
||||
self.healthKitWorkoutData.caloriesBurned = result.sumQuantity()?.doubleValue(for: HKUnit.kilocalorie()) ?? -1
|
||||
print("got total burned")
|
||||
DispatchQueue.main.async {
|
||||
self.shitReturned()
|
||||
}
|
||||
}
|
||||
})
|
||||
healthStore.execute(calQuery)
|
||||
}
|
||||
|
||||
func shitReturned() {
|
||||
returnCount += 1
|
||||
print("\(returnCount)")
|
||||
if returnCount == 2 {
|
||||
self.completion!(healthKitWorkoutData)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ extension Postable {
|
||||
|
||||
let postData = try! JSONSerialization.data(withJSONObject:postableData)
|
||||
|
||||
var request = URLRequest(url: url,timeoutInterval: Double.infinity)
|
||||
var request = URLRequest(url: url,timeoutInterval: Double.infinity)
|
||||
if attachToken {
|
||||
guard let token = UserStore.shared.token else {
|
||||
completion(.failure(.noPostData))
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
import HealthKit
|
||||
|
||||
enum MainViewTypes: Int, CaseIterable {
|
||||
case AllWorkout = 0
|
||||
@@ -27,7 +28,7 @@ struct AllWorkoutsView: View {
|
||||
@State var isUpdating = false
|
||||
@State var workouts: [Workout]?
|
||||
@State var uniqueWorkoutUsers: [RegisteredUser]?
|
||||
|
||||
let healthStore = HKHealthStore()
|
||||
var bridgeModule = BridgeModule.shared
|
||||
@State public var needsUpdating: Bool = true
|
||||
|
||||
@@ -88,6 +89,7 @@ struct AllWorkoutsView: View {
|
||||
}
|
||||
}.onAppear{
|
||||
// UserStore.shared.logout()
|
||||
authorizeHealthKit()
|
||||
maybeUpdateShit()
|
||||
}
|
||||
.sheet(item: $selectedWorkout) { item in
|
||||
@@ -178,6 +180,21 @@ struct AllWorkoutsView: View {
|
||||
showLoginView = true
|
||||
}
|
||||
}
|
||||
|
||||
func authorizeHealthKit() {
|
||||
let healthKitTypes: Set = [
|
||||
HKObjectType.quantityType(forIdentifier: .heartRate)!,
|
||||
HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)!,
|
||||
HKObjectType.quantityType(forIdentifier: .oxygenSaturation)!,
|
||||
HKQuantityType.workoutType()
|
||||
]
|
||||
|
||||
healthStore.requestAuthorization(toShare: healthKitTypes, read: healthKitTypes) { (succ, error) in
|
||||
if !succ {
|
||||
fatalError("Error requesting authorization from health store: \(String(describing: error)))")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct AllWorkoutsView_Previews: PreviewProvider {
|
||||
|
||||
@@ -6,17 +6,23 @@
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import HealthKit
|
||||
|
||||
struct CompletedWorkoutView: View {
|
||||
@ObservedObject var bridgeModule = BridgeModule.shared
|
||||
var postData: [String: Any]
|
||||
let healthKitHelper = HealthKitHelper()
|
||||
let workout: Workout
|
||||
let healthKitUUID: UUID?
|
||||
@State var healthKitWorkoutData: HealthKitWorkoutData?
|
||||
|
||||
@Environment(\.dismiss) var dismiss
|
||||
|
||||
@State var difficulty: Float = 0
|
||||
@State var notes: String = ""
|
||||
let completedWorkoutDismissed: ((Bool) -> Void)?
|
||||
@State var isUploading: Bool = false
|
||||
@State var gettingHealthKitData: Bool = false
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
@@ -29,11 +35,40 @@ struct CompletedWorkoutView: View {
|
||||
Divider()
|
||||
|
||||
HStack {
|
||||
calsBurned()
|
||||
.frame(maxWidth: .infinity)
|
||||
|
||||
heartRates()
|
||||
.frame(maxWidth: .infinity)
|
||||
if let calsBurned = healthKitWorkoutData?.caloriesBurned {
|
||||
HStack {
|
||||
HStack {
|
||||
Image(systemName: "flame.fill")
|
||||
.foregroundColor(.orange)
|
||||
.font(.title)
|
||||
VStack {
|
||||
Text("\(calsBurned, specifier: "%.0f")")
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
|
||||
if let minHeart = healthKitWorkoutData?.minHeartRate,
|
||||
let maxHeart = healthKitWorkoutData?.maxHeartRate,
|
||||
let avgHeart = healthKitWorkoutData?.avgHeartRate {
|
||||
VStack {
|
||||
HStack {
|
||||
Image(systemName: "heart")
|
||||
.foregroundColor(.red)
|
||||
.font(.title)
|
||||
VStack {
|
||||
HStack {
|
||||
Text("\(minHeart, specifier: "%.0f")")
|
||||
Text("-")
|
||||
Text("\(maxHeart, specifier: "%.0f")")
|
||||
}
|
||||
Text("\(avgHeart, specifier: "%.0f")")
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rateWorkout()
|
||||
@@ -48,6 +83,11 @@ struct CompletedWorkoutView: View {
|
||||
.overlay(RoundedRectangle(cornerRadius: 16).stroke(Color(uiColor: .clear))).background(Color(uiColor: .init(red: 200/255, green: 200/255, blue: 200/255, alpha: 0.2)))
|
||||
.cornerRadius(8)
|
||||
|
||||
if gettingHealthKitData {
|
||||
ProgressView("Getting HealthKit data")
|
||||
.padding()
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
Button("Upload", action: {
|
||||
@@ -64,6 +104,16 @@ struct CompletedWorkoutView: View {
|
||||
}
|
||||
.padding([.leading, .trailing])
|
||||
}
|
||||
.onAppear{
|
||||
if let healthKitUUID = healthKitUUID {
|
||||
gettingHealthKitData = true
|
||||
healthKitHelper.getDetails(forHealthKitUUID: healthKitUUID,
|
||||
completion: { healthKitWorkoutData in
|
||||
self.healthKitWorkoutData = healthKitWorkoutData
|
||||
gettingHealthKitData = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func topViews() -> some View {
|
||||
@@ -83,26 +133,13 @@ struct CompletedWorkoutView: View {
|
||||
}
|
||||
}
|
||||
|
||||
func calsBurned() -> some View {
|
||||
VStack {
|
||||
if let cals = postData["total_calories"] as? Float {
|
||||
HStack {
|
||||
Image(systemName: "flame.fill")
|
||||
.foregroundColor(.orange)
|
||||
.font(.title)
|
||||
VStack {
|
||||
Text("\(cals, specifier: "%.0f")")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func rateWorkout() -> some View {
|
||||
VStack {
|
||||
Divider()
|
||||
|
||||
HStack {
|
||||
Text("No Rate")
|
||||
.foregroundColor(.black)
|
||||
Text("Easy")
|
||||
.foregroundColor(.green)
|
||||
Spacer()
|
||||
@@ -112,7 +149,7 @@ struct CompletedWorkoutView: View {
|
||||
|
||||
ZStack {
|
||||
LinearGradient(
|
||||
gradient: Gradient(colors: [.green, .red]),
|
||||
gradient: Gradient(colors: [.black, .green, .red]),
|
||||
startPoint: .leading,
|
||||
endPoint: .trailing
|
||||
)
|
||||
@@ -125,35 +162,15 @@ struct CompletedWorkoutView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func heartRates() -> some View {
|
||||
VStack {
|
||||
if let heartRates = postData["heart_rates"] as? [Int],
|
||||
heartRates.count > 0 {
|
||||
let avg = heartRates.reduce(0, +)/heartRates.count
|
||||
HStack {
|
||||
Image(systemName: "heart")
|
||||
.foregroundColor(.red)
|
||||
.font(.title)
|
||||
VStack {
|
||||
HStack {
|
||||
Text("\(heartRates.min() ?? 0)")
|
||||
Text("-")
|
||||
Text("\(heartRates.max() ?? 0)")
|
||||
}
|
||||
Text("\(avg)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func upload(postBody: [String: Any]) {
|
||||
var _postBody = postBody
|
||||
_postBody["difficulty"] = difficulty
|
||||
_postBody["notes"] = notes
|
||||
|
||||
|
||||
if let healthKitUUID = healthKitUUID {
|
||||
_postBody["health_kit_workout_uuid"] = healthKitUUID.uuidString
|
||||
}
|
||||
|
||||
CompleteWorkoutFetchable(postData: _postBody).fetch(completion: { result in
|
||||
switch result {
|
||||
case .success(_):
|
||||
@@ -163,6 +180,9 @@ struct CompletedWorkoutView: View {
|
||||
completedWorkoutDismissed?(true)
|
||||
}
|
||||
case .failure(let failure):
|
||||
DispatchQueue.main.async {
|
||||
self.isUploading = false
|
||||
}
|
||||
print(failure)
|
||||
}
|
||||
})
|
||||
@@ -184,6 +204,7 @@ struct CompletedWorkoutView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
CompletedWorkoutView(postData: CompletedWorkoutView_Previews.postBody,
|
||||
workout: workout,
|
||||
healthKitUUID: nil,
|
||||
completedWorkoutDismissed: { _ in })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +102,10 @@ struct WorkoutDetailView: View {
|
||||
.sheet(item: $presentedSheet) { item in
|
||||
switch item {
|
||||
case .completedWorkout(let data):
|
||||
CompletedWorkoutView(postData: data, workout: workout, completedWorkoutDismissed: { uploaded in
|
||||
CompletedWorkoutView(postData: data,
|
||||
workout: workout,
|
||||
healthKitUUID: bridgeModule.healthKitUUID,
|
||||
completedWorkoutDismissed: { uploaded in
|
||||
if uploaded {
|
||||
dismiss()
|
||||
}
|
||||
@@ -179,9 +182,7 @@ struct WorkoutDetailView: View {
|
||||
"workout_start_time": startTime,
|
||||
"workout_end_time": endTime,
|
||||
"workout": workoutid,
|
||||
"total_time": bridgeModule.currentWorkoutRunTimeInSeconds,
|
||||
"total_calories": bridgeModule.totalCaloire ?? -1,
|
||||
"heart_rates": bridgeModule.heartRates ?? [Int]()
|
||||
"total_time": bridgeModule.currentWorkoutRunTimeInSeconds
|
||||
] as [String : Any]
|
||||
|
||||
return postBody
|
||||
|
||||
@@ -15,6 +15,5 @@ struct WatchPackageModel: Codable {
|
||||
}
|
||||
|
||||
struct WatchFinishWorkoutModel: Codable {
|
||||
var totalBurnedEnergery: Double
|
||||
var allHeartRates: [Int]
|
||||
var healthKitUUID: UUID
|
||||
}
|
||||
|
||||
@@ -39,8 +39,9 @@ class WatchMainViewModel: NSObject, ObservableObject {
|
||||
|
||||
func autorizeHealthKit() {
|
||||
let healthKitTypes: Set = [
|
||||
HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate)!,
|
||||
HKObjectType.quantityType(forIdentifier: .heartRate)!,
|
||||
HKObjectType.quantityType(forIdentifier: .activeEnergyBurned)!,
|
||||
HKObjectType.quantityType(forIdentifier: .oxygenSaturation)!,
|
||||
HKQuantityType.workoutType()
|
||||
]
|
||||
healthStore.requestAuthorization(toShare: healthKitTypes, read: healthKitTypes) { (succ, error) in
|
||||
@@ -49,22 +50,7 @@ class WatchMainViewModel: NSObject, ObservableObject {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func startHeartRateQuery(quantityTypeIdentifier: HKQuantityTypeIdentifier) {
|
||||
let devicePredicate = HKQuery.predicateForObjects(from: [HKDevice.local()])
|
||||
let updateHandler: (HKAnchoredObjectQuery, [HKSample]?, [HKDeletedObject]?, HKQueryAnchor?, Error?) -> Void = {
|
||||
query, samples, deletedObjects, queryAnchor, error in
|
||||
guard let samples = samples as? [HKQuantitySample] else {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
let query = HKAnchoredObjectQuery(type: HKObjectType.quantityType(forIdentifier: quantityTypeIdentifier)!, predicate: devicePredicate, anchor: nil, limit: HKObjectQueryNoLimit, resultsHandler: updateHandler)
|
||||
|
||||
query.updateHandler = updateHandler
|
||||
healthStore.execute(query)
|
||||
}
|
||||
|
||||
|
||||
func nextExercise() {
|
||||
let nextExerciseAction = WatchActions.nextExercise
|
||||
let data = try! JSONEncoder().encode(nextExerciseAction)
|
||||
@@ -153,8 +139,13 @@ extension WatchMainViewModel {
|
||||
DispatchQueue.main.async() {
|
||||
self.hkWorkoutSession = nil
|
||||
self.hkBuilder = nil
|
||||
let totalEnergy = workout?.totalEnergyBurned?.doubleValue(for: .kilocalorie()) ?? -1
|
||||
let watchFinishWorkoutModel = WatchFinishWorkoutModel(totalBurnedEnergery: totalEnergy, allHeartRates: self.heartRates)
|
||||
self.heartRates.removeAll()
|
||||
self.isInWorkout = false
|
||||
|
||||
guard let id = workout?.uuid else {
|
||||
return
|
||||
}
|
||||
let watchFinishWorkoutModel = WatchFinishWorkoutModel(healthKitUUID: id)
|
||||
let data = try! JSONEncoder().encode(watchFinishWorkoutModel)
|
||||
let watchAction = WatchActions.workoutComplete(data)
|
||||
let watchActionData = try! JSONEncoder().encode(watchAction)
|
||||
@@ -162,9 +153,6 @@ extension WatchMainViewModel {
|
||||
if sendDetails {
|
||||
self.send(watchActionData)
|
||||
}
|
||||
|
||||
self.heartRates.removeAll()
|
||||
self.isInWorkout = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user