@interval-health/capacitor-health 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -351,8 +351,20 @@ final class Health {
351
351
 
352
352
  // For all other data types, use the standard query approach
353
353
  let sampleType = try dataType.sampleType()
354
+
355
+ // For sleep data, extend the query window to capture overnight sleep
356
+ // Sleep typically starts in the evening (e.g., 10 PM) but should be attributed to the next day
357
+ // So we need to fetch samples that started up to 12 hours before the requested start date
358
+ let queryStartDate: Date
359
+ if dataType == .sleep {
360
+ // Extend query 12 hours earlier to capture overnight sleep that started previous evening
361
+ queryStartDate = startDate.addingTimeInterval(-12 * 60 * 60) // -12 hours
362
+ } else {
363
+ queryStartDate = startDate
364
+ }
365
+
354
366
  // Use .strictStartDate to include samples that start within the range (even if they end after endDate)
355
- let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: .strictStartDate)
367
+ let predicate = HKQuery.predicateForSamples(withStart: queryStartDate, end: endDate, options: .strictStartDate)
356
368
  let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: ascending)
357
369
 
358
370
  // Use no limit by default to ensure all samples are retrieved
@@ -932,7 +944,10 @@ final class Health {
932
944
  ))
933
945
  }
934
946
 
935
- // Now attribute each session to the day you WOKE UP (end date)
947
+ // Attribute sleep based on 6 PM rule:
948
+ // - Sleep starting AFTER 6 PM → attribute to the NEXT day (overnight sleep)
949
+ // - Sleep starting BEFORE 6 PM → attribute to the SAME day (naps)
950
+ // This makes logical sense because evening sleep continues into the next morning
936
951
  struct DayData {
937
952
  var sessions: [SleepSession]
938
953
  var deepMinutes: Double
@@ -945,10 +960,25 @@ final class Health {
945
960
  var sleepByDate: [String: DayData] = [:]
946
961
 
947
962
  for session in sessions {
948
- // Wake-up date (local)
949
963
  let calendar = Calendar.current
950
- let wakeDate = calendar.dateComponents([.year, .month, .day], from: session.end)
951
- let dateString = String(format: "%04d-%02d-%02d", wakeDate.year!, wakeDate.month!, wakeDate.day!)
964
+
965
+ // Get the hour when sleep started
966
+ let startHour = calendar.component(.hour, from: session.start)
967
+
968
+ // Determine which date this sleep belongs to:
969
+ // If sleep starts at or after 6 PM (18:00), it belongs to the NEXT day
970
+ // If sleep starts before 6 PM, it belongs to the SAME day (e.g., naps)
971
+ let attributionDate: Date
972
+ if startHour >= 18 {
973
+ // Sleep started at/after 6 PM - attribute to next day
974
+ attributionDate = calendar.date(byAdding: .day, value: 1, to: session.start)!
975
+ } else {
976
+ // Sleep started before 6 PM (nap or early morning) - attribute to same day
977
+ attributionDate = session.start
978
+ }
979
+
980
+ let dateComponents = calendar.dateComponents([.year, .month, .day], from: attributionDate)
981
+ let dateString = String(format: "%04d-%02d-%02d", dateComponents.year!, dateComponents.month!, dateComponents.day!)
952
982
 
953
983
  // Initialize day data if needed
954
984
  if sleepByDate[dateString] == nil {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@interval-health/capacitor-health",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Capacitor plugin to interact with data from Apple HealthKit and Health Connect",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",