Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Common/Extensions/TextFieldTableViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ import LoopKitUI
import LoopUI


extension TextFieldTableViewCell: NibLoadable { }
extension TextFieldTableViewCell: @retroactive NibLoadable { }
2 changes: 1 addition & 1 deletion Loop/Extensions/UIDevice+Loop.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ extension UIDevice.BatteryState {
}
}

extension UIDevice.BatteryState: CustomStringConvertible {
extension UIDevice.BatteryState: @retroactive CustomStringConvertible {
public var description: String {
switch self {
case .unknown:
Expand Down
2 changes: 1 addition & 1 deletion Loop/Extensions/UITableViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ import UIKit
import LoopCore


extension UITableViewCell: IdentifiableClass { }
extension UITableViewCell: @retroactive IdentifiableClass { }
8 changes: 4 additions & 4 deletions Loop/Extensions/UserNotifications+Loop.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ extension UNUserNotificationCenter {
}
}

extension UNAuthorizationStatus: CustomStringConvertible {
extension UNAuthorizationStatus: @retroactive CustomStringConvertible {
public var description: String {
switch self {
case .notDetermined:
Expand All @@ -50,7 +50,7 @@ extension UNAuthorizationStatus: CustomStringConvertible {
}
}

extension UNShowPreviewsSetting: CustomStringConvertible {
extension UNShowPreviewsSetting: @retroactive CustomStringConvertible {
public var description: String {
switch self {
case .always:
Expand All @@ -65,7 +65,7 @@ extension UNShowPreviewsSetting: CustomStringConvertible {
}
}

extension UNNotificationSetting: CustomStringConvertible {
extension UNNotificationSetting: @retroactive CustomStringConvertible {
public var description: String {
switch self {
case .notSupported:
Expand All @@ -80,7 +80,7 @@ extension UNNotificationSetting: CustomStringConvertible {
}
}

extension UNAlertStyle: CustomStringConvertible {
extension UNAlertStyle: @retroactive CustomStringConvertible {
public var description: String {
switch self {
case .none:
Expand Down
12 changes: 10 additions & 2 deletions Loop/Managers/Alerts/AlertManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,11 @@ extension AlertManager: AlertPermissionsCheckerDelegate {
retractionHandler: { alert in
// need to dismiss the in-app alert outside of the alert system
Task {
try await self.recordRetractedAlert(alert, at: Date())
do {
try await self.recordRetractedAlert(alert, at: Date())
} catch {
self.log.error("Error recording retracted alert: %{public}@", String(describing: error))
}
await self.dismissUnsafeNotificationPermissionsInAppAlert()
}
}
Expand Down Expand Up @@ -800,7 +804,11 @@ extension AlertManager: AlertPermissionsCheckerDelegate {
let alertController = AlertPermissionsChecker.constructUnsafeNotificationPermissionsInAppAlert(alert: alert) { [weak self] alert in
UserDefaults.standard.hasIssuedNotificationPermissionsAlert = false
Task {
try await self?.acknowledgeAlert(identifier: alert.alertIdentifier)
do {
try await self?.acknowledgeAlert(identifier: alert.alertIdentifier)
} catch {
self?.log.error("Error acknowledging alert: %{public}@", String(describing: error))
}
}
}

Expand Down
12 changes: 8 additions & 4 deletions Loop/Managers/Alerts/InAppModalAlertScheduler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,14 @@ extension InAppModalAlertScheduler {
// the completion is called after the alert is acknowledged
self?.clearPresentedAlert(identifier: alert.identifier)
Task {
if action.identifier == "acknowledge" {
try await self?.alertManagerResponder?.acknowledgeAlert(identifier: alert.identifier)
} else {
try await self?.alertManagerResponder?.userDidSelectAction(alertIdentifier: alert.identifier, actionIdentifier: action.identifier)
do {
if action.identifier == "acknowledge" {
try await self?.alertManagerResponder?.acknowledgeAlert(identifier: alert.identifier)
} else {
try await self?.alertManagerResponder?.userDidSelectAction(alertIdentifier: alert.identifier, actionIdentifier: action.identifier)
}
} catch {
self?.log.error("Error responding to alert action: %{public}@", String(describing: error))
}
}
}
Expand Down
8 changes: 2 additions & 6 deletions Loop/Managers/DeviceDataManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1292,19 +1292,15 @@ extension DeviceDataManager {
}

func deleteTestingCarbData(before: Date = Date()) async throws {
guard let testingCGMManager = cgmManager as? TestingCGMManager,
let testingPumpManager = pumpManager as? TestingPumpManager
else {
guard cgmManager is TestingCGMManager, pumpManager is TestingPumpManager else {
return
}

try await carbStore.deleteAllCarbEntries()
}

func deleteTestingAlertData() async throws {
guard let testingCGMManager = cgmManager as? TestingCGMManager,
let testingPumpManager = pumpManager as? TestingPumpManager
else {
guard cgmManager is TestingCGMManager, pumpManager is TestingPumpManager else {
return
}

Expand Down
32 changes: 18 additions & 14 deletions Loop/Managers/Live Activity/LiveActivityManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -562,24 +562,28 @@ extension TemporaryScheduleOverride {
func liveActivityTitleAndSymbol() -> (title: String, systemSymbolName: String?) {
switch context {
case .preset(let preset):
guard let symbol = preset.symbol else {
return (preset.name, nil)
}
switch symbol.symbolType {
case .emoji:
return ("\(symbol.value) \(preset.name)", nil)
case .systemImage:
return (preset.name, symbol.value)
case .image:
// Asset-image symbols can't be loaded from the widget bundle; render name only.
return (preset.name, nil)
}
return Self.titleAndSymbol(for: preset)
case .activity(let activity):
return Self.titleAndSymbol(for: activity.preset)
case .custom:
return (NSLocalizedString("Custom preset", comment: "The title of the cell indicating a generic custom preset is enabled"), nil)
case .preMeal:
return (NSLocalizedString("Pre-meal Preset", comment: "Status row title for premeal override enabled"), "fork.knife")
@unknown default:
return ("", nil)
}
}

private static func titleAndSymbol(for preset: TemporaryPreset) -> (title: String, systemSymbolName: String?) {
guard let symbol = preset.symbol else {
return (preset.name, nil)
}
switch symbol.symbolType {
case .emoji:
return ("\(symbol.value) \(preset.name)", nil)
case .systemImage:
return (preset.name, symbol.value)
case .image:
// Asset-image symbols can't be loaded from the widget bundle; render name only.
return (preset.name, nil)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,6 @@ class MealDetectionManager {
}

let date = test_currentDate ?? Date()
let samplesStart = date.addingTimeInterval(-MissedMealSettings.maxRecency)

guard let sensitivitySchedule = settingsProvider.insulinSensitivityScheduleApplyingOverrideHistory,
let carbRatioSchedule = settingsProvider.carbRatioSchedule,
let maxBolus = settingsProvider.maximumBolus else
Expand Down
2 changes: 1 addition & 1 deletion Loop/Managers/RemoteDataServicesManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ extension RemoteDataServicesManager {
case .failure(let error):
self.log.error("Error querying alert data: %{public}@", String(describing: error))
semaphore.signal()
case .success(let queryAnchor, let data):
case .success((let queryAnchor, let data)):
Task {
do {
try await remoteDataService.uploadAlertData(data)
Expand Down
2 changes: 1 addition & 1 deletion Loop/Managers/SleepStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class SleepStore {
// if there were no .inBed samples, check if there are any .asleep samples that could be used to estimate bedtime
let asleepPredicate = HKQuery.predicateForCategorySamples(
with: .equalTo,
value: HKCategoryValueSleepAnalysis.asleep.rawValue
value: HKCategoryValueSleepAnalysis.asleepUnspecified.rawValue
)
self.getAverageSleepStartTime(matching: asleepPredicate, sampleLimit: sampleLimit, completion)
default:
Expand Down
2 changes: 1 addition & 1 deletion Loop/Models/GlucoseEffectVelocity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import LoopKit
import LoopAlgorithm


extension GlucoseEffectVelocity: RawRepresentable {
extension GlucoseEffectVelocity: @retroactive RawRepresentable {
public typealias RawValue = [String: Any]

static let unit = LoopUnit.milligramsPerDeciliterPerMinute
Expand Down
1 change: 0 additions & 1 deletion Loop/View Controllers/CarbAbsorptionViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,6 @@ final class CarbAbsorptionViewController: LoopChartsTableViewController, Identif

return cell
case .entries:
let unit = LoopUnit.gram
let cell = tableView.dequeueReusableCell(withIdentifier: CarbEntryTableViewCell.className, for: indexPath) as! CarbEntryTableViewCell
cell.accessibilityIdentifier = "cell_CarbEntry"

Expand Down
7 changes: 5 additions & 2 deletions Loop/View Controllers/StatusTableViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,6 @@ final class StatusTableViewController: LoopChartsTableViewController {
var cobValues: [CarbValue]?
var carbsOnBoard: LoopQuantity?
let startDate = charts.startDate
let basalDeliveryState = self.basalDeliveryState
let automaticDosingEnabled = settingsManager.dosingEnabled

let state = await loopManager.algorithmDisplayState
Expand Down Expand Up @@ -1363,7 +1362,11 @@ final class StatusTableViewController: LoopChartsTableViewController {
Task {
var dosingDecision: StoredDosingDecision?
if let decisionId = doseEntry.decisionId {
dosingDecision = try await self.loopManager.dosingDecisionStore.findDosingDecisionsById(decisionId)
do {
dosingDecision = try await self.loopManager.dosingDecisionStore.findDosingDecisionsById(decisionId)
} catch {
self.log.error("Error finding dosing decision: %{public}@", String(describing: error))
}
}

let viewController = CommandResponseViewController(command: { (completionHandler) -> String in
Expand Down
2 changes: 1 addition & 1 deletion Loop/View Models/FavoriteFoodInsightsViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class FavoriteFoodInsightsViewModel: ObservableObject {
Task { @MainActor in
do {
if let historicalChartsData = try await delegate?.getHistoricalChartsData(start: dateInterval.start, end: dateInterval.end) {
var carbEntriesWithCorrectedFavoriteFoods = historicalChartsData.carbEntries.map({ historicalCarbEntry in
let carbEntriesWithCorrectedFavoriteFoods = historicalChartsData.carbEntries.map({ historicalCarbEntry in
// only show a favorite food icon in the glcuose-carb chart if carb entry is currently viewed favorite food
StoredCarbEntry(
startDate: historicalCarbEntry.startDate,
Expand Down
2 changes: 1 addition & 1 deletion Loop/Views/AlertManagementView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ struct AlertManagementView: View {
ConfirmationSheet(resumeDate: resumeDate)
}
}
.onChange(of: durationWasSelection) { _ in
.onChange(of: durationWasSelection) {
if durationWasSelection, let durationSelection, let durationSelectionString = formatter.string(from: durationSelection) {
sheet = .confirmation(resumeDate: Date().addingTimeInterval(durationSelection))
formattedSelectedDuration.wrappedValue = durationSelectionString
Expand Down
10 changes: 4 additions & 6 deletions Loop/Views/BolusProgressTableViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ public class BolusProgressTableViewCell: UITableViewCell {

(progressLabel.superview as? UIStackView)?.addArrangedSubview(infoButton)

registerForTraitChanges(UITraitCollection.systemTraitsAffectingColorAppearance) { (cell: Self, _: UITraitCollection) in
cell.updateColors()
}

paddedView.layer.masksToBounds = true
paddedView.layer.cornerRadius = 10
paddedView.layer.borderWidth = 1
Expand All @@ -86,12 +90,6 @@ public class BolusProgressTableViewCell: UITableViewCell {
updateColors()
}

public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)

updateColors()
}

private func updateColors() {
progressIndicator.startColor = tintColor
progressIndicator.endColor = tintColor
Expand Down
2 changes: 1 addition & 1 deletion Loop/Views/CarbEntryView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ extension CarbEntryView {
.padding(.horizontal)
.background(CardBackground())
.padding(.horizontal)
.onChange(of: viewModel.selectedFavoriteFoodIndex, perform: collapseFavoriteFoodsRowIfNeeded(_:))
.onChange(of: viewModel.selectedFavoriteFoodIndex) { _, newIndex in collapseFavoriteFoodsRowIfNeeded(newIndex) }
}
}

Expand Down
2 changes: 1 addition & 1 deletion Loop/Views/Favorite Foods/FavoriteFoodsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ struct FavoriteFoodsView: View {
.sheet(isPresented: $viewModel.isAddViewActive) {
FavoriteFoodAddEditView(onSave: viewModel.onFoodSave(_:))
}
.onChange(of: editMode) { newValue in
.onChange(of: editMode) { _, newValue in
if !newValue.isEditing {
foodToConfirmDeleteId = nil
}
Expand Down
9 changes: 3 additions & 6 deletions Loop/Views/IconTitleSubtitleTableViewCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,9 @@ class IconTitleSubtitleTableViewCell: UITableViewCell {
backgroundView?.layer.insertSublayer(gradient, at: 0)

updateColors()
}

public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)

updateColors()
registerForTraitChanges(UITraitCollection.systemTraitsAffectingColorAppearance) { (cell: Self, _: UITraitCollection) in
cell.updateColors()
}
}

private func updateColors() {
Expand Down
16 changes: 8 additions & 8 deletions Loop/Views/LiveActivityManagementView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct LiveActivityManagementView: View {
List {
Section(header: Text("Lock Screen / Dynamic Island / CarPlay")) {
Toggle(NSLocalizedString("Enabled", comment: "Title for enable live activity toggle"), isOn: $viewModel.enabled)
.onChange(of: viewModel.enabled) { _ in
.onChange(of: viewModel.enabled) {
self.isDirty = previousViewModel.enabled != viewModel.enabled
}
}
Expand All @@ -49,45 +49,45 @@ struct LiveActivityManagementView: View {
.labelsHidden()
}
)
.onChange(of: viewModel.mode) { _ in
.onChange(of: viewModel.mode) {
self.isDirty = previousViewModel.mode != viewModel.mode
}
}

Section(header: Text("Display Control Options")) {
Toggle(NSLocalizedString("Display prediction in plot", comment: "Title for prediction line toggle"), isOn: $viewModel.addPredictiveLine)
.transition(.move(edge: viewModel.mode == .large ? .top : .bottom))
.onChange(of: viewModel.addPredictiveLine) { _ in
.onChange(of: viewModel.addPredictiveLine) {
self.isDirty = previousViewModel.addPredictiveLine != viewModel.addPredictiveLine
}

Toggle(NSLocalizedString("Display colors for glucose", comment: "Title for glucose coloring"), isOn: $viewModel.useLimits)
.transition(.move(edge: viewModel.mode == .large ? .top : .bottom))
.onChange(of: viewModel.useLimits) { _ in
.onChange(of: viewModel.useLimits) {
self.isDirty = previousViewModel.useLimits != viewModel.useLimits
}

if self.viewModel.useLimits {
if self.displayGlucosePreference.unit == .millimolesPerLiter {
TextInput(label: "Upper limit", value: $viewModel.upperLimitChartMmol)
.transition(.move(edge: viewModel.useLimits ? .top : .bottom))
.onChange(of: viewModel.upperLimitChartMmol) { _ in
.onChange(of: viewModel.upperLimitChartMmol) {
self.isDirty = previousViewModel.upperLimitChartMmol != viewModel.upperLimitChartMmol
}
TextInput(label: "Lower limit", value: $viewModel.lowerLimitChartMmol)
.transition(.move(edge: viewModel.useLimits ? .top : .bottom))
.onChange(of: viewModel.lowerLimitChartMmol) { _ in
.onChange(of: viewModel.lowerLimitChartMmol) {
self.isDirty = previousViewModel.lowerLimitChartMmol != viewModel.lowerLimitChartMmol
}
} else {
TextInput(label: "Upper limit", value: $viewModel.upperLimitChartMg)
.transition(.move(edge: viewModel.useLimits ? .top : .bottom))
.onChange(of: viewModel.upperLimitChartMg) { _ in
.onChange(of: viewModel.upperLimitChartMg) {
self.isDirty = previousViewModel.upperLimitChartMg != viewModel.upperLimitChartMg
}
TextInput(label: "Lower limit", value: $viewModel.lowerLimitChartMg)
.transition(.move(edge: viewModel.useLimits ? .top : .bottom))
.onChange(of: viewModel.lowerLimitChartMg) { _ in
.onChange(of: viewModel.lowerLimitChartMg) {
self.isDirty = previousViewModel.lowerLimitChartMg != viewModel.lowerLimitChartMg
}
}
Expand Down
8 changes: 4 additions & 4 deletions Loop/Views/ManualGlucoseEntryRow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,16 @@ struct ManualGlucoseEntryRow: View {
maxLength: 4,
doneButtonColor: .loopAccent
)
.onChange(of: valueText, perform: { value in
.onChange(of: valueText) {
if let manualGlucoseValue = displayGlucosePreference.formatter.numberFormatter.number(from: valueText)?.doubleValue {
quantity = LoopQuantity(unit: displayGlucosePreference.unit, doubleValue: manualGlucoseValue)
} else {
quantity = nil
}
})
.onChange(of: displayGlucosePreference.unit, perform: { value in
}
.onChange(of: displayGlucosePreference.unit) {
unitsChanged()
})
}
.accessibilityIdentifier("textField_FingerstickGlucose")

Text(displayGlucosePreference.formatter.localizedUnitStringWithPlurality())
Expand Down
Loading