Implemented treatment, with persistence and uploading to nightscout.
This commit is contained in:
parent
689dc5ab1e
commit
956c23b29d
|
@ -1,6 +1,6 @@
|
|||
PODS:
|
||||
- ActionClosurable (2.0.0)
|
||||
- CryptoSwift (1.4.0)
|
||||
- CryptoSwift (1.4.2)
|
||||
- PieCharts (0.0.7)
|
||||
- SwiftCharts (0.6.5)
|
||||
|
||||
|
@ -27,7 +27,7 @@ CHECKOUT OPTIONS:
|
|||
|
||||
SPEC CHECKSUMS:
|
||||
ActionClosurable: 92729a0f0bb4b38d2744319ea8282a3ce8fb1e0a
|
||||
CryptoSwift: 7cc902df1784de3b389a387756c7d710f197730c
|
||||
CryptoSwift: a532e74ed010f8c95f611d00b8bbae42e9fe7c17
|
||||
PieCharts: 30e50dfa7dc19e5b84e9878d32089673ef5d0453
|
||||
SwiftCharts: 2e755ea292f0b87d3e4b2c1eb5afc080a20cdc15
|
||||
|
||||
|
|
|
@ -26,10 +26,17 @@
|
|||
47F8E95A2710255D00B8B02B /* ConstantsWatchApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F8E9592710255C00B8B02B /* ConstantsWatchApp.swift */; };
|
||||
47FB28082636B04200042FFB /* StatisticsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47FB28072636B04200042FFB /* StatisticsManager.swift */; };
|
||||
533272967B05B378D81F6529 /* Pods_xdrip.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DB0736D7B1553FC8350324C /* Pods_xdrip.framework */; };
|
||||
666E283A26F7E54C00ACE4DF /* xDrip.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 666E283826F7E54C00ACE4DF /* xDrip.xcconfig */; };
|
||||
666E283B26F7E54C00ACE4DF /* Version.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 666E283926F7E54C00ACE4DF /* Version.xcconfig */; };
|
||||
CE1B2FE025D0264B00F642F5 /* LaunchScreen.strings in Resources */ = {isa = PBXBuildFile; fileRef = CE1B2FD125D0264900F642F5 /* LaunchScreen.strings */; };
|
||||
CE1B2FE125D0264B00F642F5 /* Main.strings in Resources */ = {isa = PBXBuildFile; fileRef = CE1B2FD425D0264900F642F5 /* Main.strings */; };
|
||||
D400F8032778BD8000B57648 /* TextsTreatmentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D400F8022778BD8000B57648 /* TextsTreatmentsView.swift */; };
|
||||
D4028CC02774A50600341476 /* TreatmentsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4028CBF2774A50600341476 /* TreatmentsViewController.swift */; };
|
||||
D40C3DA4277542C400111B73 /* TreatmentEntry+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = D40C3DA3277542C400111B73 /* TreatmentEntry+CoreDataClass.swift */; };
|
||||
D40C3DA62775438F00111B73 /* TreatmentEntry+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = D40C3DA52775438F00111B73 /* TreatmentEntry+CoreDataProperties.swift */; };
|
||||
D482BD942776153F003C4FB2 /* TreatmentsNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D482BD932776153F003C4FB2 /* TreatmentsNavigationController.swift */; };
|
||||
D484BC292774F783008490E9 /* TreatmentsInsertViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D484BC282774F783008490E9 /* TreatmentsInsertViewController.swift */; };
|
||||
D4AC54502778C82C0097FF10 /* Treatments.strings in Resources */ = {isa = PBXBuildFile; fileRef = D4AC54412778C82B0097FF10 /* Treatments.strings */; };
|
||||
D4BAF37627769B38009D3465 /* TreatmentTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4BAF37527769B38009D3465 /* TreatmentTableViewCell.swift */; };
|
||||
D4FD899727772F9100689788 /* TreatmentEntryAccessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4FD899627772F9100689788 /* TreatmentEntryAccessor.swift */; };
|
||||
F51B9F7D24B216CD00FC0643 /* Libre1NonFixedSlopeCalibrator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F51B9F7C24B216CD00FC0643 /* Libre1NonFixedSlopeCalibrator.swift */; };
|
||||
F8025C0A21D94FD700ECF0C0 /* CBManagerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8025C0921D94FD700ECF0C0 /* CBManagerState.swift */; };
|
||||
F8025C1321DA683400ECF0C0 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8025C1221DA683400ECF0C0 /* Data.swift */; };
|
||||
|
@ -703,6 +710,30 @@
|
|||
CE1B2FDE25D0264B00F642F5 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Snooze.strings; sourceTree = "<group>"; };
|
||||
CE1B2FDF25D0264B00F642F5 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/BluetoothPeripheralView.strings; sourceTree = "<group>"; };
|
||||
CE1B2FE425D026B400F642F5 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Common.strings; sourceTree = "<group>"; };
|
||||
D400F8022778BD8000B57648 /* TextsTreatmentsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextsTreatmentsView.swift; sourceTree = "<group>"; };
|
||||
D4028CBF2774A50600341476 /* TreatmentsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TreatmentsViewController.swift; sourceTree = "<group>"; };
|
||||
D40C3DA3277542C400111B73 /* TreatmentEntry+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TreatmentEntry+CoreDataClass.swift"; sourceTree = "<group>"; };
|
||||
D40C3DA52775438F00111B73 /* TreatmentEntry+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TreatmentEntry+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||
D482BD932776153F003C4FB2 /* TreatmentsNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TreatmentsNavigationController.swift; sourceTree = "<group>"; };
|
||||
D484BC282774F783008490E9 /* TreatmentsInsertViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TreatmentsInsertViewController.swift; sourceTree = "<group>"; };
|
||||
D4A2661D2773EB8300B60F2A /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
|
||||
D4A2661F2773EB8300B60F2A /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
|
||||
D4AC54422778C82B0097FF10 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Treatments.strings; sourceTree = "<group>"; };
|
||||
D4AC54432778C82B0097FF10 /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = sl.lproj/Treatments.strings; sourceTree = "<group>"; };
|
||||
D4AC54442778C82B0097FF10 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Treatments.strings; sourceTree = "<group>"; };
|
||||
D4AC54452778C82B0097FF10 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Treatments.strings; sourceTree = "<group>"; };
|
||||
D4AC54462778C82B0097FF10 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Treatments.strings; sourceTree = "<group>"; };
|
||||
D4AC54472778C82B0097FF10 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/Treatments.strings; sourceTree = "<group>"; };
|
||||
D4AC54482778C82B0097FF10 /* pl-PL */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pl-PL"; path = "pl-PL.lproj/Treatments.strings"; sourceTree = "<group>"; };
|
||||
D4AC54492778C82B0097FF10 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Treatments.strings; sourceTree = "<group>"; };
|
||||
D4AC544A2778C82B0097FF10 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Treatments.strings; sourceTree = "<group>"; };
|
||||
D4AC544B2778C82B0097FF10 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Treatments.strings; sourceTree = "<group>"; };
|
||||
D4AC544C2778C82B0097FF10 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Treatments.strings; sourceTree = "<group>"; };
|
||||
D4AC544D2778C82C0097FF10 /* zh */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = zh; path = zh.lproj/Treatments.strings; sourceTree = "<group>"; };
|
||||
D4AC544E2778C82C0097FF10 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Treatments.strings; sourceTree = "<group>"; };
|
||||
D4AC544F2778C82C0097FF10 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Treatments.strings; sourceTree = "<group>"; };
|
||||
D4BAF37527769B38009D3465 /* TreatmentTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TreatmentTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D4FD899627772F9100689788 /* TreatmentEntryAccessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TreatmentEntryAccessor.swift; sourceTree = "<group>"; };
|
||||
F51B9F7C24B216CD00FC0643 /* Libre1NonFixedSlopeCalibrator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Libre1NonFixedSlopeCalibrator.swift; sourceTree = "<group>"; };
|
||||
F8025C0921D94FD700ECF0C0 /* CBManagerState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBManagerState.swift; sourceTree = "<group>"; };
|
||||
F8025C1221DA683400ECF0C0 /* Data.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = "<group>"; };
|
||||
|
@ -1533,6 +1564,17 @@
|
|||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D4028CBE2774A4B900341476 /* Treatments */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D4028CBF2774A50600341476 /* TreatmentsViewController.swift */,
|
||||
D484BC282774F783008490E9 /* TreatmentsInsertViewController.swift */,
|
||||
D482BD932776153F003C4FB2 /* TreatmentsNavigationController.swift */,
|
||||
D4BAF37527769B38009D3465 /* TreatmentTableViewCell.swift */,
|
||||
);
|
||||
path = Treatments;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F8025C0B21D9513400ECF0C0 /* Extensions */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -1930,6 +1972,7 @@
|
|||
F85DC2F921D2CCC000B9F74A /* Storyboards */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D4AC54412778C82B0097FF10 /* Treatments.strings */,
|
||||
F8B3A7B3226A0A71004BA588 /* Alerts.strings */,
|
||||
F8B3A80B227A3E97004BA588 /* AlertTypesSettingsView.strings */,
|
||||
470CE1FE246802EB00D5CB74 /* BluetoothPeripheralsView.strings */,
|
||||
|
@ -1960,6 +2003,7 @@
|
|||
F85DC2FA21D2CD3000B9F74A /* View Controllers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D4028CBE2774A4B900341476 /* Treatments */,
|
||||
F8297F47238DCAD800D74D66 /* BluetoothPeripheralsNavigationController */,
|
||||
F8B3A806227A28F9004BA588 /* Helpers */,
|
||||
F8025E5921F7861200ECF0C0 /* Root View Controller */,
|
||||
|
@ -2302,6 +2346,7 @@
|
|||
F8B3A814227DEA69004BA588 /* accessors */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D4FD899627772F9100689788 /* TreatmentEntryAccessor.swift */,
|
||||
F8B3A816227DEC91004BA588 /* AlertEntriesAccessor.swift */,
|
||||
F8B3A81A227DEC92004BA588 /* AlertTypesAccessor.swift */,
|
||||
F8B3A818227DEC92004BA588 /* BgReadingsAccessor.swift */,
|
||||
|
@ -2433,6 +2478,7 @@
|
|||
F82436FB24BE014000BED341 /* TextsLibreStates.swift */,
|
||||
F8E6C78F24CEC22A007C1199 /* TextsSnooze.swift */,
|
||||
F8A5EEB7257CF2940085E660 /* TextsLibreNFC.swift */,
|
||||
D400F8022778BD8000B57648 /* TextsTreatmentsView.swift */,
|
||||
);
|
||||
path = Texts;
|
||||
sourceTree = "<group>";
|
||||
|
@ -2625,6 +2671,8 @@
|
|||
F85FF3CC252F9FD7004E6FF1 /* SnoozeParameters+CoreDataProperties.swift */,
|
||||
F830991A23C2909E005741DF /* Watlaa+CoreDataClass.swift */,
|
||||
F830991B23C2909E005741DF /* Watlaa+CoreDataProperties.swift */,
|
||||
D40C3DA3277542C400111B73 /* TreatmentEntry+CoreDataClass.swift */,
|
||||
D40C3DA52775438F00111B73 /* TreatmentEntry+CoreDataProperties.swift */,
|
||||
);
|
||||
path = classes;
|
||||
sourceTree = "<group>";
|
||||
|
@ -3069,9 +3117,9 @@
|
|||
F8AC425221ADEBD60078C348 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
DefaultBuildSystemTypeForWorkspace = Latest;
|
||||
LastSwiftUpdateCheck = 1300;
|
||||
LastUpgradeCheck = 1200;
|
||||
DefaultBuildSystemTypeForWorkspace = Original;
|
||||
LastSwiftUpdateCheck = 1310;
|
||||
LastUpgradeCheck = 1310;
|
||||
ORGANIZATIONNAME = "Johan Degraeve";
|
||||
TargetAttributes = {
|
||||
470B6185270C448000561E56 = {
|
||||
|
@ -3237,7 +3285,6 @@
|
|||
F824379624CB7A9900BED341 /* Oringz.caf in Resources */,
|
||||
F824377D24CB7A9800BED341 /* Open_Your_Eyes_And_See.caf in Resources */,
|
||||
F82437A624CB7A9900BED341 /* Siri_Glucose_Rising_Fast.caf in Resources */,
|
||||
666E283A26F7E54C00ACE4DF /* xDrip.xcconfig in Resources */,
|
||||
F81F370825C1584A00520946 /* LibreStates.strings in Resources */,
|
||||
F82437B724CB7A9900BED341 /* Cartoon_Tip_Toe_Sneaky_Walk.caf in Resources */,
|
||||
F824379A24CB7A9900BED341 /* Siri_Alert_Device_Muted.caf in Resources */,
|
||||
|
@ -3285,9 +3332,9 @@
|
|||
F82437C824CB7A9900BED341 /* Siri_Alert_Missed_Readings.caf in Resources */,
|
||||
F821CF7D22A46CDD005C1E43 /* 1-millisecond-of-silence.mp3 in Resources */,
|
||||
F824377A24CB7A9800BED341 /* Sci-Fi_Spaceship_Message.caf in Resources */,
|
||||
D4AC54502778C82C0097FF10 /* Treatments.strings in Resources */,
|
||||
F824377124CB7A9800BED341 /* Indeed.caf in Resources */,
|
||||
F8B3A7CE226CC0B7004BA588 /* shorthigh2.mp3 in Resources */,
|
||||
666E283B26F7E54C00ACE4DF /* Version.xcconfig in Resources */,
|
||||
F82437D224CB7A9900BED341 /* Remembers_Me_Of_Asia.caf in Resources */,
|
||||
F824378F24CB7A9900BED341 /* Siri_Alert_Glucose_Rising_Fast.caf in Resources */,
|
||||
F824378A24CB7A9900BED341 /* Two_Turtle_Doves.caf in Resources */,
|
||||
|
@ -3401,6 +3448,7 @@
|
|||
F8F1670A2727317D001AA3D8 /* DexcomTransmitterTimeRxMessage.swift in Sources */,
|
||||
F8EA6C8221B723BC0082976B /* Date.swift in Sources */,
|
||||
F8E3A2A523D78FBD00E5E98A /* SettingsViewAppleWatchSettingsViewModel.swift in Sources */,
|
||||
D400F8032778BD8000B57648 /* TextsTreatmentsView.swift in Sources */,
|
||||
F81FA006228E09D40028C70F /* TextsCalibration.swift in Sources */,
|
||||
F816E0F724367137009EE65B /* GNSEntry+CoreDataClass.swift in Sources */,
|
||||
F8F9721923A5915900C3F17D /* CGMGNSEntryTransmitter.swift in Sources */,
|
||||
|
@ -3481,6 +3529,8 @@
|
|||
F80859292364D61B00F3829D /* UserDefaults+charts.swift in Sources */,
|
||||
F8B955B7258D5E2000C06016 /* ConstantsHealthKit.swift in Sources */,
|
||||
F8B3A7B2226A0878004BA588 /* TextsAlerts.swift in Sources */,
|
||||
D4BAF37627769B38009D3465 /* TreatmentTableViewCell.swift in Sources */,
|
||||
D40C3DA62775438F00111B73 /* TreatmentEntry+CoreDataProperties.swift in Sources */,
|
||||
F80D917024F85C7A006840B5 /* Libre2+BluetoothPeripheral.swift in Sources */,
|
||||
F8F9721423A5915900C3F17D /* AuthChallengeRxMessage.swift in Sources */,
|
||||
47B60F3726F389E2003198D3 /* LandscapeChartViewController.swift in Sources */,
|
||||
|
@ -3499,6 +3549,7 @@
|
|||
4752B4062635878E0081D551 /* SettingsViewStatisticsSettingsViewModel.swift in Sources */,
|
||||
F897AAF92200F2D200CDDD10 /* CBPeripheralState.swift in Sources */,
|
||||
F858CCED25AE4CD100786B91 /* LibreOOPWebError.swift in Sources */,
|
||||
D4FD899727772F9100689788 /* TreatmentEntryAccessor.swift in Sources */,
|
||||
F8F971B623A5914D00C3F17D /* M5Stack+BluetoothPeripheral.swift in Sources */,
|
||||
F830992323C291EE005741DF /* Watlaa+BluetoothPeripheral.swift in Sources */,
|
||||
F821CF57229BF43A005C1E43 /* SnoozeParameters.swift in Sources */,
|
||||
|
@ -3525,6 +3576,7 @@
|
|||
F8A1587322EDC893007F5B5D /* ConstantsDexcomShare.swift in Sources */,
|
||||
F8A1586F22EDC7EE007F5B5D /* ConstantsSuspensionPrevention.swift in Sources */,
|
||||
F8B3A82D227F07D6004BA588 /* SettingsNavigationController.swift in Sources */,
|
||||
D482BD942776153F003C4FB2 /* TreatmentsNavigationController.swift in Sources */,
|
||||
F80ED2EC236F68F90005C035 /* SettingsViewM5StackBluetoothSettingsViewModel.swift in Sources */,
|
||||
F8BECB05235CE5D80060DAE1 /* GlucoseChartManager.swift in Sources */,
|
||||
F8C97850242A9FD500A09483 /* MiaoMiaoBluetoothPeripheralViewModel.swift in Sources */,
|
||||
|
@ -3605,6 +3657,7 @@
|
|||
F80ED2ED236F68F90005C035 /* SettingsViewM5StackGeneralSettingsViewModel.swift in Sources */,
|
||||
F816E10A2437E7B8009EE65B /* CGMBlueReaderTransmitterDelegate.swift in Sources */,
|
||||
F8B3A850227F26F8004BA588 /* AlertTypesSettingsViewController.swift in Sources */,
|
||||
D484BC292774F783008490E9 /* TreatmentsInsertViewController.swift in Sources */,
|
||||
F816E0FE24367338009EE65B /* GNSEntry+BluetoothPeripheral.swift in Sources */,
|
||||
F8B3A808227A2933004BA588 /* SettingsSelectedRowAction.swift in Sources */,
|
||||
F8A5EEB2257CEC290085E660 /* LibreNFC.swift in Sources */,
|
||||
|
@ -3627,6 +3680,7 @@
|
|||
F8CB59C6273ECFE500BA199E /* DexcomG6GlucoseDataRxMessage.swift in Sources */,
|
||||
F81F9FFC2288C7530028C70F /* NewAlertSettingsViewController.swift in Sources */,
|
||||
F80D916524F5B3DE006840B5 /* Libre2+CoreDataClass.swift in Sources */,
|
||||
D4028CC02774A50600341476 /* TreatmentsViewController.swift in Sources */,
|
||||
F898EDF2234A8A0500BFB79B /* UInt8.swift in Sources */,
|
||||
F8DF766423E781C100063910 /* BLEPeripheralAccessor.swift in Sources */,
|
||||
F8F1671727288B24001AA3D8 /* DexcomSessionStopRxMessage.swift in Sources */,
|
||||
|
@ -3647,6 +3701,7 @@
|
|||
F821CF5F229BF43A005C1E43 /* ApplicationManager.swift in Sources */,
|
||||
F8B3A834227F08AC004BA588 /* PickerViewData.swift in Sources */,
|
||||
F8177025248ED4DE00AA3600 /* Libre1DerivedAlgorithmParameters.swift in Sources */,
|
||||
D40C3DA4277542C400111B73 /* TreatmentEntry+CoreDataClass.swift in Sources */,
|
||||
F808592D23677D6A00F3829D /* ChartPoint.swift in Sources */,
|
||||
F8A2BC0425DB093B001D1E78 /* Atom+CoreDataClass.swift in Sources */,
|
||||
F8F9722823A5915900C3F17D /* BluconUtilities.swift in Sources */,
|
||||
|
@ -3855,6 +3910,27 @@
|
|||
name = Main.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D4AC54412778C82B0097FF10 /* Treatments.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
D4AC54422778C82B0097FF10 /* en */,
|
||||
D4AC54432778C82B0097FF10 /* sl */,
|
||||
D4AC54442778C82B0097FF10 /* de */,
|
||||
D4AC54452778C82B0097FF10 /* sv */,
|
||||
D4AC54462778C82B0097FF10 /* es */,
|
||||
D4AC54472778C82B0097FF10 /* pt */,
|
||||
D4AC54482778C82B0097FF10 /* pl-PL */,
|
||||
D4AC54492778C82B0097FF10 /* ru */,
|
||||
D4AC544A2778C82B0097FF10 /* nl */,
|
||||
D4AC544B2778C82B0097FF10 /* fr */,
|
||||
D4AC544C2778C82B0097FF10 /* fi */,
|
||||
D4AC544D2778C82C0097FF10 /* zh */,
|
||||
D4AC544E2778C82C0097FF10 /* it */,
|
||||
D4AC544F2778C82C0097FF10 /* ar */,
|
||||
);
|
||||
name = Treatments.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F81F370525C1583400520946 /* WatlaaView.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
|
@ -4509,12 +4585,13 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_COMPILATION_MODE = singlefile;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
};
|
||||
name = Debug;
|
||||
|
@ -4567,7 +4644,7 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -4581,7 +4658,6 @@
|
|||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = FB1D964808BD308C74247D66 /* Pods-xdrip.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
APP_GROUP_IDENTIFIER = "group.com.${DEVELOPMENT_TEAM}.loopkit.LoopGroup";
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
|
@ -4610,7 +4686,6 @@
|
|||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 170A1629CB2C62ADD901F4A6 /* Pods-xdrip.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
APP_GROUP_IDENTIFIER = "group.com.${DEVELOPMENT_TEAM}.loopkit.LoopGroup";
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildSystemType</key>
|
||||
<string>Original</string>
|
||||
<key>PreviewsEnabled</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1300"
|
||||
LastUpgradeVersion = "1310"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -55,8 +55,10 @@
|
|||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES"
|
||||
launchAutomaticallySubstyle = "32">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<RemoteRunnable
|
||||
runnableDebuggingMode = "2"
|
||||
BundleIdentifier = "com.apple.Carousel"
|
||||
RemotePath = "/(null)">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "470B6185270C448000561E56"
|
||||
|
@ -64,7 +66,7 @@
|
|||
BlueprintName = "Watch App"
|
||||
ReferencedContainer = "container:xdrip.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</RemoteRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
|
@ -73,8 +75,10 @@
|
|||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
launchAutomaticallySubstyle = "32">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<RemoteRunnable
|
||||
runnableDebuggingMode = "2"
|
||||
BundleIdentifier = "com.apple.Carousel"
|
||||
RemotePath = "/(null)">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "470B6185270C448000561E56"
|
||||
|
@ -82,7 +86,16 @@
|
|||
BlueprintName = "Watch App"
|
||||
ReferencedContainer = "container:xdrip.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</RemoteRunnable>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "470B6185270C448000561E56"
|
||||
BuildableName = "xDrip4iO5.app"
|
||||
BlueprintName = "Watch App"
|
||||
ReferencedContainer = "container:xdrip.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1300"
|
||||
LastUpgradeVersion = "1310"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -54,8 +54,10 @@
|
|||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<RemoteRunnable
|
||||
runnableDebuggingMode = "2"
|
||||
BundleIdentifier = "com.apple.Carousel"
|
||||
RemotePath = "/(null)">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "470B6185270C448000561E56"
|
||||
|
@ -63,7 +65,7 @@
|
|||
BlueprintName = "Watch App"
|
||||
ReferencedContainer = "container:xdrip.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</RemoteRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
|
@ -71,8 +73,10 @@
|
|||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<RemoteRunnable
|
||||
runnableDebuggingMode = "2"
|
||||
BundleIdentifier = "com.apple.Carousel"
|
||||
RemotePath = "/(null)">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "470B6185270C448000561E56"
|
||||
|
@ -80,7 +84,16 @@
|
|||
BlueprintName = "Watch App"
|
||||
ReferencedContainer = "container:xdrip.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</RemoteRunnable>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "470B6185270C448000561E56"
|
||||
BuildableName = "xDrip4iO5.app"
|
||||
BlueprintName = "Watch App"
|
||||
ReferencedContainer = "container:xdrip.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1300"
|
||||
LastUpgradeVersion = "1310"
|
||||
wasCreatedForAppExtension = "YES"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
|
@ -74,7 +74,6 @@
|
|||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
askForAppToLaunch = "Yes"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1310"
|
||||
wasCreatedForAppExtension = "YES"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D4A2661B2773EB8300B60F2A"
|
||||
BuildableName = "xDripMultiWidgetExtension.appex"
|
||||
BlueprintName = "xDripMultiWidgetExtension"
|
||||
ReferencedContainer = "container:xdrip.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "F8AC425921ADEBD60078C348"
|
||||
BuildableName = "xdrip.app"
|
||||
BlueprintName = "xdrip"
|
||||
ReferencedContainer = "container:xdrip.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
launchStyle = "0"
|
||||
askForAppToLaunch = "Yes"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<RemoteRunnable
|
||||
runnableDebuggingMode = "2"
|
||||
BundleIdentifier = "com.apple.springboard">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "D4A2661B2773EB8300B60F2A"
|
||||
BuildableName = "xDripMultiWidgetExtension.appex"
|
||||
BlueprintName = "xDripMultiWidgetExtension"
|
||||
ReferencedContainer = "container:xdrip.xcodeproj">
|
||||
</BuildableReference>
|
||||
</RemoteRunnable>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "F8AC425921ADEBD60078C348"
|
||||
BuildableName = "xdrip.app"
|
||||
BlueprintName = "xdrip"
|
||||
ReferencedContainer = "container:xdrip.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<EnvironmentVariables>
|
||||
<EnvironmentVariable
|
||||
key = "_XCWidgetKind"
|
||||
value = ""
|
||||
isEnabled = "NO">
|
||||
</EnvironmentVariable>
|
||||
<EnvironmentVariable
|
||||
key = "_XCWidgetDefaultView"
|
||||
value = "timeline"
|
||||
isEnabled = "NO">
|
||||
</EnvironmentVariable>
|
||||
<EnvironmentVariable
|
||||
key = "_XCWidgetFamily"
|
||||
value = "medium"
|
||||
isEnabled = "NO">
|
||||
</EnvironmentVariable>
|
||||
</EnvironmentVariables>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "F8AC425921ADEBD60078C348"
|
||||
BuildableName = "xdrip.app"
|
||||
BlueprintName = "xdrip"
|
||||
ReferencedContainer = "container:xdrip.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1250"
|
||||
LastUpgradeVersion = "1310"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
@ -51,6 +51,9 @@ enum ConstantsLog {
|
|||
|
||||
/// application data bgreadings
|
||||
static let categoryApplicationDataBgReadings = "ApplicationDataBgReadings "
|
||||
|
||||
/// application data Treatments
|
||||
static let categoryApplicationDataTreatments = "ApplicationDataTreatments "
|
||||
|
||||
/// application data calibrations
|
||||
static let categoryApplicationDataCalibrations = "ApplicationDataCalibrations "
|
||||
|
|
|
@ -0,0 +1,206 @@
|
|||
//
|
||||
// TreatmentEntryAccessor.swift
|
||||
// xdrip
|
||||
//
|
||||
// Created by Eduardo Pietre on 24/12/21.
|
||||
// Copyright © 2021 Johan Degraeve. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
import os
|
||||
|
||||
|
||||
class TreatmentEntryAccessor {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
/// for logging
|
||||
private var log = OSLog(subsystem: ConstantsLog.subSystem, category: ConstantsLog.categoryApplicationDataTreatments)
|
||||
|
||||
/// CoreDataManager to use
|
||||
private let coreDataManager:CoreDataManager
|
||||
|
||||
// MARK: - initializer
|
||||
|
||||
init(coreDataManager:CoreDataManager) {
|
||||
self.coreDataManager = coreDataManager
|
||||
}
|
||||
|
||||
// MARK: - public functions
|
||||
|
||||
/// Gives the 50 latest treatments
|
||||
///
|
||||
/// - returns: an array with treatments, can be empty array.
|
||||
/// Order by timestamp, descending meaning the treatment at index 0 is the youngest
|
||||
func getLatestTreatments() -> [TreatmentEntry] {
|
||||
return getLatestTreatments(limit:50)
|
||||
}
|
||||
|
||||
/// Returns the treatments among the 50 latest
|
||||
/// that have not yet been uploaded
|
||||
///
|
||||
/// - returns: an array with treatments not uploaded, can be empty array.
|
||||
/// Order by timestamp, descending meaning the treatment at index 0 is the youngest
|
||||
func getRequireUploadTreatments() -> [TreatmentEntry] {
|
||||
// filter by not uploaded
|
||||
return getLatestTreatments().filter { treatment in
|
||||
return !treatment.uploaded
|
||||
}
|
||||
}
|
||||
|
||||
/// Gives latest treatments
|
||||
///
|
||||
/// - parameters:
|
||||
/// - limit : maximum amount of treatments to return, if nil then no limit in amount
|
||||
/// - returns: an array with treatments, can be empty array.
|
||||
/// Order by timestamp, descending meaning the treatment at index 0 is the youngest
|
||||
func getLatestTreatments(limit:Int) -> [TreatmentEntry] {
|
||||
return getLatestTreatments(limit:limit, howOld:nil)
|
||||
}
|
||||
|
||||
/// Gives treatments with maximumDays old
|
||||
///
|
||||
/// - parameters:
|
||||
/// - limit : maximum amount of treatments to return, if nil then no limit in amount
|
||||
/// - howOld : maximum age in days, it will calculate exacte (24 hours) * howOld, if nil then no limit in age
|
||||
/// - returns: an array with treatments, can be empty array.
|
||||
/// Order by timestamp, descending meaning the treatment at index 0 is the youngest
|
||||
func getLatestTreatments(limit:Int?, howOld:Int?) -> [TreatmentEntry] {
|
||||
|
||||
// if maximum age specified then create fromdate
|
||||
var fromDate:Date?
|
||||
if let howOld = howOld, howOld >= 0 {
|
||||
fromDate = Date(timeIntervalSinceNow: Double(-howOld * 60 * 60 * 24))
|
||||
}
|
||||
|
||||
return getLatestTreatments(limit: limit, fromDate: fromDate)
|
||||
}
|
||||
|
||||
/// Gives treatments with timestamp higher than fromDate
|
||||
///
|
||||
/// - parameters:
|
||||
/// - limit : maximum amount of treatments to return, if nil then no limit in amount
|
||||
/// - fromDate : treatment must have date > fromDate
|
||||
/// - returns: an array with treatments, can be empty array.
|
||||
/// Order by timestamp, descending meaning the treatment at index 0 is the youngest
|
||||
func getLatestTreatments(limit:Int?, fromDate:Date?) -> [TreatmentEntry] {
|
||||
|
||||
var returnValue:[TreatmentEntry] = []
|
||||
|
||||
let treatments = fetchTreatments(limit: limit, fromDate: fromDate)
|
||||
|
||||
loop: for (_, treatment) in treatments.enumerated() {
|
||||
returnValue.append(treatment)
|
||||
}
|
||||
|
||||
return returnValue
|
||||
}
|
||||
|
||||
/// gets last treatment
|
||||
func last() -> TreatmentEntry? {
|
||||
let treatments = getLatestTreatments(limit: 1, howOld: nil)
|
||||
if treatments.count > 0 {
|
||||
return treatments.last
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
/// gets treatments, synchronously, in the managedObjectContext's thread
|
||||
/// - returns:
|
||||
/// treatments sorted by timestamp, ascending (ie first is oldest)
|
||||
/// - parameters:
|
||||
/// - to : if specified, only return treatments with timestamp smaller than fromDate (not equal to)
|
||||
/// - from : if specified, only return treatments with timestamp greater than fromDate (not equal to)
|
||||
/// - managedObjectContext : the ManagedObjectContext to use
|
||||
func getTreatments(from: Date?, to: Date?, on managedObjectContext: NSManagedObjectContext) -> [TreatmentEntry] {
|
||||
|
||||
let fetchRequest: NSFetchRequest<TreatmentEntry> = TreatmentEntry.fetchRequest()
|
||||
fetchRequest.sortDescriptors = [NSSortDescriptor(key: #keyPath(TreatmentEntry.date), ascending: true)]
|
||||
|
||||
// create predicate
|
||||
if let from = from, to == nil {
|
||||
let predicate = NSPredicate(format: "date > %@", from as NSDate)
|
||||
fetchRequest.predicate = predicate
|
||||
} else if let to = to, from == nil {
|
||||
let predicate = NSPredicate(format: "date < %@", to as NSDate)
|
||||
fetchRequest.predicate = predicate
|
||||
} else if let to = to, let from = from {
|
||||
let predicate = NSPredicate(format: "date < %@ AND date > %@", to as CVarArg, from as NSDate)
|
||||
fetchRequest.predicate = predicate
|
||||
}
|
||||
|
||||
var treatments: [TreatmentEntry] = []
|
||||
|
||||
managedObjectContext.performAndWait {
|
||||
do {
|
||||
// Execute Fetch Request
|
||||
treatments = try fetchRequest.execute()
|
||||
} catch {
|
||||
let fetchError = error as NSError
|
||||
trace("in getTreatments, Unable to Execute BgReading Fetch Request : %{public}@", log: self.log, category: ConstantsLog.categoryApplicationDataTreatments, type: .error, fetchError.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
return treatments
|
||||
}
|
||||
|
||||
/// deletes treatmentEntry, synchronously, in the managedObjectContext's thread
|
||||
/// - treatmentEntry : treatmentEntry to delete
|
||||
/// - managedObjectContext : the ManagedObjectContext to use
|
||||
func delete(treatmentEntry: TreatmentEntry, on managedObjectContext: NSManagedObjectContext) {
|
||||
|
||||
managedObjectContext.performAndWait {
|
||||
|
||||
managedObjectContext.delete(treatmentEntry)
|
||||
|
||||
// save changes to coredata
|
||||
do {
|
||||
try managedObjectContext.save()
|
||||
} catch {
|
||||
trace("in delete bgReading, Unable to Save Changes, error.localizedDescription = %{public}@", log: self.log, category: ConstantsLog.categoryApplicationDataTreatments, type: .error, error.localizedDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - private helper functions
|
||||
|
||||
/// returnvalue can be empty array
|
||||
/// - parameters:
|
||||
/// - limit: maximum amount of treatments to fetch, if 0 then no limit
|
||||
/// - fromDate : if specified, only return readings with timestamp > fromDate
|
||||
/// - returns:
|
||||
/// List of treatments, descending, ie first is youngest
|
||||
private func fetchTreatments(limit:Int?, fromDate:Date?) -> [TreatmentEntry] {
|
||||
let fetchRequest: NSFetchRequest<TreatmentEntry> = TreatmentEntry.fetchRequest()
|
||||
fetchRequest.sortDescriptors = [NSSortDescriptor(key: #keyPath(TreatmentEntry.date), ascending: false)]
|
||||
|
||||
// if fromDate specified then create predicate
|
||||
if let fromDate = fromDate {
|
||||
let predicate = NSPredicate(format: "date > %@", fromDate as NSDate)
|
||||
fetchRequest.predicate = predicate
|
||||
}
|
||||
|
||||
// set fetchLimit
|
||||
if let limit = limit, limit >= 0 {
|
||||
fetchRequest.fetchLimit = limit
|
||||
}
|
||||
|
||||
var treatments: [TreatmentEntry] = []
|
||||
|
||||
coreDataManager.mainManagedObjectContext.performAndWait {
|
||||
do {
|
||||
// Execute Fetch Request
|
||||
treatments = try fetchRequest.execute()
|
||||
} catch {
|
||||
let fetchError = error as NSError
|
||||
trace("in fetchTreatments, Unable to Execute BgReading Fetch Request : %{public}@", log: self.log, category: ConstantsLog.categoryApplicationDataTreatments, type: .error, fetchError.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
return treatments
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
//
|
||||
// TreatmentEntry+CoreDataClass.swift
|
||||
// xdrip
|
||||
//
|
||||
// Created by Eduardo Pietre on 23/12/21.
|
||||
// Copyright © 2021 Johan Degraeve. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
|
||||
// @objc and Int16 allows enums to work with CoreData
|
||||
@objc public enum TreatmentType: Int16 {
|
||||
case Insulin
|
||||
case Carbs
|
||||
case Exercise
|
||||
|
||||
public func asString() -> String {
|
||||
switch self {
|
||||
case .Insulin:
|
||||
return "Insulin"
|
||||
case .Carbs:
|
||||
return "Carbs"
|
||||
case .Exercise:
|
||||
return "Exercise"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
public func unit() -> String {
|
||||
switch self {
|
||||
case .Insulin:
|
||||
return "u"
|
||||
case .Carbs:
|
||||
return "g"
|
||||
case .Exercise:
|
||||
return "min"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class TreatmentEntry: NSManagedObject {
|
||||
|
||||
init(date: Date, value: Double, treatmentType: TreatmentType, nsManagedObjectContext:NSManagedObjectContext) {
|
||||
|
||||
let entity = NSEntityDescription.entity(forEntityName: "TreatmentEntry", in: nsManagedObjectContext)!
|
||||
super.init(entity: entity, insertInto: nsManagedObjectContext)
|
||||
|
||||
self.date = date
|
||||
self.value = value
|
||||
self.treatmentType = treatmentType
|
||||
self.uploaded = false // tracks upload to nightscout
|
||||
}
|
||||
|
||||
private override init(entity: NSEntityDescription, insertInto context: NSManagedObjectContext?) {
|
||||
super.init(entity: entity, insertInto: context)
|
||||
}
|
||||
|
||||
public func displayValue() -> String {
|
||||
var string = String(self.value)
|
||||
// Checks prevents .0 from being displayed
|
||||
if string.suffix(2) == ".0" {
|
||||
string = String(string.dropLast(2))
|
||||
}
|
||||
return string + " " + self.treatmentType.unit()
|
||||
}
|
||||
|
||||
public func dictionaryRepresentationForNightScoutUpload() -> [String: Any] {
|
||||
var dict: [String: Any] = [
|
||||
"enteredBy": "xDrip4iOS",
|
||||
"eventTime": self.date.ISOStringFromDate(),
|
||||
]
|
||||
|
||||
switch self.treatmentType {
|
||||
case .Insulin:
|
||||
dict["eventType"] = "Correction Bolus"
|
||||
dict["insulin"] = self.value
|
||||
case .Carbs:
|
||||
dict["eventType"] = "Meal Bolus"
|
||||
dict["carbs"] = self.value
|
||||
case .Exercise:
|
||||
dict["eventType"] = "Exercise"
|
||||
dict["duration"] = self.value
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
return dict
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// TreatmentEntry+CoreDataProperties.swift
|
||||
// xdrip
|
||||
//
|
||||
// Created by Eduardo Pietre on 23/12/21.
|
||||
// Copyright © 2021 Johan Degraeve. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
|
||||
extension TreatmentEntry {
|
||||
|
||||
@nonobjc public class func fetchRequest() -> NSFetchRequest<TreatmentEntry> {
|
||||
return NSFetchRequest<TreatmentEntry>(entityName: "TreatmentEntry")
|
||||
}
|
||||
|
||||
@NSManaged public var date: Date
|
||||
|
||||
@NSManaged public var value: Double
|
||||
|
||||
@NSManaged public var treatmentType: TreatmentType
|
||||
|
||||
@NSManaged public var uploaded: Bool
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="19461" systemVersion="20G95" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="19461" systemVersion="21A559" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
|
||||
<entity name="AlertEntry" representedClassName=".AlertEntry" syncable="YES">
|
||||
<attribute name="alertkind" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="start" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
|
@ -153,6 +153,12 @@
|
|||
<attribute name="snoozePeriodInMinutes" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="snoozeTimeStamp" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
</entity>
|
||||
<entity name="TreatmentEntry" representedClassName=".TreatmentEntry" syncable="YES">
|
||||
<attribute name="date" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="treatmentType" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES"/>
|
||||
<attribute name="uploaded" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||
<attribute name="value" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
|
||||
</entity>
|
||||
<entity name="Watlaa" representedClassName=".Watlaa" syncable="YES">
|
||||
<attribute name="firmware" optional="YES" attributeType="String"/>
|
||||
<attribute name="hardware" optional="YES" attributeType="String"/>
|
||||
|
@ -177,6 +183,7 @@
|
|||
<element name="MiaoMiao" positionX="-657" positionY="189" width="128" height="88"/>
|
||||
<element name="Sensor" positionX="-603.0859375" positionY="482.2890625" width="128" height="133"/>
|
||||
<element name="SnoozeParameters" positionX="-648" positionY="198" width="128" height="28"/>
|
||||
<element name="TreatmentEntry" positionX="-657" positionY="189" width="128" height="89"/>
|
||||
<element name="Watlaa" positionX="-639" positionY="207" width="128" height="88"/>
|
||||
</elements>
|
||||
</model>
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
|
||||
public class LoopManager:NSObject {
|
||||
|
||||
// MARK: - private properties
|
||||
|
@ -88,7 +89,6 @@ public class LoopManager:NSObject {
|
|||
UserDefaults.standard.timeStampLatestLoopSharedBgReading = lastReadings.first!.timeStamp
|
||||
|
||||
UserDefaults.standard.readingsStoredInSharedUserDefaultsAsDictionary = dictionary
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,9 @@ public class NightScoutUploadManager:NSObject {
|
|||
|
||||
/// CalibrationsAccessor instance
|
||||
private let calibrationsAccessor: CalibrationsAccessor
|
||||
|
||||
/// TreatmentEntryAccessor
|
||||
private let treatmentEntryAccessor: TreatmentEntryAccessor
|
||||
|
||||
/// reference to coreDataManager
|
||||
private let coreDataManager: CoreDataManager
|
||||
|
@ -60,6 +63,7 @@ public class NightScoutUploadManager:NSObject {
|
|||
self.calibrationsAccessor = CalibrationsAccessor(coreDataManager: coreDataManager)
|
||||
self.messageHandler = messageHandler
|
||||
self.sensorsAccessor = SensorsAccessor(coreDataManager: coreDataManager)
|
||||
self.treatmentEntryAccessor = TreatmentEntryAccessor(coreDataManager: coreDataManager)
|
||||
|
||||
super.init()
|
||||
|
||||
|
@ -108,6 +112,9 @@ public class NightScoutUploadManager:NSObject {
|
|||
|
||||
// upload calibrations
|
||||
uploadCalibrationsToNightScout()
|
||||
|
||||
// upload treatments
|
||||
uploadTreatmentsToNightScout()
|
||||
|
||||
// upload activeSensor if needed
|
||||
if UserDefaults.standard.uploadSensorStartTimeToNS, let activeSensor = sensorsAccessor.fetchActiveSensor() {
|
||||
|
@ -348,6 +355,40 @@ public class NightScoutUploadManager:NSObject {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
/// upload treatments to nightscout
|
||||
/// Only checks recents ones
|
||||
public func uploadTreatmentsToNightScout() {
|
||||
trace("in uploadTreatmentsToNightScout", log: self.oslog, category: ConstantsLog.categoryNightScoutUploadManager, type: .info)
|
||||
|
||||
// get the latest treatments from the last maxDaysToUpload days
|
||||
// filter by those that have not been uploaded
|
||||
let treatments = treatmentEntryAccessor.getRequireUploadTreatments()
|
||||
|
||||
guard treatments.count > 0 else {
|
||||
trace(" no treatments to upload", log: self.oslog, category: ConstantsLog.categoryNightScoutUploadManager, type: .info)
|
||||
return
|
||||
}
|
||||
|
||||
trace(" number of treatments to upload : %{public}@", log: self.oslog, category: ConstantsLog.categoryNightScoutUploadManager, type: .info, treatments.count.description)
|
||||
|
||||
// map treatments to dictionaryRepresentation
|
||||
let treatmentsDictionaryRepresentation = treatments.map({$0.dictionaryRepresentationForNightScoutUpload()})
|
||||
|
||||
uploadData(dataToUpload: treatmentsDictionaryRepresentation, traceString: "uploadTreatmentsToNightScout", path: nightScoutTreatmentPath, completionHandler: {
|
||||
|
||||
// Be sure to use the correct thread.
|
||||
// Running in the completionHandler thread will
|
||||
// result in issues.
|
||||
self.coreDataManager.mainManagedObjectContext.performAndWait {
|
||||
for treatment in treatments {
|
||||
treatment.uploaded = true
|
||||
}
|
||||
|
||||
self.coreDataManager.saveChanges()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// upload latest calibrations to nightscout
|
||||
/// - parameters:
|
||||
|
|
|
@ -152,7 +152,125 @@
|
|||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="KZT-Nh-dNE" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-246" y="-891"/>
|
||||
<point key="canvasLocation" x="-566" y="-891"/>
|
||||
</scene>
|
||||
<!--Treatments Scene-->
|
||||
<scene sceneID="9ri-2S-eW8">
|
||||
<objects>
|
||||
<viewController title="Treatments Scene" interfaceStyle="dark" id="01q-Jv-AjA" customClass="TreatmentsViewController" customModule="xdrip" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="os0-CD-Pjv">
|
||||
<rect key="frame" x="0.0" y="0.0" width="390" height="844"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" estimatedSectionHeaderHeight="-1" sectionFooterHeight="28" estimatedSectionFooterHeight="-1" translatesAutoresizingMaskIntoConstraints="NO" id="XPB-uN-uCA">
|
||||
<rect key="frame" x="0.0" y="88" width="390" height="673"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="blue" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="TreatmentsCell" id="Gwu-WR-xta" customClass="TreatmentTableViewCell" customModule="xdrip" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="44.666666030883789" width="390" height="45"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Gwu-WR-xta" id="DBW-d4-0o5">
|
||||
<rect key="frame" x="0.0" y="0.0" width="390" height="45"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="3X4-8k-4dp">
|
||||
<rect key="frame" x="30" y="10" width="330" height="25"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="00:00" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JuE-mg-S0t">
|
||||
<rect key="frame" x="0.0" y="1.6666666666666661" width="110" height="21.666666666666671"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="18"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<color key="highlightedColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</label>
|
||||
<label opaque="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Insulin" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="U6e-jp-cms">
|
||||
<rect key="frame" x="110" y="1.6666666666666661" width="110" height="21.666666666666671"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="18"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<color key="highlightedColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="8u" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0na-qZ-kDB">
|
||||
<rect key="frame" x="220" y="1.6666666666666661" width="110" height="21.666666666666671"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="18"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<color key="highlightedColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="25" id="hTe-PH-KmG"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="3X4-8k-4dp" firstAttribute="top" secondItem="DBW-d4-0o5" secondAttribute="top" constant="10" id="7vl-wW-HHy"/>
|
||||
<constraint firstItem="3X4-8k-4dp" firstAttribute="leading" secondItem="DBW-d4-0o5" secondAttribute="leading" constant="30" id="Jqk-mh-mGZ"/>
|
||||
<constraint firstAttribute="bottom" secondItem="3X4-8k-4dp" secondAttribute="bottom" constant="10" id="hTk-XK-vN6"/>
|
||||
<constraint firstAttribute="trailing" secondItem="3X4-8k-4dp" secondAttribute="trailing" constant="30" id="m5c-aQ-ZYB"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<color key="backgroundColor" white="0.17999999999999999" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<connections>
|
||||
<outlet property="dateLabel" destination="JuE-mg-S0t" id="03N-y2-Umh"/>
|
||||
<outlet property="typeLabel" destination="U6e-jp-cms" id="uqQ-L0-k60"/>
|
||||
<outlet property="valueLabel" destination="0na-qZ-kDB" id="DRt-MD-law"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="01q-Jv-AjA" id="ZgA-8s-GVa"/>
|
||||
<outlet property="delegate" destination="01q-Jv-AjA" id="zLD-2f-MIF"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="l6g-XB-W8K"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="XPB-uN-uCA" firstAttribute="trailing" secondItem="l6g-XB-W8K" secondAttribute="trailing" id="4II-Lt-Jac"/>
|
||||
<constraint firstItem="XPB-uN-uCA" firstAttribute="leading" secondItem="l6g-XB-W8K" secondAttribute="leading" id="55U-5F-TZa"/>
|
||||
<constraint firstItem="XPB-uN-uCA" firstAttribute="centerX" secondItem="os0-CD-Pjv" secondAttribute="centerX" id="THx-wK-P5b"/>
|
||||
<constraint firstItem="XPB-uN-uCA" firstAttribute="bottom" secondItem="l6g-XB-W8K" secondAttribute="bottom" id="ktr-HH-FqK"/>
|
||||
<constraint firstItem="XPB-uN-uCA" firstAttribute="top" secondItem="l6g-XB-W8K" secondAttribute="top" id="vph-fE-Ppx"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<tabBarItem key="tabBarItem" title="Treatments" image="Home" id="EM7-TR-8Pt"/>
|
||||
<navigationItem key="navigationItem" title="Treatments" id="fUA-gv-91n">
|
||||
<barButtonItem key="leftBarButtonItem" image="arrow.clockwise.icloud" catalog="system" id="eLq-m9-bla">
|
||||
<color key="tintColor" red="0.96848052740000001" green="0.89723356880000005" blue="0.24125458929999999" alpha="1" colorSpace="custom" customColorSpace="displayP3"/>
|
||||
<connections>
|
||||
<action selector="syncButtonTapped:" destination="01q-Jv-AjA" id="EeF-H4-ZK3"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="add" id="iA1-b8-F3J">
|
||||
<color key="tintColor" systemColor="systemYellowColor"/>
|
||||
<connections>
|
||||
<segue destination="QgE-Gq-57r" kind="show" identifier="TreatmentsToNewTreatmentsSegue" id="iy5-gk-yrr"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="tableView" destination="XPB-uN-uCA" id="fV3-OR-Exz"/>
|
||||
<outlet property="titleNavigation" destination="fUA-gv-91n" id="b1y-Qh-HjD"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="IwV-Pn-lau" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1536.9230769230769" y="-1614.4549763033174"/>
|
||||
</scene>
|
||||
<!--Treatments-->
|
||||
<scene sceneID="WDM-MY-6pS">
|
||||
<objects>
|
||||
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="IdU-mY-C1M" customClass="TreatmentsNavigationController" customModule="xdrip" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tabBarItem key="tabBarItem" title="Treatments" image="pencil" catalog="system" id="Jgh-Nb-wg6"/>
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="Z4f-sX-pvq">
|
||||
<rect key="frame" x="0.0" y="44" width="390" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="01q-Jv-AjA" kind="relationship" relationship="rootViewController" id="TU7-Ve-5LG"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="KjZ-T8-3hn" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="745" y="-1614"/>
|
||||
</scene>
|
||||
<!--Home-->
|
||||
<scene sceneID="hNz-n2-bh7">
|
||||
|
@ -177,6 +295,7 @@
|
|||
<segue destination="NvR-Zh-2Zn" kind="show" identifier="RootViewToSnoozeView" id="VtQ-ZG-btn"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem style="plain" systemItem="flexibleSpace" id="8MU-0O-ujy"/>
|
||||
<barButtonItem style="plain" systemItem="flexibleSpace" id="uM8-jT-s3T"/>
|
||||
<barButtonItem title="Sensor" image="ellipsis.circle" catalog="system" id="ZIM-Wf-bUy">
|
||||
<connections>
|
||||
|
@ -190,17 +309,12 @@
|
|||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem style="plain" systemItem="flexibleSpace" id="SlH-A4-F18"/>
|
||||
<barButtonItem style="plain" systemItem="flexibleSpace" id="Bnf-FN-LqX"/>
|
||||
<barButtonItem title="Lock" image="lock" catalog="system" id="wfX-50-2w6">
|
||||
<connections>
|
||||
<action selector="screenLockToolbarButtonAction:" destination="9pv-A4-QxB" id="L14-hJ-4a9"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
<barButtonItem style="plain" systemItem="flexibleSpace" id="a6G-aW-JeE"/>
|
||||
<barButtonItem title="Help" image="questionmark.circle" catalog="system" id="DuN-xR-xYB">
|
||||
<connections>
|
||||
<action selector="helpToolbarButtonAction:" destination="9pv-A4-QxB" id="DGg-9c-TqQ"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</items>
|
||||
</toolbar>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="C16-NQ-F1Y">
|
||||
|
@ -603,7 +717,6 @@
|
|||
<outlet property="clockView" destination="ETk-QH-u1x" id="XuQ-dY-93L"/>
|
||||
<outlet property="cvTitleLabelOutlet" destination="PZI-Ln-kfh" id="IKV-zy-dNM"/>
|
||||
<outlet property="diffLabelOutlet" destination="7Wo-wd-80o" id="nnn-w9-1sX"/>
|
||||
<outlet property="helpToolbarButtonOutlet" destination="DuN-xR-xYB" id="TdW-5k-hgZ"/>
|
||||
<outlet property="highLabelOutlet" destination="Xlz-6g-zzD" id="DyX-x0-PwZ"/>
|
||||
<outlet property="highStatisticLabelOutlet" destination="EbR-T4-LIg" id="VZk-1K-BCq"/>
|
||||
<outlet property="highTitleLabelOutlet" destination="bUK-pC-4bd" id="R8q-Q6-q9d"/>
|
||||
|
@ -625,7 +738,6 @@
|
|||
<outlet property="sensorToolbarButtonOutlet" destination="ZIM-Wf-bUy" id="kjL-rX-6ZV"/>
|
||||
<outlet property="statisticsView" destination="MtJ-rx-OB9" id="u5w-qN-5Tq"/>
|
||||
<outlet property="timePeriodLabelOutlet" destination="On3-dy-RgB" id="hAe-Kx-vnM"/>
|
||||
<outlet property="toolbarOutlet" destination="tVG-ML-9xd" id="p1N-b3-pnD"/>
|
||||
<outlet property="valueLabelOutlet" destination="We3-bN-ffR" id="wtY-sZ-mev"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
|
@ -721,7 +833,7 @@
|
|||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="lDU-f7-mwF" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1753.8461538461538" y="-887.20379146919424"/>
|
||||
<point key="canvasLocation" x="1537" y="-891"/>
|
||||
</scene>
|
||||
<!--Picker View Controller-->
|
||||
<scene sceneID="6RW-Ef-2Hm">
|
||||
|
@ -803,7 +915,7 @@
|
|||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="HPe-YM-BbI" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-566" y="1268"/>
|
||||
<point key="canvasLocation" x="-566" y="1500"/>
|
||||
</scene>
|
||||
<!--Date Picker View Controller-->
|
||||
<scene sceneID="OeI-t1-GDw">
|
||||
|
@ -885,7 +997,7 @@
|
|||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="y9l-yM-uDB" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="183" y="1268"/>
|
||||
<point key="canvasLocation" x="403" y="1501"/>
|
||||
</scene>
|
||||
<!--Settings View Controller-->
|
||||
<scene sceneID="wg7-f3-ORb">
|
||||
|
@ -1569,13 +1681,14 @@
|
|||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<segue destination="9pv-A4-QxB" kind="relationship" relationship="viewControllers" id="u7Y-xg-7CH"/>
|
||||
<segue destination="FwD-2z-GTm" kind="relationship" relationship="viewControllers" id="aWk-QN-f3h"/>
|
||||
<segue destination="dyf-bd-1WE" kind="relationship" relationship="viewControllers" id="lzU-1b-eKA"/>
|
||||
<segue destination="IdU-mY-C1M" kind="relationship" relationship="viewControllers" id="zLS-NW-E1a"/>
|
||||
<segue destination="FwD-2z-GTm" kind="relationship" relationship="viewControllers" id="jP9-BP-Xv0"/>
|
||||
<segue destination="dyf-bd-1WE" kind="relationship" relationship="viewControllers" id="xge-N9-aEh"/>
|
||||
</connections>
|
||||
</tabBarController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="HuB-VB-40B" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-621" y="155"/>
|
||||
<point key="canvasLocation" x="-566" y="153"/>
|
||||
</scene>
|
||||
<!--Settings-->
|
||||
<scene sceneID="jbr-kK-p6W">
|
||||
|
@ -1712,17 +1825,149 @@
|
|||
</objects>
|
||||
<point key="canvasLocation" x="3973" y="581"/>
|
||||
</scene>
|
||||
<!--Treatments Insert Scene-->
|
||||
<scene sceneID="xQI-ZW-z6P">
|
||||
<objects>
|
||||
<viewController title="Treatments Insert Scene" id="QgE-Gq-57r" customClass="TreatmentsInsertViewController" customModule="xdrip" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="u0y-ki-EPd">
|
||||
<rect key="frame" x="0.0" y="0.0" width="390" height="844"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="40" translatesAutoresizingMaskIntoConstraints="NO" id="Ltu-UO-Ypa">
|
||||
<rect key="frame" x="35" y="219" width="320" height="406"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="24" translatesAutoresizingMaskIntoConstraints="NO" id="lph-Ca-ZpH">
|
||||
<rect key="frame" x="36" y="0.0" width="248" height="150"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="ZDj-72-yiq" userLabel="Carbs Stack">
|
||||
<rect key="frame" x="0.0" y="0.0" width="248" height="34"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Carbs (g):" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fvP-G8-Gxk">
|
||||
<rect key="frame" x="0.0" y="5.6666666666666572" width="140" height="23"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="140" id="XcQ-AC-RqE"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="19"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Amount" textAlignment="center" minimumFontSize="16" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="saY-fP-EEW">
|
||||
<rect key="frame" x="148" y="0.0" width="100" height="34"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="100" id="o92-Cd-7bP"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="20"/>
|
||||
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="numberPad" smartInsertDeleteType="no" smartQuotesType="no"/>
|
||||
</textField>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="4G8-c0-IhJ" userLabel="Insulin Stack">
|
||||
<rect key="frame" x="0.0" y="58" width="248" height="34"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Insulin (U):" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="agq-m8-HZ9">
|
||||
<rect key="frame" x="0.0" y="0.0" width="140" height="34"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="140" id="PIM-iN-dt1"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="19"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Amount" textAlignment="center" minimumFontSize="16" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="ggq-1D-Pj6">
|
||||
<rect key="frame" x="148" y="0.0" width="100" height="34"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="100" id="KId-Tf-1aj"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="20"/>
|
||||
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="numberPad" smartInsertDeleteType="no" smartQuotesType="no"/>
|
||||
</textField>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="OJv-t7-QLZ" userLabel="Exercise Stack">
|
||||
<rect key="frame" x="0.0" y="116" width="248" height="34"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Exercise (min):" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9tx-02-GXf">
|
||||
<rect key="frame" x="0.0" y="0.0" width="140" height="34"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="140" id="c4f-TH-tJq"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="19"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Amount" textAlignment="center" minimumFontSize="16" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="kl9-iM-MlH">
|
||||
<rect key="frame" x="148" y="0.0" width="100" height="34"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="100" id="1kf-sW-mbf"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="20"/>
|
||||
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="numberPad" smartInsertDeleteType="no" smartQuotesType="no"/>
|
||||
</textField>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<datePicker contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" datePickerMode="dateAndTime" minuteInterval="1" style="wheels" translatesAutoresizingMaskIntoConstraints="NO" id="M5l-qV-xjH">
|
||||
<rect key="frame" x="0.0" y="190" width="320" height="216"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="textColor">
|
||||
<color key="value" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="boolean" keyPath="highlightsToday" value="NO"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</datePicker>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="mwU-Tw-d7Q"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="Ltu-UO-Ypa" firstAttribute="centerX" secondItem="u0y-ki-EPd" secondAttribute="centerX" id="0AB-vn-joB"/>
|
||||
<constraint firstItem="Ltu-UO-Ypa" firstAttribute="centerY" secondItem="u0y-ki-EPd" secondAttribute="centerY" id="aQT-9v-5xe"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<tabBarItem key="tabBarItem" title="Treatments" image="Home" id="ucH-hI-fdv"/>
|
||||
<toolbarItems/>
|
||||
<navigationItem key="navigationItem" title="New Entry" id="nDn-qs-kKp">
|
||||
<barButtonItem key="rightBarButtonItem" systemItem="done" id="6Fh-ms-ugk">
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<connections>
|
||||
<action selector="doneButtonTapped:" destination="QgE-Gq-57r" id="pG7-65-6ae"/>
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<simulatedToolbarMetrics key="simulatedBottomBarMetrics"/>
|
||||
<connections>
|
||||
<outlet property="carbsLabel" destination="fvP-G8-Gxk" id="d2b-CN-IK4"/>
|
||||
<outlet property="carbsStackView" destination="ZDj-72-yiq" id="HEu-wA-BlI"/>
|
||||
<outlet property="carbsTextField" destination="saY-fP-EEW" id="4DV-cC-8cz"/>
|
||||
<outlet property="datePicker" destination="M5l-qV-xjH" id="itP-VQ-w6m"/>
|
||||
<outlet property="doneButton" destination="6Fh-ms-ugk" id="RiQ-MN-r0W"/>
|
||||
<outlet property="exerciseLabel" destination="9tx-02-GXf" id="GH5-oA-TX3"/>
|
||||
<outlet property="exerciseStackView" destination="OJv-t7-QLZ" id="kuw-Ef-fXa"/>
|
||||
<outlet property="exerciseTextField" destination="kl9-iM-MlH" id="hcJ-8j-9xT"/>
|
||||
<outlet property="insulinLabel" destination="agq-m8-HZ9" id="rx7-pv-7Yo"/>
|
||||
<outlet property="insulinStackView" destination="4G8-c0-IhJ" id="tao-kP-Rbv"/>
|
||||
<outlet property="insulinTextField" destination="ggq-1D-Pj6" id="eDP-Dz-C8Z"/>
|
||||
<outlet property="titleNavigation" destination="nDn-qs-kKp" id="OLC-l6-yUz"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="vCD-5v-swn" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2342" y="-1614"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="Bluetooth" width="30" height="30"/>
|
||||
<image name="Home" width="30" height="30"/>
|
||||
<image name="Settings" width="30" height="30"/>
|
||||
<image name="arrow.clockwise.icloud" catalog="system" width="128" height="88"/>
|
||||
<image name="chevron.backward" catalog="system" width="96" height="128"/>
|
||||
<image name="chevron.forward" catalog="system" width="96" height="128"/>
|
||||
<image name="ellipsis.circle" catalog="system" width="128" height="121"/>
|
||||
<image name="lock" catalog="system" width="128" height="128"/>
|
||||
<image name="moon.zzz" catalog="system" width="115" height="128"/>
|
||||
<image name="questionmark.circle" catalog="system" width="128" height="121"/>
|
||||
<image name="pencil" catalog="system" width="128" height="113"/>
|
||||
<image name="scope" catalog="system" width="128" height="122"/>
|
||||
<image name="sensor14_14_alt" width="390" height="14"/>
|
||||
<systemColor name="systemGrayColor">
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// Translation needed - remove this header after translation /////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
"treatments_title" = "Treatments";
|
||||
"treatments_new_button" = "New";
|
||||
"treatments_new_entry" = "New Entry";
|
||||
"treatments_carbs_with_unit" = "Carbs (g):";
|
||||
"treatments_insulin_with_unit" = "Insulin (U):";
|
||||
"treatments_exercise_with_unit" = "Exercise (min):";
|
|
@ -0,0 +1,10 @@
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// Translation needed - remove this header after translation /////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
"treatments_title" = "Treatments";
|
||||
"treatments_new_button" = "New";
|
||||
"treatments_new_entry" = "New Entry";
|
||||
"treatments_carbs_with_unit" = "Carbs (g):";
|
||||
"treatments_insulin_with_unit" = "Insulin (U):";
|
||||
"treatments_exercise_with_unit" = "Exercise (min):";
|
|
@ -0,0 +1,6 @@
|
|||
"treatments_title" = "Treatments";
|
||||
"treatments_new_button" = "New";
|
||||
"treatments_new_entry" = "New Entry";
|
||||
"treatments_carbs_with_unit" = "Carbs (g):";
|
||||
"treatments_insulin_with_unit" = "Insulin (U):";
|
||||
"treatments_exercise_with_unit" = "Exercise (min):";
|
|
@ -0,0 +1,10 @@
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// Translation needed - remove this header after translation /////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
"treatments_title" = "Treatments";
|
||||
"treatments_new_button" = "New";
|
||||
"treatments_new_entry" = "New Entry";
|
||||
"treatments_carbs_with_unit" = "Carbs (g):";
|
||||
"treatments_insulin_with_unit" = "Insulin (U):";
|
||||
"treatments_exercise_with_unit" = "Exercise (min):";
|
|
@ -0,0 +1,10 @@
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// Translation needed - remove this header after translation /////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
"treatments_title" = "Treatments";
|
||||
"treatments_new_button" = "New";
|
||||
"treatments_new_entry" = "New Entry";
|
||||
"treatments_carbs_with_unit" = "Carbs (g):";
|
||||
"treatments_insulin_with_unit" = "Insulin (U):";
|
||||
"treatments_exercise_with_unit" = "Exercise (min):";
|
|
@ -0,0 +1,10 @@
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// Translation needed - remove this header after translation /////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
"treatments_title" = "Treatments";
|
||||
"treatments_new_button" = "New";
|
||||
"treatments_new_entry" = "New Entry";
|
||||
"treatments_carbs_with_unit" = "Carbs (g):";
|
||||
"treatments_insulin_with_unit" = "Insulin (U):";
|
||||
"treatments_exercise_with_unit" = "Exercise (min):";
|
|
@ -0,0 +1,10 @@
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// Translation needed - remove this header after translation /////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
"treatments_title" = "Treatments";
|
||||
"treatments_new_button" = "New";
|
||||
"treatments_new_entry" = "New Entry";
|
||||
"treatments_carbs_with_unit" = "Carbs (g):";
|
||||
"treatments_insulin_with_unit" = "Insulin (U):";
|
||||
"treatments_exercise_with_unit" = "Exercise (min):";
|
|
@ -0,0 +1,10 @@
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// Translation needed - remove this header after translation /////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
"treatments_title" = "Treatments";
|
||||
"treatments_new_button" = "New";
|
||||
"treatments_new_entry" = "New Entry";
|
||||
"treatments_carbs_with_unit" = "Carbs (g):";
|
||||
"treatments_insulin_with_unit" = "Insulin (U):";
|
||||
"treatments_exercise_with_unit" = "Exercise (min):";
|
|
@ -0,0 +1,10 @@
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// Translation needed - remove this header after translation /////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
"treatments_title" = "Treatments";
|
||||
"treatments_new_button" = "New";
|
||||
"treatments_new_entry" = "New Entry";
|
||||
"treatments_carbs_with_unit" = "Carbs (g):";
|
||||
"treatments_insulin_with_unit" = "Insulin (U):";
|
||||
"treatments_exercise_with_unit" = "Exercise (min):";
|
|
@ -0,0 +1,10 @@
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// Translation needed - remove this header after translation /////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
"treatments_title" = "Treatments";
|
||||
"treatments_new_button" = "New";
|
||||
"treatments_new_entry" = "New Entry";
|
||||
"treatments_carbs_with_unit" = "Carbs (g):";
|
||||
"treatments_insulin_with_unit" = "Insulin (U):";
|
||||
"treatments_exercise_with_unit" = "Exercise (min):";
|
|
@ -0,0 +1,10 @@
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// Translation needed - remove this header after translation /////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
"treatments_title" = "Treatments";
|
||||
"treatments_new_button" = "New";
|
||||
"treatments_new_entry" = "New Entry";
|
||||
"treatments_carbs_with_unit" = "Carbs (g):";
|
||||
"treatments_insulin_with_unit" = "Insulin (U):";
|
||||
"treatments_exercise_with_unit" = "Exercise (min):";
|
|
@ -0,0 +1,10 @@
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// Translation needed - remove this header after translation /////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
"treatments_title" = "Treatments";
|
||||
"treatments_new_button" = "New";
|
||||
"treatments_new_entry" = "New Entry";
|
||||
"treatments_carbs_with_unit" = "Carbs (g):";
|
||||
"treatments_insulin_with_unit" = "Insulin (U):";
|
||||
"treatments_exercise_with_unit" = "Exercise (min):";
|
|
@ -0,0 +1,10 @@
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// Translation needed - remove this header after translation /////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
"treatments_title" = "Treatments";
|
||||
"treatments_new_button" = "New";
|
||||
"treatments_new_entry" = "New Entry";
|
||||
"treatments_carbs_with_unit" = "Carbs (g):";
|
||||
"treatments_insulin_with_unit" = "Insulin (U):";
|
||||
"treatments_exercise_with_unit" = "Exercise (min):";
|
|
@ -0,0 +1,10 @@
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///// Translation needed - remove this header after translation /////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
"treatments_title" = "Treatments";
|
||||
"treatments_new_button" = "New";
|
||||
"treatments_new_entry" = "New Entry";
|
||||
"treatments_carbs_with_unit" = "Carbs (g):";
|
||||
"treatments_insulin_with_unit" = "Insulin (U):";
|
||||
"treatments_exercise_with_unit" = "Exercise (min):";
|
|
@ -38,7 +38,10 @@
|
|||
<key>NFCReaderUsageDescription</key>
|
||||
<string>xDrip4iO5 uses NFC to scan Libre sensors.</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict/>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>NSBluetoothAlwaysUsageDescription</key>
|
||||
<string>Connect to CGM Transmitter and M5Stack</string>
|
||||
<key>NSBluetoothPeripheralUsageDescription</key>
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import Foundation
|
||||
|
||||
/// all texts related to treatmentss (2 views)
|
||||
enum Texts_TreatmentsView {
|
||||
static private let filename = "Treatments"
|
||||
|
||||
static let treatmentsTitle:String = {
|
||||
return NSLocalizedString("treatments_title", tableName: filename, bundle: Bundle.main, value: "Treatments", comment: "Title of treatments view.")
|
||||
}()
|
||||
|
||||
static let newButton:String = {
|
||||
return NSLocalizedString("treatments_new_button", tableName: filename, bundle: Bundle.main, value: "New", comment: "New button text.")
|
||||
}()
|
||||
|
||||
static let newEntryTitle:String = {
|
||||
return NSLocalizedString("treatments_new_entry", tableName: filename, bundle: Bundle.main, value: "New Entry", comment: "New entry view title.")
|
||||
}()
|
||||
|
||||
static let carbsWithUnit:String = {
|
||||
return NSLocalizedString("treatments_carbs_with_unit", tableName: filename, bundle: Bundle.main, value: "Carbs (g):", comment: "Carbs with unit.")
|
||||
}()
|
||||
|
||||
static let insulinWithUnit:String = {
|
||||
return NSLocalizedString("treatments_insulin_with_unit", tableName: filename, bundle: Bundle.main, value: "Insulin (U):", comment: "Insulin with unit.")
|
||||
}()
|
||||
|
||||
static let exerciseWithUnit:String = {
|
||||
return NSLocalizedString("treatments_exercise_with_unit", tableName: filename, bundle: Bundle.main, value: "Exercise (min):", comment: "Exercise with unit.")
|
||||
}()
|
||||
|
||||
}
|
|
@ -312,6 +312,9 @@ final class RootViewController: UIViewController {
|
|||
|
||||
/// CalibrationsAccessor instance
|
||||
private var calibrationsAccessor:CalibrationsAccessor?
|
||||
|
||||
/// TreatmentEntryAccessor instance
|
||||
private var treatmentEntryAccessor:TreatmentEntryAccessor?
|
||||
|
||||
/// NightScoutUploadManager instance
|
||||
private var nightScoutUploadManager:NightScoutUploadManager?
|
||||
|
@ -784,6 +787,8 @@ final class RootViewController: UIViewController {
|
|||
guard let bgReadingsAccessor = bgReadingsAccessor else {
|
||||
fatalError("In setupApplicationData, failed to initialize bgReadings")
|
||||
}
|
||||
|
||||
treatmentEntryAccessor = TreatmentEntryAccessor(coreDataManager: coreDataManager)
|
||||
|
||||
// instantiate calibrations
|
||||
calibrationsAccessor = CalibrationsAccessor(coreDataManager: coreDataManager)
|
||||
|
@ -2922,7 +2927,9 @@ extension RootViewController: UITabBarControllerDelegate {
|
|||
|
||||
navigationController.configure(coreDataManager: coreDataManager, bluetoothPeripheralManager: bluetoothPeripheralManager)
|
||||
|
||||
}
|
||||
} else if let navigationController = viewController as? TreatmentsNavigationController, let coreDataManager = coreDataManager, let nightScoutUploadManager = nightScoutUploadManager, let treatmentEntryAccessor = treatmentEntryAccessor {
|
||||
navigationController.configure(coreDataManager: coreDataManager, nightScoutUploadManager: nightScoutUploadManager, treatmentEntryAccessor: treatmentEntryAccessor)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// TreatmentTableViewCell.swift
|
||||
// xdrip
|
||||
//
|
||||
// Created by Eduardo Pietre on 24/12/21.
|
||||
// Copyright © 2021 Johan Degraeve. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class TreatmentTableViewCell: UITableViewCell {
|
||||
@IBOutlet weak var typeLabel: UILabel!
|
||||
@IBOutlet weak var valueLabel: UILabel!
|
||||
@IBOutlet weak var dateLabel: UILabel!
|
||||
|
||||
public func setupWithTreatment(_ treatment: TreatmentEntry) {
|
||||
self.typeLabel.text = treatment.treatmentType.asString()
|
||||
self.valueLabel.text = treatment.displayValue()
|
||||
|
||||
let formatter = DateFormatter()
|
||||
formatter.dateFormat = "dd/MM HH:mm"
|
||||
|
||||
self.dateLabel.text = formatter.string(from: treatment.date)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
//
|
||||
// TreatmentsInsertViewController.swift
|
||||
// xdrip
|
||||
//
|
||||
// Created by Eduardo Pietre on 23/12/21.
|
||||
// Copyright © 2021 Johan Degraeve. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
class TreatmentsInsertViewController : UIViewController {
|
||||
|
||||
@IBOutlet weak var titleLabel: UILabel!
|
||||
@IBOutlet weak var carbsLabel: UILabel!
|
||||
@IBOutlet weak var insulinLabel: UILabel!
|
||||
@IBOutlet weak var exerciseLabel: UILabel!
|
||||
@IBOutlet weak var cancelButton: UIButton!
|
||||
@IBOutlet weak var okButton: UIButton!
|
||||
@IBOutlet weak var datePicker: UIDatePicker!
|
||||
@IBOutlet weak var carbsTextField: UITextField!
|
||||
@IBOutlet weak var insulinTextField: UITextField!
|
||||
@IBOutlet weak var exerciseTextField: UITextField!
|
||||
|
||||
// MARK: - private properties
|
||||
/// reference to coreDataManager
|
||||
private var coreDataManager:CoreDataManager?
|
||||
|
||||
// handler to executed when user clicks actionButton
|
||||
private var entryHandler:((_ entries: [TreatmentEntry]) -> Void)?
|
||||
|
||||
/// handler to execute when user clicks cancelHandler
|
||||
private var cancelHandler:(() -> Void)?
|
||||
|
||||
// MARK: - overrides
|
||||
// set the status bar content colour to light to match new darker theme
|
||||
override var preferredStatusBarStyle: UIStatusBarStyle {
|
||||
return .lightContent
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
// Title
|
||||
self.titleLabel.text = Texts_TreatmentsView.newEntryTitle
|
||||
// Labels for each TextField
|
||||
self.carbsLabel.text = Texts_TreatmentsView.carbsWithUnit
|
||||
self.insulinLabel.text = Texts_TreatmentsView.insulinWithUnit
|
||||
self.exerciseLabel.text = Texts_TreatmentsView.exerciseWithUnit
|
||||
// Buttons
|
||||
self.cancelButton.setTitle(Texts_Common.Cancel, for: .normal)
|
||||
self.okButton.setTitle(Texts_Common.Ok, for: .normal)
|
||||
|
||||
self.addDoneButtonOnNumpad(textField: self.carbsTextField)
|
||||
self.addDoneButtonOnNumpad(textField: self.insulinTextField)
|
||||
self.addDoneButtonOnNumpad(textField: self.exerciseTextField)
|
||||
self.setDismissKeyboard()
|
||||
}
|
||||
|
||||
// MARK: - buttons actions
|
||||
|
||||
@IBAction func okButtonTapped(_ sender: UIButton) {
|
||||
guard let coreDataManager = coreDataManager, let entryHandler = entryHandler else {
|
||||
return
|
||||
}
|
||||
|
||||
var treatments: [TreatmentEntry] = []
|
||||
let date = datePicker.date
|
||||
|
||||
if let carbsText = carbsTextField.text, let carbs = Double(carbsText) {
|
||||
let treatment = TreatmentEntry(date: date, value: carbs, treatmentType: .Carbs, nsManagedObjectContext: coreDataManager.mainManagedObjectContext)
|
||||
treatments.append(treatment)
|
||||
}
|
||||
|
||||
if let insulinText = insulinTextField.text, let insulin = Double(insulinText) {
|
||||
let treatment = TreatmentEntry(date: date, value: insulin, treatmentType: .Insulin, nsManagedObjectContext: coreDataManager.mainManagedObjectContext)
|
||||
treatments.append(treatment)
|
||||
}
|
||||
|
||||
if let exerciseText = exerciseTextField.text, let exercise = Double(exerciseText) {
|
||||
let treatment = TreatmentEntry(date: date, value: exercise, treatmentType: .Exercise, nsManagedObjectContext: coreDataManager.mainManagedObjectContext)
|
||||
treatments.append(treatment)
|
||||
}
|
||||
|
||||
entryHandler(treatments)
|
||||
}
|
||||
|
||||
|
||||
@IBAction func cancelButtonTapped(_ sender: UIButton) {
|
||||
if let cancelHandler = cancelHandler {
|
||||
cancelHandler()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - public functions
|
||||
|
||||
public func configure(coreDataManager: CoreDataManager?, entryHandler: ((_ entries: [TreatmentEntry]) -> Void)?, cancelHandler:(() -> Void)?) {
|
||||
// initalize private properties
|
||||
self.coreDataManager = coreDataManager
|
||||
self.entryHandler = entryHandler
|
||||
self.cancelHandler = cancelHandler
|
||||
}
|
||||
|
||||
|
||||
// MARK: - private functions
|
||||
|
||||
private func addDoneButtonOnNumpad(textField: UITextField) {
|
||||
|
||||
let keypadToolbar: UIToolbar = UIToolbar()
|
||||
|
||||
// add a done button to the numberpad
|
||||
keypadToolbar.items = [
|
||||
UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: self, action: nil),
|
||||
UIBarButtonItem(title: Texts_Common.Ok, style: UIBarButtonItem.Style.done, target: textField, action: #selector(UITextField.resignFirstResponder))
|
||||
]
|
||||
keypadToolbar.sizeToFit()
|
||||
// add a toolbar with a done button above the number pad
|
||||
textField.inputAccessoryView = keypadToolbar
|
||||
} //addDoneToKeyPad
|
||||
|
||||
func setDismissKeyboard() {
|
||||
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboardTouchOutside))
|
||||
tap.cancelsTouchesInView = false
|
||||
view.addGestureRecognizer(tap)
|
||||
}
|
||||
|
||||
@objc private func dismissKeyboardTouchOutside() {
|
||||
view.endEditing(true)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
//
|
||||
// TreatmentsNavigationController.swift
|
||||
// xdrip
|
||||
//
|
||||
// Created by Eduardo Pietre on 24/12/21.
|
||||
// Copyright © 2021 Johan Degraeve. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
final class TreatmentsNavigationController: UINavigationController {
|
||||
|
||||
// set the status bar content colour to light to match new darker theme
|
||||
override var preferredStatusBarStyle: UIStatusBarStyle {
|
||||
return .lightContent
|
||||
}
|
||||
|
||||
// MARK: - private properties
|
||||
|
||||
/// reference to coreDataManager
|
||||
private var coreDataManager:CoreDataManager?
|
||||
|
||||
/// reference to nightScoutUploadManager
|
||||
private var nightScoutUploadManager: NightScoutUploadManager?
|
||||
|
||||
/// reference to treatmentEntryAccessor
|
||||
private var treatmentEntryAccessor: TreatmentEntryAccessor?
|
||||
|
||||
// MARK: - public functions
|
||||
|
||||
/// configure
|
||||
public func configure(coreDataManager: CoreDataManager, nightScoutUploadManager: NightScoutUploadManager, treatmentEntryAccessor: TreatmentEntryAccessor) {
|
||||
// initalize private properties
|
||||
self.coreDataManager = coreDataManager
|
||||
self.nightScoutUploadManager = nightScoutUploadManager
|
||||
self.treatmentEntryAccessor = treatmentEntryAccessor
|
||||
}
|
||||
|
||||
// MARK: - overrides
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
delegate = self
|
||||
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
|
||||
// remove titles from tabbar items
|
||||
self.tabBarController?.cleanTitles()
|
||||
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
|
||||
// restrict rotation of this Navigation Controller to just portrait
|
||||
(UIApplication.shared.delegate as! AppDelegate).restrictRotation = .portrait
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension TreatmentsNavigationController: UINavigationControllerDelegate {
|
||||
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
|
||||
|
||||
if let coreDataManager = coreDataManager, let nightScoutUploadManager = nightScoutUploadManager, let treatmentEntryAccessor = treatmentEntryAccessor, let treatmentsViewController = viewController as? TreatmentsViewController {
|
||||
treatmentsViewController.configure(coreDataManager: coreDataManager, nightScoutUploadManager: nightScoutUploadManager, treatmentEntryAccessor: treatmentEntryAccessor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
//
|
||||
// TreatmentsViewController.swift
|
||||
// xdrip
|
||||
//
|
||||
// Created by Eduardo Pietre on 23/12/21.
|
||||
// Copyright © 2021 Johan Degraeve. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
|
||||
class TreatmentsViewController : UIViewController {
|
||||
|
||||
// MARK: - private properties
|
||||
|
||||
// Will store the recent treatments to be displayed
|
||||
private var treatments: [TreatmentEntry] = []
|
||||
|
||||
/// reference to coreDataManager
|
||||
private var coreDataManager: CoreDataManager?
|
||||
|
||||
/// reference to nightScoutUploadManager
|
||||
private var nightScoutUploadManager: NightScoutUploadManager?
|
||||
|
||||
/// reference to treatmentEntryAccessor
|
||||
private var treatmentEntryAccessor: TreatmentEntryAccessor?
|
||||
|
||||
@IBOutlet weak var titleLabel: UILabel!
|
||||
@IBOutlet weak var newButton: UIButton!
|
||||
@IBOutlet weak var tableView: UITableView!
|
||||
|
||||
@IBAction func newButtonTapped(_ sender: UIButton) {
|
||||
self.presentTreatmentsInsert()
|
||||
}
|
||||
|
||||
@IBAction func uploadButtonTapped(_ sender: UIButton) {
|
||||
nightScoutUploadManager?.uploadTreatmentsToNightScout()
|
||||
let alert = UIAlertController(title: Texts_Common.Ok, message: Texts_Common.Ok, actionHandler: nil)
|
||||
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
self.titleLabel.text = Texts_TreatmentsView.treatmentsTitle
|
||||
self.newButton.setTitle(Texts_TreatmentsView.newButton, for: .normal)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - public functions
|
||||
|
||||
public func configure(coreDataManager: CoreDataManager, nightScoutUploadManager: NightScoutUploadManager, treatmentEntryAccessor: TreatmentEntryAccessor) {
|
||||
// initalize private properties
|
||||
self.coreDataManager = coreDataManager
|
||||
self.nightScoutUploadManager = nightScoutUploadManager
|
||||
self.treatmentEntryAccessor = treatmentEntryAccessor
|
||||
|
||||
self.reloadTreatments()
|
||||
self.tableView.reloadData()
|
||||
}
|
||||
|
||||
// MARK: - private functions
|
||||
|
||||
private func reloadTreatments() {
|
||||
guard let treatmentEntryAccessor = treatmentEntryAccessor else { return }
|
||||
self.treatments = treatmentEntryAccessor.getLatestTreatments()
|
||||
}
|
||||
|
||||
private func presentTreatmentsInsert() {
|
||||
let insertViewController = UIStoryboard.main.instantiateViewController(withIdentifier: "TreatmentsInsertViewController") as! TreatmentsInsertViewController
|
||||
insertViewController.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
|
||||
|
||||
let entryHandler = { (entries : [TreatmentEntry]) in
|
||||
self.coreDataManager?.saveChanges()
|
||||
insertViewController.dismiss(animated: true, completion: nil)
|
||||
self.reloadTreatments()
|
||||
self.tableView.reloadData()
|
||||
}
|
||||
|
||||
let cancelHandler = {
|
||||
insertViewController.dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
//configure insertViewController
|
||||
insertViewController.configure(coreDataManager: coreDataManager, entryHandler: entryHandler, cancelHandler: cancelHandler)
|
||||
|
||||
// present it
|
||||
self.present(insertViewController, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - UITableView related
|
||||
|
||||
extension TreatmentsViewController: UITableViewDelegate, UITableViewDataSource {
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return self.treatments.count
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: "TreatmentsCell", for: indexPath) as? TreatmentTableViewCell else {
|
||||
fatalError("Unexpected Table View Cell")
|
||||
}
|
||||
|
||||
let treatment = self.treatments[indexPath.row]
|
||||
cell.setupWithTreatment(treatment)
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
|
||||
if (editingStyle == .delete) {
|
||||
guard let treatmentEntryAccessor = treatmentEntryAccessor, let coreDataManager = coreDataManager else {
|
||||
return
|
||||
}
|
||||
let treatment = treatments[indexPath.row]
|
||||
|
||||
treatmentEntryAccessor.delete(treatmentEntry: treatment, on: coreDataManager.mainManagedObjectContext)
|
||||
|
||||
treatments.remove(at: indexPath.row)
|
||||
|
||||
self.reloadTreatments()
|
||||
self.tableView.reloadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue