Skip to content

Commit

Permalink
[LOOP-5153] Remove HealthKit dependency from LoopAlgorithm (#726)
Browse files Browse the repository at this point in the history
  • Loading branch information
Camji55 authored Dec 4, 2024
1 parent 7c90bdd commit b723d23
Show file tree
Hide file tree
Showing 112 changed files with 436 additions and 515 deletions.
10 changes: 5 additions & 5 deletions Common/Extensions/GlucoseRangeSchedule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
//

import LoopKit
import HealthKit
import LoopAlgorithm


extension GlucoseRangeSchedule {
func minQuantity(at date: Date) -> HKQuantity {
return HKQuantity(unit: unit, doubleValue: value(at: date).minValue)
func minQuantity(at date: Date) -> LoopQuantity {
return LoopQuantity(unit: unit, doubleValue: value(at: date).minValue)
}
func maxQuantity(at date: Date) -> HKQuantity {
return HKQuantity(unit: unit, doubleValue: value(at: date).maxValue)
func maxQuantity(at date: Date) -> LoopQuantity {
return LoopQuantity(unit: unit, doubleValue: value(at: date).maxValue)
}
}
18 changes: 2 additions & 16 deletions Common/Extensions/HKUnit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
// Copyright © 2016 LoopKit Authors. All rights reserved.
//

import HealthKit
import LoopAlgorithm
import LoopCore

// Code in this extension is duplicated from:
// https://github.com/LoopKit/LoopKit/blob/master/LoopKit/HKUnit.swift
// to avoid pulling in the LoopKit extension since it's not extension-API safe.
extension HKUnit {
extension LoopUnit {
// A formatting helper for determining the preferred decimal style for a given unit
var preferredFractionDigits: Int {
if self == .milligramsPerDeciliter {
Expand All @@ -22,20 +22,6 @@ extension HKUnit {
}
}

var localizedShortUnitString: String {
if self == HKUnit.millimolesPerLiter {
return NSLocalizedString("mmol/L", comment: "The short unit display string for millimoles of glucose per liter")
} else if self == .milligramsPerDeciliter {
return NSLocalizedString("mg/dL", comment: "The short unit display string for milligrams of glucose per decilter")
} else if self == .internationalUnit() {
return NSLocalizedString("U", comment: "The short unit display string for international units of insulin")
} else if self == .gram() {
return NSLocalizedString("g", comment: "The short unit display string for grams")
} else {
return String(describing: self)
}
}

/// The smallest value expected to be visible on a chart
var chartableIncrement: Double {
if self == .milligramsPerDeciliter {
Expand Down
8 changes: 4 additions & 4 deletions Common/Extensions/NumberFormatter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
//

import Foundation
import HealthKit
import LoopAlgorithm


extension NumberFormatter {
static func glucoseFormatter(for unit: HKUnit) -> NumberFormatter {
static func glucoseFormatter(for unit: LoopUnit) -> NumberFormatter {
let numberFormatter = NumberFormatter()

numberFormatter.numberStyle = .decimal
Expand All @@ -24,11 +24,11 @@ extension NumberFormatter {
return string(from: NSNumber(value: number))
}

func string(from quantity: HKQuantity, unit: HKUnit) -> String? {
func string(from quantity: LoopQuantity, unit: LoopUnit) -> String? {
return string(from: quantity.doubleValue(for: unit), unit: unit)
}

func string(from number: Double, unit: HKUnit) -> String? {
func string(from number: Double, unit: LoopUnit) -> String? {
return string(from: number, unit: unit.localizedShortUnitString)
}

Expand Down
7 changes: 3 additions & 4 deletions Common/Extensions/SampleValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
// Copyright © 2018 LoopKit Authors. All rights reserved.
//

import HealthKit
import LoopKit
import LoopAlgorithm

extension Collection where Element == SampleValue {
/// O(n)
var quantityRange: ClosedRange<HKQuantity>? {
var lowest: HKQuantity?
var highest: HKQuantity?
var quantityRange: ClosedRange<LoopQuantity>? {
var lowest: LoopQuantity?
var highest: LoopQuantity?

for sample in self {
if let l = lowest {
Expand Down
18 changes: 9 additions & 9 deletions Common/Models/StatusExtensionContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// This class allows Loop to pass context data to the Loop Status Extension.

import Foundation
import HealthKit
import LoopAlgorithm
import LoopKit
import LoopKitUI
import LoopAlgorithm
Expand All @@ -25,24 +25,24 @@ struct GlucoseDisplayableContext: GlucoseDisplayable {
let isStateValid: Bool
let stateDescription: String
let trendType: GlucoseTrend?
let trendRate: HKQuantity?
let trendRate: LoopQuantity?
let isLocal: Bool
let glucoseRangeCategory: GlucoseRangeCategory?
}

struct GlucoseContext: GlucoseValue {
let value: Double
let unit: HKUnit
let unit: LoopUnit
let startDate: Date

var quantity: HKQuantity {
return HKQuantity(unit: unit, doubleValue: value)
var quantity: LoopQuantity {
return LoopQuantity(unit: unit, doubleValue: value)
}
}

struct PredictedGlucoseContext {
let values: [Double]
let unit: HKUnit
let unit: LoopUnit
let startDate: Date
let interval: TimeInterval

Expand Down Expand Up @@ -162,7 +162,7 @@ extension GlucoseDisplayableContext: RawRepresentable {
}

if let trendRateValue = rawValue["trendRateValue"] as? Double {
trendRate = HKQuantity(unit: .milligramsPerDeciliterPerMinute, doubleValue: trendRateValue)
trendRate = LoopQuantity(unit: .milligramsPerDeciliterPerMinute, doubleValue: trendRateValue)
} else {
trendRate = nil
}
Expand All @@ -182,7 +182,7 @@ extension GlucoseDisplayableContext: RawRepresentable {
]
raw["trendType"] = trendType?.rawValue
if let trendRate = trendRate {
raw["trendRateValue"] = trendRate.doubleValue(for: HKUnit.milligramsPerDeciliterPerMinute)
raw["trendRateValue"] = trendRate.doubleValue(for: LoopUnit.milligramsPerDeciliterPerMinute)
}
raw["glucoseRangeCategory"] = glucoseRangeCategory?.rawValue

Expand All @@ -204,7 +204,7 @@ extension PredictedGlucoseContext: RawRepresentable {
}

self.values = values
self.unit = HKUnit(from: unitString)
self.unit = LoopUnit(from: unitString)
self.startDate = startDate
self.interval = interval
}
Expand Down
17 changes: 8 additions & 9 deletions Common/Models/WatchContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
//

import Foundation
import HealthKit
import LoopKit
import LoopAlgorithm

Expand All @@ -19,19 +18,19 @@ final class WatchContext: RawRepresentable {

var creationDate = Date()

var displayGlucoseUnit: HKUnit?
var displayGlucoseUnit: LoopUnit?

var glucose: HKQuantity?
var glucose: LoopQuantity?
var glucoseCondition: GlucoseCondition?
var glucoseTrend: GlucoseTrend?
var glucoseTrendRate: HKQuantity?
var glucoseTrendRate: LoopQuantity?
var glucoseDate: Date?
var glucoseIsDisplayOnly: Bool?
var glucoseWasUserEntered: Bool?
var glucoseSyncIdentifier: String?

var predictedGlucose: WatchPredictedGlucose?
var eventualGlucose: HKQuantity? {
var eventualGlucose: LoopQuantity? {
return predictedGlucose?.values.last?.quantity
}

Expand Down Expand Up @@ -63,11 +62,11 @@ final class WatchContext: RawRepresentable {
isClosedLoop = rawValue["cl"] as? Bool

if let unitString = rawValue["gu"] as? String {
displayGlucoseUnit = HKUnit(from: unitString)
displayGlucoseUnit = LoopUnit(from: unitString)
}
let unit = displayGlucoseUnit ?? .milligramsPerDeciliter
if let glucoseValue = rawValue["gv"] as? Double {
glucose = HKQuantity(unit: unit, doubleValue: glucoseValue)
glucose = LoopQuantity(unit: unit, doubleValue: glucoseValue)
}

if let rawGlucoseCondition = rawValue["gc"] as? GlucoseCondition.RawValue {
Expand All @@ -77,7 +76,7 @@ final class WatchContext: RawRepresentable {
glucoseTrend = GlucoseTrend(rawValue: rawGlucoseTrend)
}
if let glucoseTrendRateValue = rawValue["gtrv"] as? Double {
glucoseTrendRate = HKQuantity(unit: .milligramsPerDeciliterPerMinute, doubleValue: glucoseTrendRateValue)
glucoseTrendRate = LoopQuantity(unit: .milligramsPerDeciliterPerMinute, doubleValue: glucoseTrendRateValue)
}
glucoseDate = rawValue["gd"] as? Date
glucoseIsDisplayOnly = rawValue["gdo"] as? Bool
Expand Down Expand Up @@ -126,7 +125,7 @@ final class WatchContext: RawRepresentable {
raw["gc"] = glucoseCondition?.rawValue
raw["gt"] = glucoseTrend?.rawValue
if let glucoseTrendRate = glucoseTrendRate {
let unitPerMinute = unit.unitDivided(by: .minute())
let unitPerMinute = unit.glucose(per: .minutes)
raw["gtru"] = unitPerMinute.unitString
raw["gtrv"] = glucoseTrendRate.doubleValue(for: unitPerMinute)
}
Expand Down
4 changes: 2 additions & 2 deletions Common/Models/WatchHistoricalGlucose.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ extension WatchHistoricalGlucose: RawRepresentable {
syncIdentifier: syncIdentifiers[$0],
syncVersion: syncVersions[$0],
startDate: startDates[$0],
quantity: HKQuantity(unit: .milligramsPerDeciliter, doubleValue: quantities[$0]),
quantity: LoopQuantity(unit: .milligramsPerDeciliter, doubleValue: quantities[$0]),
condition: conditions[$0],
trend: trends[$0],
trendRate: trendRates[$0].flatMap { HKQuantity(unit: .milligramsPerDeciliterPerMinute, doubleValue: $0) },
trendRate: trendRates[$0].flatMap { LoopQuantity(unit: .milligramsPerDeciliterPerMinute, doubleValue: $0) },
isDisplayOnly: isDisplayOnlys[$0],
wasUserEntered: wasUserEntereds[$0],
device: devices[$0].flatMap { try? HKDevice(from: $0) },
Expand Down
3 changes: 1 addition & 2 deletions Common/Models/WatchPredictedGlucose.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import Foundation
import LoopKit
import HealthKit
import LoopAlgorithm


Expand Down Expand Up @@ -47,7 +46,7 @@ extension WatchPredictedGlucose: RawRepresentable {

self.values = values.enumerated().map { tuple in
PredictedGlucoseValue(startDate: firstDate + Double(tuple.0) * interval,
quantity: HKQuantity(unit: .milligramsPerDeciliter, doubleValue: Double(tuple.1)))
quantity: LoopQuantity(unit: .milligramsPerDeciliter, doubleValue: Double(tuple.1)))
}
}
}
1 change: 0 additions & 1 deletion Learn/Configuration/QuantityRangeEntry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
// Copyright © 2019 LoopKit Authors. All rights reserved.
//

import HealthKit
import LoopKit
import UIKit

Expand Down
1 change: 0 additions & 1 deletion Learn/Lessons/ModalDayLesson.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
//

import Foundation
import HealthKit
import LoopCore
import LoopKit
import os.log
Expand Down
1 change: 0 additions & 1 deletion Learn/Lessons/TimeInRangeLesson.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import LoopCore
import LoopKit
import LoopKitUI
import LoopUI
import HealthKit
import os.log


Expand Down
1 change: 0 additions & 1 deletion Learn/Managers/DataManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
//

import Foundation
import HealthKit
import LoopKit
import LoopCore

Expand Down
1 change: 0 additions & 1 deletion Loop Widget Extension/Components/GlucoseView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import SwiftUI
import LoopKit
import HealthKit
import LoopCore

struct GlucoseView: View {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
// Copyright © 2023 LoopKit Authors. All rights reserved.
//

import HealthKit
import LoopCore
import LoopKit
import WidgetKit
Expand All @@ -25,8 +24,8 @@ struct StatusWidgetTimelimeEntry: TimelineEntry {

let currentGlucose: GlucoseValue?
let glucoseFetchedAt: Date?
let delta: HKQuantity?
let unit: HKUnit?
let delta: LoopQuantity?
let unit: LoopUnit?
let sensor: GlucoseDisplayableContext?

let pumpHighlight: DeviceStatusHighlightContext?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,15 @@ class StatusWidgetTimelineProvider: TimelineProvider {

let finalGlucose = glucose

guard let defaults = self.defaults,
guard let hkUnit = await healthStore.cachedPreferredUnits(for: .bloodGlucose),
let defaults = self.defaults,
let context = defaults.statusExtensionContext,
let contextUpdatedAt = context.createdAt,
let unit = await healthStore.cachedPreferredUnits(for: .bloodGlucose)
let contextUpdatedAt = context.createdAt
else {
return
}

let unit = LoopUnit(from: hkUnit)
let lastCompleted = context.lastLoopCompleted

let closeLoop = context.isClosedLoop ?? false
Expand All @@ -137,15 +138,15 @@ class StatusWidgetTimelineProvider: TimelineProvider {
previousGlucose = finalGlucose[finalGlucose.count - 2]
}

var delta: HKQuantity?
var delta: LoopQuantity?

// Making sure that previous glucose is within 6 mins of last glucose to avoid large deltas on sensor changes, missed readings, etc.
if let prevGlucose = previousGlucose,
let currGlucose = currentGlucose,
currGlucose.startDate.timeIntervalSince(prevGlucose.startDate).minutes < 6
{
let deltaMGDL = currGlucose.quantity.doubleValue(for: .milligramsPerDeciliter) - prevGlucose.quantity.doubleValue(for: .milligramsPerDeciliter)
delta = HKQuantity(unit: .milligramsPerDeciliter, doubleValue: deltaMGDL)
delta = LoopQuantity(unit: .milligramsPerDeciliter, doubleValue: deltaMGDL)
}

let predictedGlucose = context.predictedGlucose?.samples
Expand Down
4 changes: 2 additions & 2 deletions Loop/Extensions/CarbStore+SimulatedCoreData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//

import Foundation
import HealthKit
import LoopAlgorithm
import LoopKit

// MARK: - Simulated Core Data
Expand Down Expand Up @@ -63,7 +63,7 @@ extension CarbStore {
fileprivate extension NewCarbEntry {
static func simulated(startDate: Date, grams: Double, absorptionTime: TimeInterval) -> NewCarbEntry {
return NewCarbEntry(date: startDate,
quantity: HKQuantity(unit: .gram(), doubleValue: grams),
quantity: LoopQuantity(unit: .gram, doubleValue: grams),
startDate: startDate,
foodType: "Simulated",
absorptionTime: absorptionTime)
Expand Down
4 changes: 2 additions & 2 deletions Loop/Extensions/DoseStore+SimulatedCoreData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//

import Foundation
import HealthKit
import LoopAlgorithm
import LoopKit

// MARK: - Simulated Core Data
Expand Down Expand Up @@ -144,7 +144,7 @@ fileprivate extension PersistedPumpEvent {
value: rate,
unit: .unitsPerHour,
deliveredUnits: rate * duration / .hours(1),
scheduledBasalRate: HKQuantity(unit: .internationalUnitsPerHour, doubleValue: scheduledRate)))
scheduledBasalRate: LoopQuantity(unit: .internationalUnitsPerHour, doubleValue: scheduledRate)))
}

private static func simulated(date: Date, type: PumpEventType, alarmType: PumpAlarmType? = nil) -> PersistedPumpEvent {
Expand Down
Loading

0 comments on commit b723d23

Please sign in to comment.