-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
also toothbrushing in sessions per day
- Loading branch information
Showing
5 changed files
with
122 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
BeeKit/HeathKit/Toothbrushing/ToothbrushingHealthKitMetric.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import Foundation | ||
import HealthKit | ||
|
||
/// tracks toothbrushing, in number of seconds per day (daystamp) | ||
class ToothbrushingHealthKitMetric: CategoryHealthKitMetric { | ||
private static let healthkitMetric = ["toothbrushing", "seconds-per-day"].joined(separator: "|") | ||
|
||
private init(humanText: String, | ||
databaseString: String, | ||
category: HealthKitCategory) { | ||
super.init(humanText: humanText, | ||
databaseString: databaseString, | ||
category: category, | ||
hkSampleType: HKObjectType.categoryType(forIdentifier: .toothbrushingEvent)!) | ||
} | ||
|
||
override func units(healthStore : HKHealthStore) async throws -> HKUnit { | ||
HKUnit.second() | ||
} | ||
|
||
static func make() -> ToothbrushingHealthKitMetric { | ||
.init(humanText: "Teethbrushing (in seconds per day)", | ||
databaseString: healthkitMetric, | ||
category: HealthKitCategory.SelfCare) | ||
} | ||
|
||
override func recentDataPoints(days: Int, deadline: Int, healthStore: HKHealthStore) async throws -> [any BeeDataPoint] { | ||
try await super.recentDataPoints(days: days, deadline: deadline, healthStore: healthStore) | ||
.map { | ||
NewDataPoint(requestid: $0.requestid, | ||
daystamp: $0.daystamp, | ||
value: $0.value, | ||
comment: "Auto-entered via Apple Health (\(Self.healthkitMetric))") | ||
} | ||
} | ||
} |
72 changes: 72 additions & 0 deletions
72
BeeKit/HeathKit/Toothbrushing/ToothbrushingSessionsHealthKitMetric.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// Part of BeeSwift. Copyright Beeminder | ||
|
||
/// tracks toothbrushing, in number of sessions per day (daystamp) | ||
class ToothbrushingSessionsHealthKitMetric: CategoryHealthKitMetric { | ||
private static let healthkitMetric = ["toothbrushing", "sessions-per-day"].joined(separator: "|") | ||
|
||
private init(humanText: String, | ||
databaseString: String, | ||
category: HealthKitCategory) { | ||
super.init(humanText: humanText, | ||
databaseString: databaseString, | ||
category: category, | ||
hkSampleType: HKObjectType.categoryType(forIdentifier: .toothbrushingEvent)!) | ||
} | ||
|
||
override func units(healthStore : HKHealthStore) async throws -> HKUnit { | ||
.count() | ||
} | ||
|
||
static func make() -> ToothbrushingSessionsHealthKitMetric { | ||
.init(humanText: "Teethbrushing (in sessions per day)", | ||
databaseString: healthkitMetric, | ||
category: HealthKitCategory.SelfCare) | ||
} | ||
|
||
override func recentDataPoints(days: Int, deadline: Int, healthStore: HKHealthStore) async throws -> [any BeeDataPoint] { | ||
let todayDaystamp = Daystamp.now(deadline: deadline) | ||
let startDaystamp = todayDaystamp - days | ||
|
||
let predicate = HKQuery.predicateForSamples(withStart: startDaystamp.start(deadline: deadline), | ||
end: todayDaystamp.end(deadline: deadline)) | ||
|
||
let samples = try await withCheckedThrowingContinuation({ (continuation: CheckedContinuation<[HKSample], Error>) in | ||
let query = HKSampleQuery(sampleType: sampleType(), | ||
predicate: predicate, | ||
limit: HKObjectQueryNoLimit, | ||
sortDescriptors: [NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: true)], | ||
resultsHandler: { (query, samples, error) in | ||
if let error { | ||
continuation.resume(throwing: error) | ||
} else if let samples { | ||
continuation.resume(returning: samples) | ||
} else { | ||
continuation.resume(throwing: HealthKitError("HKSampleQuery did not return samples")) | ||
} | ||
}) | ||
healthStore.execute(query) | ||
}) | ||
.compactMap { $0 as? HKCategorySample } | ||
|
||
let calendar = Calendar.autoupdatingCurrent | ||
let groupedByDay = Dictionary(grouping: samples, by: { sample in | ||
calendar.startOfDay(for: sample.startDate) | ||
}) | ||
|
||
let dailyCounts = groupedByDay | ||
.map { ($0, $1.count) } | ||
.sorted { $0.0 < $1.0 } | ||
|
||
let datapoints = dailyCounts.map({ (date, numberOfEntries) in | ||
let daystamp = Daystamp(fromDate: date, deadline: deadline) | ||
let requestID = "apple-heath-" + daystamp.description | ||
|
||
return NewDataPoint(requestid: requestID, | ||
daystamp: daystamp, | ||
value: NSNumber(value: numberOfEntries), | ||
comment: "Auto-entered via Apple Health (\(Self.healthkitMetric))") | ||
}) | ||
|
||
return datapoints | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters