mirror of
https://github.com/cagnulein/qdomyos-zwift.git
synced 2026-02-18 00:17:41 +01:00
Compare commits
2 Commits
Computrain
...
build-1168
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a3b211edf | ||
|
|
4b3ea5a1d0 |
@@ -4455,7 +4455,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1167;
|
||||
CURRENT_PROJECT_VERSION = 1168;
|
||||
DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES;
|
||||
DEVELOPMENT_TEAM = 6335M7T29D;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -4655,7 +4655,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1167;
|
||||
CURRENT_PROJECT_VERSION = 1168;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER = YES;
|
||||
DEVELOPMENT_TEAM = 6335M7T29D;
|
||||
@@ -4891,7 +4891,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1167;
|
||||
CURRENT_PROJECT_VERSION = 1168;
|
||||
DEVELOPMENT_TEAM = 6335M7T29D;
|
||||
ENABLE_BITCODE = YES;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
@@ -4987,7 +4987,7 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1167;
|
||||
CURRENT_PROJECT_VERSION = 1168;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = 6335M7T29D;
|
||||
ENABLE_BITCODE = YES;
|
||||
@@ -5079,7 +5079,7 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1167;
|
||||
CURRENT_PROJECT_VERSION = 1168;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\"";
|
||||
ENABLE_BITCODE = YES;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
@@ -5195,7 +5195,7 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1167;
|
||||
CURRENT_PROJECT_VERSION = 1168;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\"";
|
||||
ENABLE_BITCODE = YES;
|
||||
|
||||
@@ -29,20 +29,24 @@ protocol WorkoutTrackingProtocol {
|
||||
@objc class WorkoutTracking: NSObject {
|
||||
static let shared = WorkoutTracking()
|
||||
public static var lastDateMetric = Date()
|
||||
public static var distance = Double()
|
||||
public static var kcal = Double()
|
||||
public static var totalKcal = Double()
|
||||
public static var steps = Double()
|
||||
var sport: Int = 0
|
||||
let healthStore = HKHealthStore()
|
||||
let configuration = HKWorkoutConfiguration()
|
||||
var workoutBuilder: HKWorkoutBuilder!
|
||||
var workoutInProgress: Bool = false
|
||||
|
||||
weak var delegate: WorkoutTrackingDelegate?
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
public static var distance = Double()
|
||||
public static var kcal = Double()
|
||||
public static var totalKcal = Double()
|
||||
public static var steps = Double()
|
||||
var sport: Int = 0
|
||||
let healthStore = HKHealthStore()
|
||||
let configuration = HKWorkoutConfiguration()
|
||||
var workoutBuilder: HKWorkoutBuilder!
|
||||
var workoutInProgress: Bool = false
|
||||
private var heartRateQuery: HKAnchoredObjectQuery?
|
||||
private var heartRateQueryAnchor: HKQueryAnchor?
|
||||
private let heartRateUnit = HKUnit.count().unitDivided(by: HKUnit.minute())
|
||||
private let heartRateType = HKQuantityType.quantityType(forIdentifier: .heartRate)
|
||||
|
||||
weak var delegate: WorkoutTrackingDelegate?
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,12 +56,12 @@ extension WorkoutTracking {
|
||||
self.sport = sport
|
||||
}
|
||||
|
||||
private func configWorkout() {
|
||||
var activityType = HKWorkoutActivityType.cycling
|
||||
if self.sport == 1 {
|
||||
activityType = HKWorkoutActivityType.running
|
||||
} else if self.sport == 2 {
|
||||
activityType = HKWorkoutActivityType.cycling
|
||||
private func configWorkout() {
|
||||
var activityType = HKWorkoutActivityType.cycling
|
||||
if self.sport == 1 {
|
||||
activityType = HKWorkoutActivityType.running
|
||||
} else if self.sport == 2 {
|
||||
activityType = HKWorkoutActivityType.cycling
|
||||
} else if self.sport == 3 {
|
||||
activityType = HKWorkoutActivityType.rowing
|
||||
} else if self.sport == 4 {
|
||||
@@ -67,16 +71,71 @@ extension WorkoutTracking {
|
||||
configuration.activityType = activityType
|
||||
configuration.locationType = .indoor
|
||||
|
||||
do {
|
||||
workoutBuilder = try HKWorkoutBuilder(healthStore: healthStore, configuration: configuration, device: .local())
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 17.0, *)
|
||||
extension WorkoutTracking: WorkoutTrackingProtocol {
|
||||
do {
|
||||
workoutBuilder = try HKWorkoutBuilder(healthStore: healthStore, configuration: configuration, device: .local())
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
private func startHeartRateStreamingQuery() {
|
||||
guard heartRateQuery == nil else { return }
|
||||
guard HKHealthStore.isHealthDataAvailable() else {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: Health data unavailable for heart rate query")
|
||||
return
|
||||
}
|
||||
guard let heartRateType = heartRateType else {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: Heart rate type unavailable")
|
||||
return
|
||||
}
|
||||
|
||||
let predicate = HKQuery.predicateForSamples(withStart: Date(), end: nil, options: .strictStartDate)
|
||||
let query = HKAnchoredObjectQuery(type: heartRateType, predicate: predicate, anchor: heartRateQueryAnchor, limit: HKObjectQueryNoLimit) { [weak self] _, samples, _, newAnchor, error in
|
||||
self?.handleHeartRateSamples(samples, error: error)
|
||||
self?.heartRateQueryAnchor = newAnchor
|
||||
}
|
||||
|
||||
query.updateHandler = { [weak self] _, samples, _, newAnchor, error in
|
||||
self?.handleHeartRateSamples(samples, error: error)
|
||||
self?.heartRateQueryAnchor = newAnchor
|
||||
}
|
||||
|
||||
heartRateQuery = query
|
||||
healthStore.execute(query)
|
||||
}
|
||||
|
||||
private func stopHeartRateStreamingQuery() {
|
||||
if let query = heartRateQuery {
|
||||
healthStore.stop(query)
|
||||
}
|
||||
heartRateQuery = nil
|
||||
heartRateQueryAnchor = nil
|
||||
}
|
||||
|
||||
private func handleHeartRateSamples(_ samples: [HKSample]?, error: Error?) {
|
||||
if let error = error {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: Heart rate query error " + error.localizedDescription)
|
||||
return
|
||||
}
|
||||
|
||||
guard
|
||||
let quantitySamples = samples as? [HKQuantitySample],
|
||||
let latestSample = quantitySamples.last
|
||||
else {
|
||||
return
|
||||
}
|
||||
|
||||
let bpm = latestSample.quantity.doubleValue(for: heartRateUnit)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
WatchKitConnection.currentHeartRate = Int(round(bpm))
|
||||
self.delegate?.didReceiveHealthKitHeartRate(bpm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 17.0, *)
|
||||
extension WorkoutTracking: WorkoutTrackingProtocol {
|
||||
|
||||
@objc static func requestAuth() {
|
||||
authorizeHealthKit()
|
||||
@@ -141,31 +200,34 @@ extension WorkoutTracking: WorkoutTrackingProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
@objc func startWorkOut(deviceType: UInt16) {
|
||||
if(workoutInProgress) {
|
||||
return;
|
||||
@objc func startWorkOut(deviceType: UInt16) {
|
||||
if(workoutInProgress) {
|
||||
return;
|
||||
}
|
||||
WorkoutTracking.authorizeHealthKit()
|
||||
workoutInProgress = true;
|
||||
WorkoutTracking.lastDateMetric = Date()
|
||||
SwiftDebug.qtDebug("WorkoutTracking: Start workout")
|
||||
setSport(Int(deviceType))
|
||||
configWorkout()
|
||||
startHeartRateStreamingQuery()
|
||||
workoutBuilder.beginCollection(withStart: Date()) { (success, error) in
|
||||
SwiftDebug.qtDebug(success.description)
|
||||
if let error = error {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: " + error.localizedDescription)
|
||||
}
|
||||
}
|
||||
WorkoutTracking.authorizeHealthKit()
|
||||
workoutInProgress = true;
|
||||
WorkoutTracking.lastDateMetric = Date()
|
||||
SwiftDebug.qtDebug("WorkoutTracking: Start workout")
|
||||
setSport(Int(deviceType))
|
||||
configWorkout()
|
||||
workoutBuilder.beginCollection(withStart: Date()) { (success, error) in
|
||||
SwiftDebug.qtDebug(success.description)
|
||||
if let error = error {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: " + error.localizedDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc func stopWorkOut() {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: Stop workout")
|
||||
|
||||
guard let workoutBuilder = self.workoutBuilder,
|
||||
let startDate = workoutBuilder.startDate else {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: Cannot stop workout - no workout builder or start date available")
|
||||
workoutInProgress = false
|
||||
}
|
||||
|
||||
@objc func stopWorkOut() {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: Stop workout")
|
||||
|
||||
stopHeartRateStreamingQuery()
|
||||
|
||||
guard let workoutBuilder = self.workoutBuilder,
|
||||
let startDate = workoutBuilder.startDate else {
|
||||
SwiftDebug.qtDebug("WorkoutTracking: Cannot stop workout - no workout builder or start date available")
|
||||
workoutInProgress = false
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user