Skip to content

Commit

Permalink
HealthKit should not remove metadata datapoints (#474)
Browse files Browse the repository at this point in the history
The HealthKit integration deletes all points which do not correspond to
HealthKit entries. In the past this resulted in deleting points used for
metadata tracking, e.g. derailments or restarts. This was confusing for
support.

Resolve this by ignoring those points when syncing with HealthKit, so
they are neither updated nor deleted.

Fixes #456
  • Loading branch information
theospears authored Sep 14, 2024
1 parent df12449 commit 0f6a3ae
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 4 deletions.
4 changes: 1 addition & 3 deletions BeeKit/GoalExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,7 @@ extension Goal {
public var suggestedNextValue: NSNumber? {
let recentData = self.recentData
for dataPoint in recentData.sorted(by: { $0.updatedAt > $1.updatedAt }) {
let comment = dataPoint.comment
// Ignore data points with comments suggesting they aren't a real value
if comment.contains("#DERAIL") || comment.contains("#SELFDESTRUCT") || comment.contains("#THISWILLSELFDESTRUCT") || comment.contains("#RESTART") || comment.contains("#TARE") {
if dataPoint.isMeta() {
continue
}
return dataPoint.value
Expand Down
3 changes: 2 additions & 1 deletion BeeKit/Managers/DataPointManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,10 @@ public class DataPointManager {
guard let firstDaystamp = healthKitDataPoints.map({ point in point.daystamp }).min() else { return }

let datapoints = try await datapointsSince(goal: goal, daystamp: try! Daystamp(fromString: firstDaystamp.description))
let realDatapoints = datapoints.filter{ !$0.isMeta() }

for newDataPoint in healthKitDataPoints {
try await self.updateToMatchDataPoint(goal: goal, newDataPoint: newDataPoint, recentDatapoints: datapoints)
try await self.updateToMatchDataPoint(goal: goal, newDataPoint: newDataPoint, recentDatapoints: realDatapoints)
}
}

Expand Down
16 changes: 16 additions & 0 deletions BeeKit/Model/DataPoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,19 @@ public class DataPoint: NSManagedObject, BeeDataPoint {
}
}
}

extension DataPoint {
private static var metaPointHashtags = Set(["#DERAIL", "#SELFDESTRUCT", "#THISWILLSELFDESTRUCT", "#RESTART", "#TARE"])

/// Is this a DataPoint containing metadata, rather than a real value
/// DataPoints are used to track certain events, like automatic pessimistic values, goal restarts, derailments, etc. These should sometimes
/// be treated differently, e.g. not deleted as part of syncing with HealthKit
public func isMeta() -> Bool {
for tag in DataPoint.metaPointHashtags {
if comment.contains(tag) {
return true
}
}
return false
}
}

0 comments on commit 0f6a3ae

Please sign in to comment.