diff --git a/.gitignore b/.gitignore index 033162007f..95e915d310 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ xcuserdata *.moved-aside *.xcuserstate *.xcscmblueprint +project.xcworkspace ## Obj-C/Swift specific *.hmap @@ -53,6 +54,7 @@ Carthage/Checkouts/ Carthage/Build/tvOS/ Carthage/Build/iOS/*.bcsymbolmap Carthage/Build/iOS/*.dSYM +Carthage/Build/watchOS/ # fastlane # diff --git a/Cartfile b/Cartfile index 4a75ddeb9a..ffaa9c09ce 100644 --- a/Cartfile +++ b/Cartfile @@ -1,7 +1,7 @@ -github "LoopKit/LoopKit" == 1.5.4 -github "LoopKit/xDripG5" ~> 0.8.1 +github "LoopKit/LoopKit" == 1.5.5 +github "LoopKit/CGMBLEKit" ~> 2.0 github "i-schuetz/SwiftCharts" == 0.6.1 github "mddub/dexcom-share-client-swift" == 0.4.1 github "mddub/G4ShareSpy" == 0.3.3 -github "ps2/rileylink_ios" == 1.2.2 +github "ps2/rileylink_ios" == 2.0.0 github "amplitude/Amplitude-iOS" ~> 3.8.5 diff --git a/Cartfile.resolved b/Cartfile.resolved index a01fd7cb58..d2ac7370e5 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,7 +1,7 @@ -github "LoopKit/LoopKit" "v1.5.4" -github "LoopKit/xDripG5" "v0.8.1" +github "LoopKit/CGMBLEKit" "v2.0" +github "LoopKit/LoopKit" "v1.5.5" github "amplitude/Amplitude-iOS" "v3.14.1" github "i-schuetz/SwiftCharts" "6b55a26a7b0b95e49202ddc1db5404702fce114f" github "mddub/G4ShareSpy" "v0.3.3" github "mddub/dexcom-share-client-swift" "v0.4.1" -github "ps2/rileylink_ios" "v1.2.2" +github "ps2/rileylink_ios" "v2.0.0" diff --git a/Carthage/Build/.CGMBLEKit.version b/Carthage/Build/.CGMBLEKit.version new file mode 100644 index 0000000000..1e31df3f4e --- /dev/null +++ b/Carthage/Build/.CGMBLEKit.version @@ -0,0 +1,21 @@ +{ + "Mac" : [ + + ], + "watchOS" : [ + { + "name" : "CGMBLEKit", + "hash" : "575d04bdf7c1104cf77670c7a4298307717595e99a187c613f6059a285e1b994" + } + ], + "tvOS" : [ + + ], + "commitish" : "v2.0", + "iOS" : [ + { + "name" : "CGMBLEKit", + "hash" : "406ed00637ad11854d93d89f6ad171b00e7a48a652475e3fa9bdcb4bc2f1698d" + } + ] +} \ No newline at end of file diff --git a/Carthage/Build/.LoopKit.version b/Carthage/Build/.LoopKit.version index 0f796e5934..1a53b51eee 100644 --- a/Carthage/Build/.LoopKit.version +++ b/Carthage/Build/.LoopKit.version @@ -8,23 +8,23 @@ "tvOS" : [ ], - "commitish" : "v1.5.4", + "commitish" : "v1.5.5", "iOS" : [ { "name" : "GlucoseKit", - "hash" : "6872d3a023296a5b44c4ebb0ab49b49bf092d7eb7db6e4c6a9c332ed26ab7961" + "hash" : "5dee38f5899972ffefc1bc5e1d45a7f569bd903f321f92ceff52c1426f27c9ac" }, { - "name" : "InsulinKit", - "hash" : "bb4d83e337d86acc75bbe1d1a626b6f91b980cd358c9c8ad08cfb111acb3888e" + "name" : "CarbKit", + "hash" : "95604f653082fd6f5d2353c368d22e5d55505e3728df7d65fd124ab40d8cf908" }, { "name" : "LoopKit", - "hash" : "38819d4f9f66502f6204e34ef975e0fe9058bbb187228e6e5a1235118b917bb5" + "hash" : "4bc51d30fcb5a4572948d3e555214eccf71fea63404e6f64cb011d5767d5242e" }, { - "name" : "CarbKit", - "hash" : "225db1ed41e23b4b917de34ae1f1aefc49e744a1ab4df0c1044fd0740a2eed83" + "name" : "InsulinKit", + "hash" : "c77e75c0e772386fc50e389cde14111b72978b54263690a5b7aea237b067c5a5" } ] } \ No newline at end of file diff --git a/Carthage/Build/.rileylink_ios.version b/Carthage/Build/.rileylink_ios.version index c10c1064d4..61db1ce0fe 100644 --- a/Carthage/Build/.rileylink_ios.version +++ b/Carthage/Build/.rileylink_ios.version @@ -3,32 +3,39 @@ ], "watchOS" : [ - + { + "name" : "RileyLinkBLEKit", + "hash" : "c94d79d1403870df4539dd531024d5b44333642f28d49f8e9f4e26fbad42fd7a" + } ], "tvOS" : [ ], - "commitish" : "v1.2.2", + "commitish" : "v2.0.0", "iOS" : [ { "name" : "Crypto", - "hash" : "3ed5243fb098cf37b22ba203d4f8b5c58c3f16bba7261d16299cf8b94dbd7da4" + "hash" : "03768a89eb61f55cc386ae4586048ae851d61373da6868aab905db2a2586efc7" }, { - "name" : "RileyLinkBLEKit", - "hash" : "76060aa5b24d392228a205419fa16071f25b038bdf824639c10c1233d2d6d5ce" + "name" : "RileyLinkKitUI", + "hash" : "dc1035fdadd445d12f383f01c10225b62aa7eca1f4da9016420d1835487628bb" + }, + { + "name" : "RileyLinkKit", + "hash" : "69fd21c5cd31ca8fe4611b01139780b1df32e71400a6fd91ebc865d85791b0a5" }, { "name" : "NightscoutUploadKit", - "hash" : "5b3fef0981d79029e869cd8baabdedc3005ca49d6b5217e4f88a8f8babfe4a0a" + "hash" : "d3fe0bc023a0a275dddec6bba616ff38239acf44ee71879e270a3f8690e4961d" }, { - "name" : "RileyLinkKit", - "hash" : "fd9e14cb041a25b00cb8c8bd4cc790b731587a28658331e52efdb116327b3afd" + "name" : "RileyLinkBLEKit", + "hash" : "a95573627d6ad9a853c620938e53e97d4c054553fde4af097a489038b020fd2f" }, { "name" : "MinimedKit", - "hash" : "31bd6963439b1b1213742e0065d064beeca8a5675967f69cc63d32af58758193" + "hash" : "c5f8ad60aea1a15646ed78afcb485435b55cb6e5b54d7d299d2415e5fa74cf38" } ] } \ No newline at end of file diff --git a/Carthage/Build/iOS/CGMBLEKit.framework/CGMBLEKit b/Carthage/Build/iOS/CGMBLEKit.framework/CGMBLEKit new file mode 100755 index 0000000000..9519695f4e Binary files /dev/null and b/Carthage/Build/iOS/CGMBLEKit.framework/CGMBLEKit differ diff --git a/Carthage/Build/iOS/xDripG5.framework/Headers/AESCrypt.h b/Carthage/Build/iOS/CGMBLEKit.framework/Headers/AESCrypt.h similarity index 100% rename from Carthage/Build/iOS/xDripG5.framework/Headers/AESCrypt.h rename to Carthage/Build/iOS/CGMBLEKit.framework/Headers/AESCrypt.h diff --git a/Carthage/Build/iOS/xDripG5.framework/Headers/xDripG5-Swift.h b/Carthage/Build/iOS/CGMBLEKit.framework/Headers/CGMBLEKit-Swift.h similarity index 97% rename from Carthage/Build/iOS/xDripG5.framework/Headers/xDripG5-Swift.h rename to Carthage/Build/iOS/CGMBLEKit.framework/Headers/CGMBLEKit-Swift.h index 77318c35c0..1d603aadfd 100644 --- a/Carthage/Build/iOS/xDripG5.framework/Headers/xDripG5-Swift.h +++ b/Carthage/Build/iOS/CGMBLEKit.framework/Headers/CGMBLEKit-Swift.h @@ -163,6 +163,7 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); # define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) #endif #if __has_feature(modules) +@import CoreBluetooth; @import HealthKit; #endif @@ -177,12 +178,16 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); #if __has_attribute(external_source_symbol) # pragma push_macro("any") # undef any -# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="xDripG5",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) +# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="CGMBLEKit",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) # pragma pop_macro("any") #endif + + + + #if __has_attribute(external_source_symbol) # pragma clang attribute pop #endif diff --git a/Carthage/Build/iOS/CGMBLEKit.framework/Headers/CGMBLEKit.h b/Carthage/Build/iOS/CGMBLEKit.framework/Headers/CGMBLEKit.h new file mode 100644 index 0000000000..49882cc8ea --- /dev/null +++ b/Carthage/Build/iOS/CGMBLEKit.framework/Headers/CGMBLEKit.h @@ -0,0 +1,17 @@ +// +// CGMBLEKit.h +// xDripG5 +// +// Created by Nathan Racklyeft on 12/30/15. +// Copyright © 2015 Nathan Racklyeft. All rights reserved. +// + +#import +#import + +//! Project version number for CGMBLEKIt. +FOUNDATION_EXPORT double CGMBLEKitVersionNumber; + +//! Project version string for CGMBLEKit. +FOUNDATION_EXPORT const unsigned char CGMBLEKitVersionString[]; + diff --git a/Carthage/Build/iOS/xDripG5.framework/Info.plist b/Carthage/Build/iOS/CGMBLEKit.framework/Info.plist similarity index 54% rename from Carthage/Build/iOS/xDripG5.framework/Info.plist rename to Carthage/Build/iOS/CGMBLEKit.framework/Info.plist index af6f2803b8..3dba5d77bb 100644 Binary files a/Carthage/Build/iOS/xDripG5.framework/Info.plist and b/Carthage/Build/iOS/CGMBLEKit.framework/Info.plist differ diff --git a/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/arm.swiftdoc b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/arm.swiftdoc new file mode 100644 index 0000000000..79d030817a Binary files /dev/null and b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/arm.swiftdoc differ diff --git a/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/arm.swiftmodule b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/arm.swiftmodule new file mode 100644 index 0000000000..6428b30f47 Binary files /dev/null and b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/arm.swiftmodule differ diff --git a/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/arm64.swiftdoc b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/arm64.swiftdoc new file mode 100644 index 0000000000..3da9a2567d Binary files /dev/null and b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/arm64.swiftdoc differ diff --git a/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/arm64.swiftmodule b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/arm64.swiftmodule new file mode 100644 index 0000000000..9708db49d7 Binary files /dev/null and b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/arm64.swiftmodule differ diff --git a/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/i386.swiftdoc b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/i386.swiftdoc new file mode 100644 index 0000000000..b33ef2b6a7 Binary files /dev/null and b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/i386.swiftdoc differ diff --git a/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/i386.swiftmodule b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/i386.swiftmodule new file mode 100644 index 0000000000..80d2e01314 Binary files /dev/null and b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/i386.swiftmodule differ diff --git a/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/x86_64.swiftdoc b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/x86_64.swiftdoc new file mode 100644 index 0000000000..2e9075905d Binary files /dev/null and b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/x86_64.swiftdoc differ diff --git a/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/x86_64.swiftmodule b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/x86_64.swiftmodule new file mode 100644 index 0000000000..9e5bf26a39 Binary files /dev/null and b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/CGMBLEKit.swiftmodule/x86_64.swiftmodule differ diff --git a/Carthage/Build/iOS/CGMBLEKit.framework/Modules/module.modulemap b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/module.modulemap new file mode 100644 index 0000000000..64bb2572ba --- /dev/null +++ b/Carthage/Build/iOS/CGMBLEKit.framework/Modules/module.modulemap @@ -0,0 +1,11 @@ +framework module CGMBLEKit { + umbrella header "CGMBLEKit.h" + + export * + module * { export * } +} + +module CGMBLEKit.Swift { + header "CGMBLEKit-Swift.h" + requires objc +} diff --git a/Carthage/Build/iOS/CarbKit.framework/Assets.car b/Carthage/Build/iOS/CarbKit.framework/Assets.car index 9e901b46e4..b17646a739 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/Assets.car and b/Carthage/Build/iOS/CarbKit.framework/Assets.car differ diff --git a/Carthage/Build/iOS/CarbKit.framework/CarbKit b/Carthage/Build/iOS/CarbKit.framework/CarbKit index 3bdf18494d..ee75d0741d 100755 Binary files a/Carthage/Build/iOS/CarbKit.framework/CarbKit and b/Carthage/Build/iOS/CarbKit.framework/CarbKit differ diff --git a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbAbsorptionInputController.nib/objects-11.0+.nib b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbAbsorptionInputController.nib/objects-11.0+.nib index 6eb798ce25..f80a62e453 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbAbsorptionInputController.nib/objects-11.0+.nib and b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbAbsorptionInputController.nib/objects-11.0+.nib differ diff --git a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbAbsorptionInputController.nib/runtime.nib b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbAbsorptionInputController.nib/runtime.nib index 2e1c46f414..0c2c7d2ff2 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbAbsorptionInputController.nib/runtime.nib and b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbAbsorptionInputController.nib/runtime.nib differ diff --git a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbEntryEditViewController.nib/objects-11.0+.nib b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbEntryEditViewController.nib/objects-11.0+.nib index 8b28d5d82b..9deba38ef7 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbEntryEditViewController.nib/objects-11.0+.nib and b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbEntryEditViewController.nib/objects-11.0+.nib differ diff --git a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbEntryEditViewController.nib/runtime.nib b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbEntryEditViewController.nib/runtime.nib index b64d0ac292..62247aa8a6 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbEntryEditViewController.nib/runtime.nib and b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbEntryEditViewController.nib/runtime.nib differ diff --git a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbEntryTableViewController.nib/objects-11.0+.nib b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbEntryTableViewController.nib/objects-11.0+.nib index f33274fc34..5fa8d7081b 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbEntryTableViewController.nib/objects-11.0+.nib and b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbEntryTableViewController.nib/objects-11.0+.nib differ diff --git a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbEntryTableViewController.nib/runtime.nib b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbEntryTableViewController.nib/runtime.nib index 6dc55a1874..8b3c9de308 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbEntryTableViewController.nib/runtime.nib and b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/CarbEntryTableViewController.nib/runtime.nib differ diff --git a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/LyL-9U-twn-view-9Ci-XW-6nA.nib/objects-11.0+.nib b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/LyL-9U-twn-view-9Ci-XW-6nA.nib/objects-11.0+.nib index a6deba1df0..4d22452758 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/LyL-9U-twn-view-9Ci-XW-6nA.nib/objects-11.0+.nib and b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/LyL-9U-twn-view-9Ci-XW-6nA.nib/objects-11.0+.nib differ diff --git a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/LyL-9U-twn-view-9Ci-XW-6nA.nib/runtime.nib b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/LyL-9U-twn-view-9Ci-XW-6nA.nib/runtime.nib index 857f1967cc..36ed7e85de 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/LyL-9U-twn-view-9Ci-XW-6nA.nib/runtime.nib and b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/LyL-9U-twn-view-9Ci-XW-6nA.nib/runtime.nib differ diff --git a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/QAc-uE-L5K-view-ZAF-8o-e2g.nib/objects-11.0+.nib b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/QAc-uE-L5K-view-ZAF-8o-e2g.nib/objects-11.0+.nib index 24d69c0803..3839c9772e 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/QAc-uE-L5K-view-ZAF-8o-e2g.nib/objects-11.0+.nib and b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/QAc-uE-L5K-view-ZAF-8o-e2g.nib/objects-11.0+.nib differ diff --git a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/QAc-uE-L5K-view-ZAF-8o-e2g.nib/runtime.nib b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/QAc-uE-L5K-view-ZAF-8o-e2g.nib/runtime.nib index 9d297dc637..d02ce35167 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/QAc-uE-L5K-view-ZAF-8o-e2g.nib/runtime.nib and b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/QAc-uE-L5K-view-ZAF-8o-e2g.nib/runtime.nib differ diff --git a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/UINavigationController-wgu-gT-TgV.nib/objects-11.0+.nib b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/UINavigationController-wgu-gT-TgV.nib/objects-11.0+.nib index 0c75447f43..56c71fb4c4 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/UINavigationController-wgu-gT-TgV.nib/objects-11.0+.nib and b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/UINavigationController-wgu-gT-TgV.nib/objects-11.0+.nib differ diff --git a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/UINavigationController-wgu-gT-TgV.nib/runtime.nib b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/UINavigationController-wgu-gT-TgV.nib/runtime.nib index d396354528..8b20734e21 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/UINavigationController-wgu-gT-TgV.nib/runtime.nib and b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/UINavigationController-wgu-gT-TgV.nib/runtime.nib differ diff --git a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/rUL-yg-cFX-view-b1s-8o-0Wp.nib/objects-11.0+.nib b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/rUL-yg-cFX-view-b1s-8o-0Wp.nib/objects-11.0+.nib index a89444b67b..7bdbd52956 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/rUL-yg-cFX-view-b1s-8o-0Wp.nib/objects-11.0+.nib and b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/rUL-yg-cFX-view-b1s-8o-0Wp.nib/objects-11.0+.nib differ diff --git a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/rUL-yg-cFX-view-b1s-8o-0Wp.nib/runtime.nib b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/rUL-yg-cFX-view-b1s-8o-0Wp.nib/runtime.nib index ff5c03d4b2..74324c3c45 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/rUL-yg-cFX-view-b1s-8o-0Wp.nib/runtime.nib and b/Carthage/Build/iOS/CarbKit.framework/CarbKit.storyboardc/rUL-yg-cFX-view-b1s-8o-0Wp.nib/runtime.nib differ diff --git a/Carthage/Build/iOS/CarbKit.framework/DatePickerTableViewCell.nib b/Carthage/Build/iOS/CarbKit.framework/DatePickerTableViewCell.nib index a9b4d481a9..943e9a8145 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/DatePickerTableViewCell.nib and b/Carthage/Build/iOS/CarbKit.framework/DatePickerTableViewCell.nib differ diff --git a/Carthage/Build/iOS/CarbKit.framework/Info.plist b/Carthage/Build/iOS/CarbKit.framework/Info.plist index 47db337e62..69297b53a1 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/Info.plist and b/Carthage/Build/iOS/CarbKit.framework/Info.plist differ diff --git a/Carthage/Build/iOS/CarbKit.framework/Modules/CarbKit.swiftmodule/arm.swiftmodule b/Carthage/Build/iOS/CarbKit.framework/Modules/CarbKit.swiftmodule/arm.swiftmodule index 8ca4b264da..88348cb44e 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/Modules/CarbKit.swiftmodule/arm.swiftmodule and b/Carthage/Build/iOS/CarbKit.framework/Modules/CarbKit.swiftmodule/arm.swiftmodule differ diff --git a/Carthage/Build/iOS/CarbKit.framework/Modules/CarbKit.swiftmodule/arm64.swiftmodule b/Carthage/Build/iOS/CarbKit.framework/Modules/CarbKit.swiftmodule/arm64.swiftmodule index 0ba1c9654d..2d5ff4f7bd 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/Modules/CarbKit.swiftmodule/arm64.swiftmodule and b/Carthage/Build/iOS/CarbKit.framework/Modules/CarbKit.swiftmodule/arm64.swiftmodule differ diff --git a/Carthage/Build/iOS/CarbKit.framework/Modules/CarbKit.swiftmodule/i386.swiftmodule b/Carthage/Build/iOS/CarbKit.framework/Modules/CarbKit.swiftmodule/i386.swiftmodule index ba4cd1d285..0f1914a473 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/Modules/CarbKit.swiftmodule/i386.swiftmodule and b/Carthage/Build/iOS/CarbKit.framework/Modules/CarbKit.swiftmodule/i386.swiftmodule differ diff --git a/Carthage/Build/iOS/CarbKit.framework/Modules/CarbKit.swiftmodule/x86_64.swiftmodule b/Carthage/Build/iOS/CarbKit.framework/Modules/CarbKit.swiftmodule/x86_64.swiftmodule index 706c35b941..ffdcbbc761 100644 Binary files a/Carthage/Build/iOS/CarbKit.framework/Modules/CarbKit.swiftmodule/x86_64.swiftmodule and b/Carthage/Build/iOS/CarbKit.framework/Modules/CarbKit.swiftmodule/x86_64.swiftmodule differ diff --git a/Carthage/Build/iOS/Crypto.framework/Crypto b/Carthage/Build/iOS/Crypto.framework/Crypto index ba732bb8b2..3e1d7d6d30 100755 Binary files a/Carthage/Build/iOS/Crypto.framework/Crypto and b/Carthage/Build/iOS/Crypto.framework/Crypto differ diff --git a/Carthage/Build/iOS/Crypto.framework/Info.plist b/Carthage/Build/iOS/Crypto.framework/Info.plist index f33da39604..966cd811ab 100644 Binary files a/Carthage/Build/iOS/Crypto.framework/Info.plist and b/Carthage/Build/iOS/Crypto.framework/Info.plist differ diff --git a/Carthage/Build/iOS/Crypto.framework/es.lproj/InfoPlist.strings b/Carthage/Build/iOS/Crypto.framework/es.lproj/InfoPlist.strings new file mode 100644 index 0000000000..1ee4318d4f Binary files /dev/null and b/Carthage/Build/iOS/Crypto.framework/es.lproj/InfoPlist.strings differ diff --git a/Carthage/Build/iOS/Crypto.framework/ru.lproj/InfoPlist.strings b/Carthage/Build/iOS/Crypto.framework/ru.lproj/InfoPlist.strings new file mode 100644 index 0000000000..3967e063f9 Binary files /dev/null and b/Carthage/Build/iOS/Crypto.framework/ru.lproj/InfoPlist.strings differ diff --git a/Carthage/Build/iOS/GlucoseKit.framework/GlucoseKit b/Carthage/Build/iOS/GlucoseKit.framework/GlucoseKit index 16e7efb66c..81f7ab0846 100755 Binary files a/Carthage/Build/iOS/GlucoseKit.framework/GlucoseKit and b/Carthage/Build/iOS/GlucoseKit.framework/GlucoseKit differ diff --git a/Carthage/Build/iOS/GlucoseKit.framework/Info.plist b/Carthage/Build/iOS/GlucoseKit.framework/Info.plist index a47b64ec12..e9c0f8bf45 100644 Binary files a/Carthage/Build/iOS/GlucoseKit.framework/Info.plist and b/Carthage/Build/iOS/GlucoseKit.framework/Info.plist differ diff --git a/Carthage/Build/iOS/GlucoseKit.framework/Modules/GlucoseKit.swiftmodule/arm.swiftmodule b/Carthage/Build/iOS/GlucoseKit.framework/Modules/GlucoseKit.swiftmodule/arm.swiftmodule index 6c4c0bb23f..0f122494f0 100644 Binary files a/Carthage/Build/iOS/GlucoseKit.framework/Modules/GlucoseKit.swiftmodule/arm.swiftmodule and b/Carthage/Build/iOS/GlucoseKit.framework/Modules/GlucoseKit.swiftmodule/arm.swiftmodule differ diff --git a/Carthage/Build/iOS/GlucoseKit.framework/Modules/GlucoseKit.swiftmodule/arm64.swiftmodule b/Carthage/Build/iOS/GlucoseKit.framework/Modules/GlucoseKit.swiftmodule/arm64.swiftmodule index ff22f6beb2..cb4b4b9d85 100644 Binary files a/Carthage/Build/iOS/GlucoseKit.framework/Modules/GlucoseKit.swiftmodule/arm64.swiftmodule and b/Carthage/Build/iOS/GlucoseKit.framework/Modules/GlucoseKit.swiftmodule/arm64.swiftmodule differ diff --git a/Carthage/Build/iOS/GlucoseKit.framework/Modules/GlucoseKit.swiftmodule/i386.swiftmodule b/Carthage/Build/iOS/GlucoseKit.framework/Modules/GlucoseKit.swiftmodule/i386.swiftmodule index 7dae6860ae..e13cce12de 100644 Binary files a/Carthage/Build/iOS/GlucoseKit.framework/Modules/GlucoseKit.swiftmodule/i386.swiftmodule and b/Carthage/Build/iOS/GlucoseKit.framework/Modules/GlucoseKit.swiftmodule/i386.swiftmodule differ diff --git a/Carthage/Build/iOS/GlucoseKit.framework/Modules/GlucoseKit.swiftmodule/x86_64.swiftmodule b/Carthage/Build/iOS/GlucoseKit.framework/Modules/GlucoseKit.swiftmodule/x86_64.swiftmodule index b1db443efa..1fabc078dc 100644 Binary files a/Carthage/Build/iOS/GlucoseKit.framework/Modules/GlucoseKit.swiftmodule/x86_64.swiftmodule and b/Carthage/Build/iOS/GlucoseKit.framework/Modules/GlucoseKit.swiftmodule/x86_64.swiftmodule differ diff --git a/Carthage/Build/iOS/InsulinKit.framework/Base.lproj/InsulinKit.storyboardc/UITableViewController-jGX-GA-nlH.nib b/Carthage/Build/iOS/InsulinKit.framework/Base.lproj/InsulinKit.storyboardc/UITableViewController-jGX-GA-nlH.nib index a883e95304..49e3f94c38 100644 Binary files a/Carthage/Build/iOS/InsulinKit.framework/Base.lproj/InsulinKit.storyboardc/UITableViewController-jGX-GA-nlH.nib and b/Carthage/Build/iOS/InsulinKit.framework/Base.lproj/InsulinKit.storyboardc/UITableViewController-jGX-GA-nlH.nib differ diff --git a/Carthage/Build/iOS/InsulinKit.framework/Base.lproj/InsulinKit.storyboardc/jGX-GA-nlH-view-ccM-3y-LQM.nib b/Carthage/Build/iOS/InsulinKit.framework/Base.lproj/InsulinKit.storyboardc/jGX-GA-nlH-view-ccM-3y-LQM.nib index 14153d5b4f..230228aa02 100644 Binary files a/Carthage/Build/iOS/InsulinKit.framework/Base.lproj/InsulinKit.storyboardc/jGX-GA-nlH-view-ccM-3y-LQM.nib and b/Carthage/Build/iOS/InsulinKit.framework/Base.lproj/InsulinKit.storyboardc/jGX-GA-nlH-view-ccM-3y-LQM.nib differ diff --git a/Carthage/Build/iOS/InsulinKit.framework/Info.plist b/Carthage/Build/iOS/InsulinKit.framework/Info.plist index a645edfd9a..c1f5686ff6 100644 Binary files a/Carthage/Build/iOS/InsulinKit.framework/Info.plist and b/Carthage/Build/iOS/InsulinKit.framework/Info.plist differ diff --git a/Carthage/Build/iOS/InsulinKit.framework/InsulinKit b/Carthage/Build/iOS/InsulinKit.framework/InsulinKit index 1a3a4a2bcc..663286ab56 100755 Binary files a/Carthage/Build/iOS/InsulinKit.framework/InsulinKit and b/Carthage/Build/iOS/InsulinKit.framework/InsulinKit differ diff --git a/Carthage/Build/iOS/InsulinKit.framework/Modules/InsulinKit.swiftmodule/arm.swiftmodule b/Carthage/Build/iOS/InsulinKit.framework/Modules/InsulinKit.swiftmodule/arm.swiftmodule index ec19c87b60..33cd1eb678 100644 Binary files a/Carthage/Build/iOS/InsulinKit.framework/Modules/InsulinKit.swiftmodule/arm.swiftmodule and b/Carthage/Build/iOS/InsulinKit.framework/Modules/InsulinKit.swiftmodule/arm.swiftmodule differ diff --git a/Carthage/Build/iOS/InsulinKit.framework/Modules/InsulinKit.swiftmodule/arm64.swiftmodule b/Carthage/Build/iOS/InsulinKit.framework/Modules/InsulinKit.swiftmodule/arm64.swiftmodule index 0089eaa78f..47998f7964 100644 Binary files a/Carthage/Build/iOS/InsulinKit.framework/Modules/InsulinKit.swiftmodule/arm64.swiftmodule and b/Carthage/Build/iOS/InsulinKit.framework/Modules/InsulinKit.swiftmodule/arm64.swiftmodule differ diff --git a/Carthage/Build/iOS/InsulinKit.framework/Modules/InsulinKit.swiftmodule/i386.swiftmodule b/Carthage/Build/iOS/InsulinKit.framework/Modules/InsulinKit.swiftmodule/i386.swiftmodule index e0e2450fbb..938f583e8a 100644 Binary files a/Carthage/Build/iOS/InsulinKit.framework/Modules/InsulinKit.swiftmodule/i386.swiftmodule and b/Carthage/Build/iOS/InsulinKit.framework/Modules/InsulinKit.swiftmodule/i386.swiftmodule differ diff --git a/Carthage/Build/iOS/InsulinKit.framework/Modules/InsulinKit.swiftmodule/x86_64.swiftmodule b/Carthage/Build/iOS/InsulinKit.framework/Modules/InsulinKit.swiftmodule/x86_64.swiftmodule index ea8f493d25..76ebec91bf 100644 Binary files a/Carthage/Build/iOS/InsulinKit.framework/Modules/InsulinKit.swiftmodule/x86_64.swiftmodule and b/Carthage/Build/iOS/InsulinKit.framework/Modules/InsulinKit.swiftmodule/x86_64.swiftmodule differ diff --git a/Carthage/Build/iOS/LoopKit.framework/Assets.car b/Carthage/Build/iOS/LoopKit.framework/Assets.car index 4217ca1be0..a186bf9c91 100644 Binary files a/Carthage/Build/iOS/LoopKit.framework/Assets.car and b/Carthage/Build/iOS/LoopKit.framework/Assets.car differ diff --git a/Carthage/Build/iOS/LoopKit.framework/GlucoseRangeOverrideTableViewCell.nib b/Carthage/Build/iOS/LoopKit.framework/GlucoseRangeOverrideTableViewCell.nib index 726b79723c..a4fa1e9678 100644 Binary files a/Carthage/Build/iOS/LoopKit.framework/GlucoseRangeOverrideTableViewCell.nib and b/Carthage/Build/iOS/LoopKit.framework/GlucoseRangeOverrideTableViewCell.nib differ diff --git a/Carthage/Build/iOS/LoopKit.framework/GlucoseRangeTableViewCell.nib b/Carthage/Build/iOS/LoopKit.framework/GlucoseRangeTableViewCell.nib index 2b9aa7c88c..6a7121d01e 100644 Binary files a/Carthage/Build/iOS/LoopKit.framework/GlucoseRangeTableViewCell.nib and b/Carthage/Build/iOS/LoopKit.framework/GlucoseRangeTableViewCell.nib differ diff --git a/Carthage/Build/iOS/LoopKit.framework/Info.plist b/Carthage/Build/iOS/LoopKit.framework/Info.plist index fe651ce76e..e6a59817c0 100644 Binary files a/Carthage/Build/iOS/LoopKit.framework/Info.plist and b/Carthage/Build/iOS/LoopKit.framework/Info.plist differ diff --git a/Carthage/Build/iOS/LoopKit.framework/LoopKit b/Carthage/Build/iOS/LoopKit.framework/LoopKit index cd90133301..15372e4c7d 100755 Binary files a/Carthage/Build/iOS/LoopKit.framework/LoopKit and b/Carthage/Build/iOS/LoopKit.framework/LoopKit differ diff --git a/Carthage/Build/iOS/LoopKit.framework/Modules/LoopKit.swiftmodule/arm.swiftmodule b/Carthage/Build/iOS/LoopKit.framework/Modules/LoopKit.swiftmodule/arm.swiftmodule index f4b2d9db1e..dc547a7665 100644 Binary files a/Carthage/Build/iOS/LoopKit.framework/Modules/LoopKit.swiftmodule/arm.swiftmodule and b/Carthage/Build/iOS/LoopKit.framework/Modules/LoopKit.swiftmodule/arm.swiftmodule differ diff --git a/Carthage/Build/iOS/LoopKit.framework/Modules/LoopKit.swiftmodule/arm64.swiftmodule b/Carthage/Build/iOS/LoopKit.framework/Modules/LoopKit.swiftmodule/arm64.swiftmodule index 8637de8265..0e5caa551a 100644 Binary files a/Carthage/Build/iOS/LoopKit.framework/Modules/LoopKit.swiftmodule/arm64.swiftmodule and b/Carthage/Build/iOS/LoopKit.framework/Modules/LoopKit.swiftmodule/arm64.swiftmodule differ diff --git a/Carthage/Build/iOS/LoopKit.framework/Modules/LoopKit.swiftmodule/i386.swiftmodule b/Carthage/Build/iOS/LoopKit.framework/Modules/LoopKit.swiftmodule/i386.swiftmodule index f9640b834b..b6e9688850 100644 Binary files a/Carthage/Build/iOS/LoopKit.framework/Modules/LoopKit.swiftmodule/i386.swiftmodule and b/Carthage/Build/iOS/LoopKit.framework/Modules/LoopKit.swiftmodule/i386.swiftmodule differ diff --git a/Carthage/Build/iOS/LoopKit.framework/Modules/LoopKit.swiftmodule/x86_64.swiftmodule b/Carthage/Build/iOS/LoopKit.framework/Modules/LoopKit.swiftmodule/x86_64.swiftmodule index 539d43ac7d..9cf7848b48 100644 Binary files a/Carthage/Build/iOS/LoopKit.framework/Modules/LoopKit.swiftmodule/x86_64.swiftmodule and b/Carthage/Build/iOS/LoopKit.framework/Modules/LoopKit.swiftmodule/x86_64.swiftmodule differ diff --git a/Carthage/Build/iOS/LoopKit.framework/RepeatingScheduleValueTableViewCell.nib b/Carthage/Build/iOS/LoopKit.framework/RepeatingScheduleValueTableViewCell.nib index f1e79e958c..6d2aa6eb0f 100644 Binary files a/Carthage/Build/iOS/LoopKit.framework/RepeatingScheduleValueTableViewCell.nib and b/Carthage/Build/iOS/LoopKit.framework/RepeatingScheduleValueTableViewCell.nib differ diff --git a/Carthage/Build/iOS/LoopKit.framework/TextFieldTableViewCell.nib b/Carthage/Build/iOS/LoopKit.framework/TextFieldTableViewCell.nib index e5aa583d40..06499afbf0 100644 Binary files a/Carthage/Build/iOS/LoopKit.framework/TextFieldTableViewCell.nib and b/Carthage/Build/iOS/LoopKit.framework/TextFieldTableViewCell.nib differ diff --git a/Carthage/Build/iOS/MinimedKit.framework/Info.plist b/Carthage/Build/iOS/MinimedKit.framework/Info.plist index 13b7b16ee9..92cc757b5e 100644 Binary files a/Carthage/Build/iOS/MinimedKit.framework/Info.plist and b/Carthage/Build/iOS/MinimedKit.framework/Info.plist differ diff --git a/Carthage/Build/iOS/MinimedKit.framework/MinimedKit b/Carthage/Build/iOS/MinimedKit.framework/MinimedKit index c63a38e2fb..d84e493e3d 100755 Binary files a/Carthage/Build/iOS/MinimedKit.framework/MinimedKit and b/Carthage/Build/iOS/MinimedKit.framework/MinimedKit differ diff --git a/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/arm.swiftdoc b/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/arm.swiftdoc index 9f9c396e07..b564fce1c8 100644 Binary files a/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/arm.swiftdoc and b/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/arm.swiftdoc differ diff --git a/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/arm.swiftmodule b/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/arm.swiftmodule index b7c3c423a0..f2b3b0e273 100644 Binary files a/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/arm.swiftmodule and b/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/arm.swiftmodule differ diff --git a/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/arm64.swiftdoc b/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/arm64.swiftdoc index 7c944e93d8..ce6bf9551b 100644 Binary files a/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/arm64.swiftdoc and b/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/arm64.swiftdoc differ diff --git a/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/arm64.swiftmodule b/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/arm64.swiftmodule index e08b12da7a..0f180096a7 100644 Binary files a/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/arm64.swiftmodule and b/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/arm64.swiftmodule differ diff --git a/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/i386.swiftdoc b/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/i386.swiftdoc index 15f5774300..2bdc4adc89 100644 Binary files a/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/i386.swiftdoc and b/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/i386.swiftdoc differ diff --git a/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/i386.swiftmodule b/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/i386.swiftmodule index 53b8a16a8f..8668c50051 100644 Binary files a/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/i386.swiftmodule and b/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/i386.swiftmodule differ diff --git a/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/x86_64.swiftdoc b/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/x86_64.swiftdoc index f26642390a..eea7806599 100644 Binary files a/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/x86_64.swiftdoc and b/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/x86_64.swiftdoc differ diff --git a/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/x86_64.swiftmodule b/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/x86_64.swiftmodule index 82e3b3d597..a5a2164939 100644 Binary files a/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/x86_64.swiftmodule and b/Carthage/Build/iOS/MinimedKit.framework/Modules/MinimedKit.swiftmodule/x86_64.swiftmodule differ diff --git a/Carthage/Build/iOS/MinimedKit.framework/es.lproj/InfoPlist.strings b/Carthage/Build/iOS/MinimedKit.framework/es.lproj/InfoPlist.strings new file mode 100644 index 0000000000..1ee4318d4f Binary files /dev/null and b/Carthage/Build/iOS/MinimedKit.framework/es.lproj/InfoPlist.strings differ diff --git a/Carthage/Build/iOS/MinimedKit.framework/es.lproj/Localizable.strings b/Carthage/Build/iOS/MinimedKit.framework/es.lproj/Localizable.strings new file mode 100644 index 0000000000..704a2f1224 Binary files /dev/null and b/Carthage/Build/iOS/MinimedKit.framework/es.lproj/Localizable.strings differ diff --git a/Carthage/Build/iOS/MinimedKit.framework/ru.lproj/InfoPlist.strings b/Carthage/Build/iOS/MinimedKit.framework/ru.lproj/InfoPlist.strings new file mode 100644 index 0000000000..3967e063f9 Binary files /dev/null and b/Carthage/Build/iOS/MinimedKit.framework/ru.lproj/InfoPlist.strings differ diff --git a/Carthage/Build/iOS/MinimedKit.framework/ru.lproj/Localizable.strings b/Carthage/Build/iOS/MinimedKit.framework/ru.lproj/Localizable.strings new file mode 100644 index 0000000000..284262d537 Binary files /dev/null and b/Carthage/Build/iOS/MinimedKit.framework/ru.lproj/Localizable.strings differ diff --git a/Carthage/Build/iOS/NightscoutUploadKit.framework/Headers/NightscoutUploadKit-Swift.h b/Carthage/Build/iOS/NightscoutUploadKit.framework/Headers/NightscoutUploadKit-Swift.h index 1ec1959218..5bc4b7be48 100644 --- a/Carthage/Build/iOS/NightscoutUploadKit.framework/Headers/NightscoutUploadKit-Swift.h +++ b/Carthage/Build/iOS/NightscoutUploadKit.framework/Headers/NightscoutUploadKit-Swift.h @@ -194,6 +194,10 @@ SWIFT_CLASS("_TtC19NightscoutUploadKit20NightscoutPumpEvents") @end +SWIFT_CLASS("_TtC19NightscoutUploadKit10TimeFormat") +@interface TimeFormat : NSObject +- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER; +@end #if __has_attribute(external_source_symbol) # pragma clang attribute pop diff --git a/Carthage/Build/iOS/NightscoutUploadKit.framework/Info.plist b/Carthage/Build/iOS/NightscoutUploadKit.framework/Info.plist index 0f57d8302c..05bdf8efd4 100644 Binary files a/Carthage/Build/iOS/NightscoutUploadKit.framework/Info.plist and b/Carthage/Build/iOS/NightscoutUploadKit.framework/Info.plist differ diff --git a/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/arm.swiftdoc b/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/arm.swiftdoc index d561cbd98b..f9ad01ab02 100644 Binary files a/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/arm.swiftdoc and b/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/arm.swiftdoc differ diff --git a/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/arm.swiftmodule b/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/arm.swiftmodule index 2d0d5da0db..3a9353945e 100644 Binary files a/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/arm.swiftmodule and b/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/arm.swiftmodule differ diff --git a/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/arm64.swiftdoc b/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/arm64.swiftdoc index f218047c8d..1dcfd3bfc8 100644 Binary files a/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/arm64.swiftdoc and b/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/arm64.swiftdoc differ diff --git a/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/arm64.swiftmodule b/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/arm64.swiftmodule index af651e6cbc..049671c9cc 100644 Binary files a/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/arm64.swiftmodule and b/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/arm64.swiftmodule differ diff --git a/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/i386.swiftdoc b/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/i386.swiftdoc index 50f79056c2..58b739fff0 100644 Binary files a/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/i386.swiftdoc and b/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/i386.swiftdoc differ diff --git a/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/i386.swiftmodule b/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/i386.swiftmodule index 874ca7c1a9..80f52949c4 100644 Binary files a/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/i386.swiftmodule and b/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/i386.swiftmodule differ diff --git a/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/x86_64.swiftdoc b/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/x86_64.swiftdoc index d674451191..11f0095f4f 100644 Binary files a/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/x86_64.swiftdoc and b/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/x86_64.swiftdoc differ diff --git a/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/x86_64.swiftmodule b/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/x86_64.swiftmodule index ece7c2370c..46745e245f 100644 Binary files a/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/x86_64.swiftmodule and b/Carthage/Build/iOS/NightscoutUploadKit.framework/Modules/NightscoutUploadKit.swiftmodule/x86_64.swiftmodule differ diff --git a/Carthage/Build/iOS/NightscoutUploadKit.framework/NightscoutUploadKit b/Carthage/Build/iOS/NightscoutUploadKit.framework/NightscoutUploadKit index 8cca9b8410..bfdfcfd5ab 100755 Binary files a/Carthage/Build/iOS/NightscoutUploadKit.framework/NightscoutUploadKit and b/Carthage/Build/iOS/NightscoutUploadKit.framework/NightscoutUploadKit differ diff --git a/Carthage/Build/iOS/NightscoutUploadKit.framework/es.lproj/InfoPlist.strings b/Carthage/Build/iOS/NightscoutUploadKit.framework/es.lproj/InfoPlist.strings new file mode 100644 index 0000000000..1ee4318d4f Binary files /dev/null and b/Carthage/Build/iOS/NightscoutUploadKit.framework/es.lproj/InfoPlist.strings differ diff --git a/Carthage/Build/iOS/NightscoutUploadKit.framework/ru.lproj/InfoPlist.strings b/Carthage/Build/iOS/NightscoutUploadKit.framework/ru.lproj/InfoPlist.strings new file mode 100644 index 0000000000..3967e063f9 Binary files /dev/null and b/Carthage/Build/iOS/NightscoutUploadKit.framework/ru.lproj/InfoPlist.strings differ diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/CmdBase.h b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/CmdBase.h deleted file mode 100644 index fd81d13117..0000000000 --- a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/CmdBase.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// BaseCmd.h -// RileyLink -// -// Created by Pete Schwamb on 12/26/15. -// Copyright © 2015 Pete Schwamb. All rights reserved. -// - -@import Foundation; - -#define RILEYLINK_CMD_GET_STATE 1 -#define RILEYLINK_CMD_GET_VERSION 2 -#define RILEYLINK_CMD_GET_PACKET 3 -#define RILEYLINK_CMD_SEND_PACKET 4 -#define RILEYLINK_CMD_SEND_AND_LISTEN 5 -#define RILEYLINK_CMD_UPDATE_REGISTER 6 -#define RILEYLINK_CMD_RESET 7 - -@interface CmdBase : NSObject - -@property (NS_NONATOMIC_IOSONLY, readonly, copy) NSData *data; - -@property (nonatomic, strong) NSData *response; - -@end diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/GetPacketCmd.h b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/GetPacketCmd.h deleted file mode 100644 index ae43054d15..0000000000 --- a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/GetPacketCmd.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// GetPacketCmd.h -// RileyLink -// -// Created by Pete Schwamb on 1/2/16. -// Copyright © 2016 Pete Schwamb. All rights reserved. -// - -@import Foundation; -#import "ReceivingPacketCmd.h" - - -@interface GetPacketCmd : ReceivingPacketCmd - -@property (nonatomic, assign) uint8_t listenChannel; -@property (nonatomic, assign) uint32_t timeoutMS; - -@end diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/RFPacket.h b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/RFPacket.h deleted file mode 100644 index 2300bca7df..0000000000 --- a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/RFPacket.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// RFPacket.h -// RileyLink -// -// Created by Pete Schwamb on 2/28/16. -// Copyright © 2016 Pete Schwamb. All rights reserved. -// - -@import Foundation; - -@interface RFPacket : NSObject - -- (nonnull instancetype)initWithData:(nonnull NSData*)data NS_DESIGNATED_INITIALIZER; -- (nullable instancetype)initWithRFSPYResponse:(nonnull NSData*)data NS_DESIGNATED_INITIALIZER; - -- (nonnull NSData*)encodedData; - -@property (nonatomic, nullable, strong) NSData *data; -@property (nonatomic, nullable, strong) NSDate *capturedAt; -@property (nonatomic, assign) int rssi; -@property (nonatomic, assign) int packetNumber; - - -@end diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/ReceivingPacketCmd.h b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/ReceivingPacketCmd.h deleted file mode 100644 index 57e8648a3f..0000000000 --- a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/ReceivingPacketCmd.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// ReceivingPacketCmd.h -// RileyLink -// -// Created by Pete Schwamb on 3/3/16. -// Copyright © 2016 Pete Schwamb. All rights reserved. -// - -@import Foundation; -#import "CmdBase.h" -#import "RFPacket.h" - -@interface ReceivingPacketCmd : CmdBase - -@property (nonatomic, strong) RFPacket *receivedPacket; -@property (nonatomic, readonly) BOOL didReceiveResponse; -@property (nonatomic, readonly) NSData *rawReceivedData; - -@end diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/RileyLinkBLEDevice.h b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/RileyLinkBLEDevice.h deleted file mode 100644 index 9063f61900..0000000000 --- a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/RileyLinkBLEDevice.h +++ /dev/null @@ -1,106 +0,0 @@ -// -// RileyLinkBLE.h -// RileyLink -// -// Created by Pete Schwamb on 7/28/15. -// Copyright (c) 2015 Pete Schwamb. All rights reserved. -// - -@import Foundation; -@import CoreBluetooth; -#import "CmdBase.h" - -typedef NS_ENUM(NSUInteger, RileyLinkState) { - RileyLinkStateConnecting, - RileyLinkStateConnected, - RileyLinkStateDisconnected -}; - -extern NSString * _Nonnull const SubgRfspyErrorDomain; - -typedef NS_ENUM(NSUInteger, SubgRfspyError) { - SubgRfspyErrorRxTimeout = 0xaa, - SubgRfspyErrorCmdInterrupted = 0xbb, - SubgRfspyErrorZeroData = 0xcc -}; - -typedef NS_ENUM(NSUInteger, SubgRfspyVersionState) { - SubgRfspyVersionStateUnknown = 0, - SubgRfspyVersionStateUpToDate, - SubgRfspyVersionStateOutOfDate, - SubgRfspyVersionStateInvalid -}; - - -#define ERROR_RX_TIMEOUT 0xaa -#define ERROR_CMD_INTERRUPTED 0xbb -#define ERROR_ZERO_DATA 0xcc - -#define RILEYLINK_FREQ_XTAL 24000000 - -#define CC111X_REG_FREQ2 0x09 -#define CC111X_REG_FREQ1 0x0A -#define CC111X_REG_FREQ0 0x0B -#define CC111X_REG_MDMCFG4 0x0C -#define CC111X_REG_MDMCFG3 0x0D -#define CC111X_REG_MDMCFG2 0x0E -#define CC111X_REG_MDMCFG1 0x0F -#define CC111X_REG_MDMCFG0 0x10 -#define CC111X_REG_DEVIATN 0x11 -#define CC111X_REG_AGCCTRL2 0x17 -#define CC111X_REG_AGCCTRL1 0x18 -#define CC111X_REG_AGCCTRL0 0x19 -#define CC111X_REG_FREND1 0x1A -#define CC111X_REG_FREND0 0x1B - - -@interface RileyLinkCmdSession : NSObject -/** - Runs a command synchronously. I.E. this method will not return until the command - finishes, or times out. Returns NO if the command timed out. The command's response - is set if the command did not time out. - */ -- (BOOL) doCmd:(nonnull CmdBase*)cmd withTimeoutMs:(NSInteger)timeoutMS; -@end - -@interface RileyLinkBLEDevice : NSObject - -@property (nonatomic, nullable, readonly) NSString * name; -@property (nonatomic, nullable, strong) NSNumber * RSSI; -@property (nonatomic, nonnull, readonly) NSString * peripheralId; -@property (nonatomic, nonnull, strong) CBPeripheral * peripheral; - -@property (nonatomic, readonly) RileyLinkState state; - -@property (nonatomic, readonly, copy, nonnull) NSString * deviceURI; - -@property (nonatomic, readonly, nullable) NSString *firmwareVersion; - -@property (nonatomic, readonly) SubgRfspyVersionState firmwareState; - -@property (nonatomic, readonly, nullable) NSString *bleFirmwareVersion; - -@property (nonatomic, readonly, nullable) NSDate *lastIdle; - -@property (nonatomic) BOOL timerTickEnabled; - -@property (nonatomic) uint32_t idleTimeoutMS; - -/** - Initializes the device with a specified peripheral - - @param peripheral The peripheral to represent - - @return A newly-initialized device - */ -- (nonnull instancetype)initWithPeripheral:(nonnull CBPeripheral *)peripheral NS_DESIGNATED_INITIALIZER; - -- (void) connectionStateDidChange:(nullable NSError *)error; - -- (void) runSessionWithName:(nonnull NSString*)name usingBlock:(void (^ _Nonnull)(RileyLinkCmdSession* _Nonnull))proc; -- (void) setCustomName:(nonnull NSString*)customName; -- (void) enableIdleListeningOnChannel:(uint8_t)channel; -- (void) disableIdleListening; -- (void) assertIdleListeningForcingRestart:(BOOL)forceRestart; - -@end diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/RileyLinkBLEKit-Swift.h b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/RileyLinkBLEKit-Swift.h new file mode 100644 index 0000000000..f291e9aff6 --- /dev/null +++ b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/RileyLinkBLEKit-Swift.h @@ -0,0 +1,263 @@ +// Generated by Apple Swift version 4.1 (swiftlang-902.0.48 clang-902.0.37.1) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgcc-compat" + +#if !defined(__has_include) +# define __has_include(x) 0 +#endif +#if !defined(__has_attribute) +# define __has_attribute(x) 0 +#endif +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif +#if !defined(__has_warning) +# define __has_warning(x) 0 +#endif + +#if __has_include() +# include +#endif + +#pragma clang diagnostic ignored "-Wauto-import" +#include +#include +#include +#include + +#if !defined(SWIFT_TYPEDEFS) +# define SWIFT_TYPEDEFS 1 +# if __has_include() +# include +# elif !defined(__cplusplus) +typedef uint_least16_t char16_t; +typedef uint_least32_t char32_t; +# endif +typedef float swift_float2 __attribute__((__ext_vector_type__(2))); +typedef float swift_float3 __attribute__((__ext_vector_type__(3))); +typedef float swift_float4 __attribute__((__ext_vector_type__(4))); +typedef double swift_double2 __attribute__((__ext_vector_type__(2))); +typedef double swift_double3 __attribute__((__ext_vector_type__(3))); +typedef double swift_double4 __attribute__((__ext_vector_type__(4))); +typedef int swift_int2 __attribute__((__ext_vector_type__(2))); +typedef int swift_int3 __attribute__((__ext_vector_type__(3))); +typedef int swift_int4 __attribute__((__ext_vector_type__(4))); +typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); +typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); +typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); +#endif + +#if !defined(SWIFT_PASTE) +# define SWIFT_PASTE_HELPER(x, y) x##y +# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) +#endif +#if !defined(SWIFT_METATYPE) +# define SWIFT_METATYPE(X) Class +#endif +#if !defined(SWIFT_CLASS_PROPERTY) +# if __has_feature(objc_class_property) +# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ +# else +# define SWIFT_CLASS_PROPERTY(...) +# endif +#endif + +#if __has_attribute(objc_runtime_name) +# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) +#else +# define SWIFT_RUNTIME_NAME(X) +#endif +#if __has_attribute(swift_name) +# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) +#else +# define SWIFT_COMPILE_NAME(X) +#endif +#if __has_attribute(objc_method_family) +# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) +#else +# define SWIFT_METHOD_FAMILY(X) +#endif +#if __has_attribute(noescape) +# define SWIFT_NOESCAPE __attribute__((noescape)) +#else +# define SWIFT_NOESCAPE +#endif +#if __has_attribute(warn_unused_result) +# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +# define SWIFT_WARN_UNUSED_RESULT +#endif +#if __has_attribute(noreturn) +# define SWIFT_NORETURN __attribute__((noreturn)) +#else +# define SWIFT_NORETURN +#endif +#if !defined(SWIFT_CLASS_EXTRA) +# define SWIFT_CLASS_EXTRA +#endif +#if !defined(SWIFT_PROTOCOL_EXTRA) +# define SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_ENUM_EXTRA) +# define SWIFT_ENUM_EXTRA +#endif +#if !defined(SWIFT_CLASS) +# if __has_attribute(objc_subclassing_restricted) +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# else +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# endif +#endif + +#if !defined(SWIFT_PROTOCOL) +# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +#endif + +#if !defined(SWIFT_EXTENSION) +# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) +#endif + +#if !defined(OBJC_DESIGNATED_INITIALIZER) +# if __has_attribute(objc_designated_initializer) +# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +# else +# define OBJC_DESIGNATED_INITIALIZER +# endif +#endif +#if !defined(SWIFT_ENUM_ATTR) +# if defined(__has_attribute) && __has_attribute(enum_extensibility) +# define SWIFT_ENUM_ATTR __attribute__((enum_extensibility(open))) +# else +# define SWIFT_ENUM_ATTR +# endif +#endif +#if !defined(SWIFT_ENUM) +# define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum SWIFT_ENUM_ATTR SWIFT_ENUM_EXTRA _name : _type +# if __has_feature(generalized_swift_name) +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR SWIFT_ENUM_EXTRA _name : _type +# else +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) SWIFT_ENUM(_type, _name) +# endif +#endif +#if !defined(SWIFT_UNAVAILABLE) +# define SWIFT_UNAVAILABLE __attribute__((unavailable)) +#endif +#if !defined(SWIFT_UNAVAILABLE_MSG) +# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) +#endif +#if !defined(SWIFT_AVAILABILITY) +# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) +#endif +#if !defined(SWIFT_DEPRECATED) +# define SWIFT_DEPRECATED __attribute__((deprecated)) +#endif +#if !defined(SWIFT_DEPRECATED_MSG) +# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) +#endif +#if __has_feature(attribute_diagnose_if_objc) +# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) +#else +# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) +#endif +#if __has_feature(modules) +@import CoreBluetooth; +@import ObjectiveC; +#endif + +#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" +#pragma clang diagnostic ignored "-Wduplicate-method-arg" +#if __has_warning("-Wpragma-clang-attribute") +# pragma clang diagnostic ignored "-Wpragma-clang-attribute" +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wnullability" + +#if __has_attribute(external_source_symbol) +# pragma push_macro("any") +# undef any +# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="RileyLinkBLEKit",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) +# pragma pop_macro("any") +#endif + + + + + + + + + + +SWIFT_CLASS("_TtC15RileyLinkBLEKit17PeripheralManager") +@interface PeripheralManager : NSObject +- (nonnull instancetype)init SWIFT_UNAVAILABLE; ++ (nonnull instancetype)new SWIFT_DEPRECATED_MSG("-init is unavailable"); +@end + + + + + + +@interface PeripheralManager (SWIFT_EXTENSION(RileyLinkBLEKit)) +- (void)centralManagerDidUpdateState:(CBCentralManager * _Nonnull)central; +- (void)centralManager:(CBCentralManager * _Nonnull)central didConnectPeripheral:(CBPeripheral * _Nonnull)peripheral; +@end + + + + + +@class CBService; +@class CBCharacteristic; +@class NSNumber; + +@interface PeripheralManager (SWIFT_EXTENSION(RileyLinkBLEKit)) +- (void)peripheral:(CBPeripheral * _Nonnull)peripheral didDiscoverServices:(NSError * _Nullable)error; +- (void)peripheral:(CBPeripheral * _Nonnull)peripheral didDiscoverCharacteristicsForService:(CBService * _Nonnull)service error:(NSError * _Nullable)error; +- (void)peripheral:(CBPeripheral * _Nonnull)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic * _Nonnull)characteristic error:(NSError * _Nullable)error; +- (void)peripheral:(CBPeripheral * _Nonnull)peripheral didWriteValueForCharacteristic:(CBCharacteristic * _Nonnull)characteristic error:(NSError * _Nullable)error; +- (void)peripheral:(CBPeripheral * _Nonnull)peripheral didUpdateValueForCharacteristic:(CBCharacteristic * _Nonnull)characteristic error:(NSError * _Nullable)error; +- (void)peripheral:(CBPeripheral * _Nonnull)peripheral didReadRSSI:(NSNumber * _Nonnull)RSSI error:(NSError * _Nullable)error; +- (void)peripheralDidUpdateName:(CBPeripheral * _Nonnull)peripheral; +@end + + + + + + +SWIFT_CLASS("_TtC15RileyLinkBLEKit22RileyLinkDeviceManager") +@interface RileyLinkDeviceManager : NSObject +- (nonnull instancetype)init SWIFT_UNAVAILABLE; ++ (nonnull instancetype)new SWIFT_DEPRECATED_MSG("-init is unavailable"); +@end + + + + + + +@interface RileyLinkDeviceManager (SWIFT_EXTENSION(RileyLinkBLEKit)) +@property (nonatomic, readonly, copy) NSString * _Nonnull debugDescription; +@end + + +@interface RileyLinkDeviceManager (SWIFT_EXTENSION(RileyLinkBLEKit)) +- (void)centralManager:(CBCentralManager * _Nonnull)central willRestoreState:(NSDictionary * _Nonnull)dict; +- (void)centralManagerDidUpdateState:(CBCentralManager * _Nonnull)central; +- (void)centralManager:(CBCentralManager * _Nonnull)central didDiscoverPeripheral:(CBPeripheral * _Nonnull)peripheral advertisementData:(NSDictionary * _Nonnull)advertisementData RSSI:(NSNumber * _Nonnull)RSSI; +- (void)centralManager:(CBCentralManager * _Nonnull)central didConnectPeripheral:(CBPeripheral * _Nonnull)peripheral; +- (void)centralManager:(CBCentralManager * _Nonnull)central didDisconnectPeripheral:(CBPeripheral * _Nonnull)peripheral error:(NSError * _Nullable)error; +- (void)centralManager:(CBCentralManager * _Nonnull)central didFailToConnectPeripheral:(CBPeripheral * _Nonnull)peripheral error:(NSError * _Nullable)error; +@end + + + +#if __has_attribute(external_source_symbol) +# pragma clang attribute pop +#endif +#pragma clang diagnostic pop diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/RileyLinkBLEKit.h b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/RileyLinkBLEKit.h index 64ce668ea4..191e90389a 100644 --- a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/RileyLinkBLEKit.h +++ b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/RileyLinkBLEKit.h @@ -2,11 +2,10 @@ // RileyLinkBLEKit.h // RileyLinkBLEKit // -// Created by Nathan Racklyeft on 4/8/16. -// Copyright © 2016 Pete Schwamb. All rights reserved. +// Copyright © 2017 Pete Schwamb. All rights reserved. // -#import +#import //! Project version number for RileyLinkBLEKit. FOUNDATION_EXPORT double RileyLinkBLEKitVersionNumber; @@ -14,10 +13,6 @@ FOUNDATION_EXPORT double RileyLinkBLEKitVersionNumber; //! Project version string for RileyLinkBLEKit. FOUNDATION_EXPORT const unsigned char RileyLinkBLEKitVersionString[]; -#import -#import -#import -#import -#import -#import -#import +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/RileyLinkBLEManager.h b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/RileyLinkBLEManager.h deleted file mode 100644 index aa94fd6785..0000000000 --- a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/RileyLinkBLEManager.h +++ /dev/null @@ -1,55 +0,0 @@ -// -// RileyLink.h -// RileyLink -// -// Created by Pete Schwamb on 8/5/14. -// Copyright (c) 2014 Pete Schwamb. All rights reserved. -// - -@import CoreBluetooth; -@import Foundation; - -#define RILEYLINK_EVENT_DEVICE_CREATED @"RILEYLINK_EVENT_DEVICE_CREATED" -#define RILEYLINK_IDLE_RESPONSE_RECEIVED @"RILEYLINK_IDLE_RESPONSE_RECEIVED" -#define RILEYLINK_EVENT_DEVICE_CONNECTED @"RILEYLINK_EVENT_DEVICE_CONNECTED" -#define RILEYLINK_EVENT_DEVICE_DISCONNECTED @"RILEYLINK_EVENT_DEVICE_DISCONNECTED" -#define RILEYLINK_EVENT_DEVICE_ATTRS_DISCOVERED @"RILEYLINK_EVENT_DEVICE_ATTRS_DISCOVERED" -#define RILEYLINK_EVENT_DEVICE_READY @"RILEYLINK_EVENT_DEVICE_READY" -#define RILEYLINK_EVENT_DEVICE_TIMER_TICK @"RILEYLINK_EVENT_DEVICE_TIMER_TICK" -#define RILEYLINK_EVENT_RSSI_CHANGED @"RILEYLINK_EVENT_RSSI_CHANGED" -#define RILEYLINK_EVENT_NAME_CHANGED @"RILEYLINK_EVENT_NAME_CHANGED" - -#define RILEYLINK_SERVICE_UUID @"0235733b-99c5-4197-b856-69219c2a3845" -#define RILEYLINK_DATA_UUID @"c842e849-5028-42e2-867c-016adada9155" -#define RILEYLINK_RESPONSE_COUNT_UUID @"6e6c7910-b89e-43a5-a0fe-50c5e2b81f4a" -#define RILEYLINK_CUSTOM_NAME_UUID @"d93b2af0-1e28-11e4-8c21-0800200c9a66" -#define RILEYLINK_TIMER_TICK_UUID @"6e6c7910-b89e-43a5-78af-50c5e2b86f7e" -#define RILEYLINK_FIRMWARE_VERSION_UUID @"30d99dc9-7c91-4295-a051-0a104d238cf2" - -@class RileyLinkBLEDevice; - -@interface RileyLinkBLEManager : NSObject - -@property (nonatomic, nonnull, readonly, copy) NSArray *rileyLinkList; - -- (void)connectDevice:(nonnull RileyLinkBLEDevice *)device; -- (void)disconnectDevice:(nonnull RileyLinkBLEDevice *)device; - -- (nonnull instancetype)initWithAutoConnectIDs:(nonnull NSSet *)autoConnectIDs; - -@property (nonatomic, nonnull, readonly) NSSet *autoConnectIDs; - -- (void)setScanningEnabled:(BOOL)scanningEnabled; - -/** - Converts an array of UUID strings to CBUUID objects, excluding those represented in an array of CBAttribute objects. - - @param UUIDStrings An array of UUID string representations to filter - @param attributes An array of CBAttribute objects to exclude - - @return An array of CBUUID objects - */ -+ (nonnull NSArray *)UUIDsFromUUIDStrings:(nonnull NSArray *)UUIDStrings excludingAttributes:(nullable NSArray *)attributes; - -@end - diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/SendAndListenCmd.h b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/SendAndListenCmd.h deleted file mode 100644 index 9d5eca8855..0000000000 --- a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/SendAndListenCmd.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// SendDataCmd.h -// RileyLink -// -// Created by Pete Schwamb on 8/9/15. -// Copyright (c) 2015 Pete Schwamb. All rights reserved. -// - -@import Foundation; -#import "ReceivingPacketCmd.h" -#import "RFPacket.h" - -@interface SendAndListenCmd : ReceivingPacketCmd - -@property (nonatomic, strong) RFPacket *packet; -@property (nonatomic, assign) uint8_t sendChannel; // In general, 0 = meter, cgm. 2 = pump -@property (nonatomic, assign) uint8_t repeatCount; // 0 = no repeat, i.e. only one packet. 1 repeat = 2 packets sent total. -@property (nonatomic, assign) uint8_t msBetweenPackets; -@property (nonatomic, assign) uint8_t listenChannel; -@property (nonatomic, assign) uint32_t timeoutMS; -@property (nonatomic, assign) uint8_t retryCount; - -@end diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/SendPacketCmd.h b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/SendPacketCmd.h deleted file mode 100644 index c5d50e8303..0000000000 --- a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/SendPacketCmd.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// SendPacketCmd.h -// RileyLink -// -// Created by Pete Schwamb on 12/27/15. -// Copyright © 2015 Pete Schwamb. All rights reserved. -// - -@import Foundation; -#import "CmdBase.h" -#import "RFPacket.h" - -@interface SendPacketCmd : CmdBase - -@property (nonatomic, strong) RFPacket *packet; -@property (nonatomic, assign) uint8_t sendChannel; // In general, 0 = meter, cgm. 2 = pump -@property (nonatomic, assign) uint8_t repeatCount; // 0 = no repeat, i.e. only one packet. 1 repeat = 2 packets sent total. -@property (nonatomic, assign) uint8_t msBetweenPackets; - -@end diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/UpdateRegisterCmd.h b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/UpdateRegisterCmd.h deleted file mode 100644 index 61289a45e2..0000000000 --- a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Headers/UpdateRegisterCmd.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// UpdateRegisterCmd.h -// RileyLink -// -// Created by Pete Schwamb on 1/25/16. -// Copyright © 2016 Pete Schwamb. All rights reserved. -// - -#import "CmdBase.h" - -@interface UpdateRegisterCmd : CmdBase - -@property (nonatomic, assign) uint8_t addr; -@property (nonatomic, assign) uint8_t value; - -@end diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Info.plist b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Info.plist index e71c66ef76..607b825d56 100644 Binary files a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Info.plist and b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Info.plist differ diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/arm.swiftdoc b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/arm.swiftdoc new file mode 100644 index 0000000000..cbe667511c Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/arm.swiftdoc differ diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/arm.swiftmodule b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/arm.swiftmodule new file mode 100644 index 0000000000..9ff1531c58 Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/arm.swiftmodule differ diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/arm64.swiftdoc b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/arm64.swiftdoc new file mode 100644 index 0000000000..efa74fdffd Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/arm64.swiftdoc differ diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/arm64.swiftmodule b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/arm64.swiftmodule new file mode 100644 index 0000000000..cba3abdfd0 Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/arm64.swiftmodule differ diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/i386.swiftdoc b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/i386.swiftdoc new file mode 100644 index 0000000000..b704f724d7 Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/i386.swiftdoc differ diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/i386.swiftmodule b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/i386.swiftmodule new file mode 100644 index 0000000000..b987761709 Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/i386.swiftmodule differ diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/x86_64.swiftdoc b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/x86_64.swiftdoc new file mode 100644 index 0000000000..899270802a Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/x86_64.swiftdoc differ diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/x86_64.swiftmodule b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/x86_64.swiftmodule new file mode 100644 index 0000000000..bb08da24ee Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/RileyLinkBLEKit.swiftmodule/x86_64.swiftmodule differ diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/module.modulemap b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/module.modulemap index 3e72917a43..8985fa2761 100644 --- a/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/module.modulemap +++ b/Carthage/Build/iOS/RileyLinkBLEKit.framework/Modules/module.modulemap @@ -4,3 +4,8 @@ framework module RileyLinkBLEKit { export * module * { export * } } + +module RileyLinkBLEKit.Swift { + header "RileyLinkBLEKit-Swift.h" + requires objc +} diff --git a/Carthage/Build/iOS/RileyLinkBLEKit.framework/RileyLinkBLEKit b/Carthage/Build/iOS/RileyLinkBLEKit.framework/RileyLinkBLEKit index 12c24d439c..ed739b996e 100755 Binary files a/Carthage/Build/iOS/RileyLinkBLEKit.framework/RileyLinkBLEKit and b/Carthage/Build/iOS/RileyLinkBLEKit.framework/RileyLinkBLEKit differ diff --git a/Carthage/Build/iOS/RileyLinkKit.framework/Headers/RileyLinkKit-Swift.h b/Carthage/Build/iOS/RileyLinkKit.framework/Headers/RileyLinkKit-Swift.h index 0eb5b95f8e..f204a949f5 100644 --- a/Carthage/Build/iOS/RileyLinkKit.framework/Headers/RileyLinkKit-Swift.h +++ b/Carthage/Build/iOS/RileyLinkKit.framework/Headers/RileyLinkKit-Swift.h @@ -163,8 +163,6 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); # define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) #endif #if __has_feature(modules) -@import UIKit; -@import Foundation; #endif #pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" @@ -182,40 +180,6 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); # pragma pop_macro("any") #endif -@class UISwitch; -@class NSCoder; - -SWIFT_CLASS("_TtC12RileyLinkKit28RileyLinkDeviceTableViewCell") -@interface RileyLinkDeviceTableViewCell : UITableViewCell -@property (nonatomic, weak) IBOutlet UISwitch * _Null_unspecified connectSwitch; -- (void)prepareForReuse; -- (nonnull instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString * _Nullable)reuseIdentifier OBJC_DESIGNATED_INITIALIZER SWIFT_AVAILABILITY(ios,introduced=3.0); -- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER; -@end - -@class UITableView; -@class NSBundle; - -SWIFT_CLASS("_TtC12RileyLinkKit34RileyLinkDeviceTableViewController") -@interface RileyLinkDeviceTableViewController : UITableViewController -- (nonnull instancetype)init SWIFT_UNAVAILABLE; -+ (nonnull instancetype)new SWIFT_DEPRECATED_MSG("-init is unavailable"); -- (void)viewDidLoad; -- (void)viewWillAppear:(BOOL)animated; -- (void)viewWillDisappear:(BOOL)animated; -- (NSInteger)numberOfSectionsInTableView:(UITableView * _Nonnull)tableView SWIFT_WARN_UNUSED_RESULT; -- (NSInteger)tableView:(UITableView * _Nonnull)tableView numberOfRowsInSection:(NSInteger)section SWIFT_WARN_UNUSED_RESULT; -- (UITableViewCell * _Nonnull)tableView:(UITableView * _Nonnull)tableView cellForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath SWIFT_WARN_UNUSED_RESULT; -- (NSString * _Nullable)tableView:(UITableView * _Nonnull)tableView titleForHeaderInSection:(NSInteger)section SWIFT_WARN_UNUSED_RESULT; -- (BOOL)tableView:(UITableView * _Nonnull)tableView shouldHighlightRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath SWIFT_WARN_UNUSED_RESULT; -- (void)tableView:(UITableView * _Nonnull)tableView didSelectRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath; -- (nonnull instancetype)initWithStyle:(UITableViewStyle)style OBJC_DESIGNATED_INITIALIZER; -- (nonnull instancetype)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil OBJC_DESIGNATED_INITIALIZER; -- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER; -@end - - - #if __has_attribute(external_source_symbol) # pragma clang attribute pop #endif diff --git a/Carthage/Build/iOS/RileyLinkKit.framework/Info.plist b/Carthage/Build/iOS/RileyLinkKit.framework/Info.plist index 079c5192b0..7939db8efa 100644 Binary files a/Carthage/Build/iOS/RileyLinkKit.framework/Info.plist and b/Carthage/Build/iOS/RileyLinkKit.framework/Info.plist differ diff --git a/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/arm.swiftdoc b/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/arm.swiftdoc index e8775af24a..b951c256fc 100644 Binary files a/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/arm.swiftdoc and b/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/arm.swiftdoc differ diff --git a/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/arm.swiftmodule b/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/arm.swiftmodule index 9aeace8214..069818c359 100644 Binary files a/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/arm.swiftmodule and b/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/arm.swiftmodule differ diff --git a/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/arm64.swiftdoc b/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/arm64.swiftdoc index 9825d70c31..206ae7c5a1 100644 Binary files a/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/arm64.swiftdoc and b/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/arm64.swiftdoc differ diff --git a/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/arm64.swiftmodule b/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/arm64.swiftmodule index e877711c02..acf856abfd 100644 Binary files a/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/arm64.swiftmodule and b/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/arm64.swiftmodule differ diff --git a/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/i386.swiftdoc b/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/i386.swiftdoc index be39a4df4f..a9287c28bb 100644 Binary files a/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/i386.swiftdoc and b/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/i386.swiftdoc differ diff --git a/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/i386.swiftmodule b/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/i386.swiftmodule index 8c3dad8fe7..a636df0bf7 100644 Binary files a/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/i386.swiftmodule and b/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/i386.swiftmodule differ diff --git a/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/x86_64.swiftdoc b/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/x86_64.swiftdoc index 70c3fc0be7..c891fbf837 100644 Binary files a/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/x86_64.swiftdoc and b/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/x86_64.swiftdoc differ diff --git a/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/x86_64.swiftmodule b/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/x86_64.swiftmodule index 469d479462..64c21e39d7 100644 Binary files a/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/x86_64.swiftmodule and b/Carthage/Build/iOS/RileyLinkKit.framework/Modules/RileyLinkKit.swiftmodule/x86_64.swiftmodule differ diff --git a/Carthage/Build/iOS/RileyLinkKit.framework/RileyLinkDeviceTableViewCell.nib b/Carthage/Build/iOS/RileyLinkKit.framework/RileyLinkDeviceTableViewCell.nib deleted file mode 100644 index c006a1e133..0000000000 Binary files a/Carthage/Build/iOS/RileyLinkKit.framework/RileyLinkDeviceTableViewCell.nib and /dev/null differ diff --git a/Carthage/Build/iOS/RileyLinkKit.framework/RileyLinkKit b/Carthage/Build/iOS/RileyLinkKit.framework/RileyLinkKit index bc98950b4d..1e6f66fe23 100755 Binary files a/Carthage/Build/iOS/RileyLinkKit.framework/RileyLinkKit and b/Carthage/Build/iOS/RileyLinkKit.framework/RileyLinkKit differ diff --git a/Carthage/Build/iOS/RileyLinkKit.framework/TextFieldTableViewCell.nib b/Carthage/Build/iOS/RileyLinkKit.framework/TextFieldTableViewCell.nib deleted file mode 100644 index 04fc0e0753..0000000000 Binary files a/Carthage/Build/iOS/RileyLinkKit.framework/TextFieldTableViewCell.nib and /dev/null differ diff --git a/Carthage/Build/iOS/RileyLinkKit.framework/es.lproj/InfoPlist.strings b/Carthage/Build/iOS/RileyLinkKit.framework/es.lproj/InfoPlist.strings new file mode 100644 index 0000000000..1ee4318d4f Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkKit.framework/es.lproj/InfoPlist.strings differ diff --git a/Carthage/Build/iOS/RileyLinkKit.framework/es.lproj/Localizable.strings b/Carthage/Build/iOS/RileyLinkKit.framework/es.lproj/Localizable.strings new file mode 100644 index 0000000000..9f76d6cf34 Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkKit.framework/es.lproj/Localizable.strings differ diff --git a/Carthage/Build/iOS/RileyLinkKit.framework/ru.lproj/InfoPlist.strings b/Carthage/Build/iOS/RileyLinkKit.framework/ru.lproj/InfoPlist.strings new file mode 100644 index 0000000000..3967e063f9 Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkKit.framework/ru.lproj/InfoPlist.strings differ diff --git a/Carthage/Build/iOS/RileyLinkKit.framework/ru.lproj/Localizable.strings b/Carthage/Build/iOS/RileyLinkKit.framework/ru.lproj/Localizable.strings new file mode 100644 index 0000000000..5a57392335 Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkKit.framework/ru.lproj/Localizable.strings differ diff --git a/Carthage/Build/iOS/RileyLinkKitUI.framework/Headers/RileyLinkKitUI-Swift.h b/Carthage/Build/iOS/RileyLinkKitUI.framework/Headers/RileyLinkKitUI-Swift.h new file mode 100644 index 0000000000..1bad713eda --- /dev/null +++ b/Carthage/Build/iOS/RileyLinkKitUI.framework/Headers/RileyLinkKitUI-Swift.h @@ -0,0 +1,244 @@ +// Generated by Apple Swift version 4.1 (swiftlang-902.0.48 clang-902.0.37.1) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgcc-compat" + +#if !defined(__has_include) +# define __has_include(x) 0 +#endif +#if !defined(__has_attribute) +# define __has_attribute(x) 0 +#endif +#if !defined(__has_feature) +# define __has_feature(x) 0 +#endif +#if !defined(__has_warning) +# define __has_warning(x) 0 +#endif + +#if __has_include() +# include +#endif + +#pragma clang diagnostic ignored "-Wauto-import" +#include +#include +#include +#include + +#if !defined(SWIFT_TYPEDEFS) +# define SWIFT_TYPEDEFS 1 +# if __has_include() +# include +# elif !defined(__cplusplus) +typedef uint_least16_t char16_t; +typedef uint_least32_t char32_t; +# endif +typedef float swift_float2 __attribute__((__ext_vector_type__(2))); +typedef float swift_float3 __attribute__((__ext_vector_type__(3))); +typedef float swift_float4 __attribute__((__ext_vector_type__(4))); +typedef double swift_double2 __attribute__((__ext_vector_type__(2))); +typedef double swift_double3 __attribute__((__ext_vector_type__(3))); +typedef double swift_double4 __attribute__((__ext_vector_type__(4))); +typedef int swift_int2 __attribute__((__ext_vector_type__(2))); +typedef int swift_int3 __attribute__((__ext_vector_type__(3))); +typedef int swift_int4 __attribute__((__ext_vector_type__(4))); +typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); +typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); +typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); +#endif + +#if !defined(SWIFT_PASTE) +# define SWIFT_PASTE_HELPER(x, y) x##y +# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) +#endif +#if !defined(SWIFT_METATYPE) +# define SWIFT_METATYPE(X) Class +#endif +#if !defined(SWIFT_CLASS_PROPERTY) +# if __has_feature(objc_class_property) +# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ +# else +# define SWIFT_CLASS_PROPERTY(...) +# endif +#endif + +#if __has_attribute(objc_runtime_name) +# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) +#else +# define SWIFT_RUNTIME_NAME(X) +#endif +#if __has_attribute(swift_name) +# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) +#else +# define SWIFT_COMPILE_NAME(X) +#endif +#if __has_attribute(objc_method_family) +# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) +#else +# define SWIFT_METHOD_FAMILY(X) +#endif +#if __has_attribute(noescape) +# define SWIFT_NOESCAPE __attribute__((noescape)) +#else +# define SWIFT_NOESCAPE +#endif +#if __has_attribute(warn_unused_result) +# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +# define SWIFT_WARN_UNUSED_RESULT +#endif +#if __has_attribute(noreturn) +# define SWIFT_NORETURN __attribute__((noreturn)) +#else +# define SWIFT_NORETURN +#endif +#if !defined(SWIFT_CLASS_EXTRA) +# define SWIFT_CLASS_EXTRA +#endif +#if !defined(SWIFT_PROTOCOL_EXTRA) +# define SWIFT_PROTOCOL_EXTRA +#endif +#if !defined(SWIFT_ENUM_EXTRA) +# define SWIFT_ENUM_EXTRA +#endif +#if !defined(SWIFT_CLASS) +# if __has_attribute(objc_subclassing_restricted) +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# else +# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA +# endif +#endif + +#if !defined(SWIFT_PROTOCOL) +# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA +#endif + +#if !defined(SWIFT_EXTENSION) +# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) +#endif + +#if !defined(OBJC_DESIGNATED_INITIALIZER) +# if __has_attribute(objc_designated_initializer) +# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +# else +# define OBJC_DESIGNATED_INITIALIZER +# endif +#endif +#if !defined(SWIFT_ENUM_ATTR) +# if defined(__has_attribute) && __has_attribute(enum_extensibility) +# define SWIFT_ENUM_ATTR __attribute__((enum_extensibility(open))) +# else +# define SWIFT_ENUM_ATTR +# endif +#endif +#if !defined(SWIFT_ENUM) +# define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum SWIFT_ENUM_ATTR SWIFT_ENUM_EXTRA _name : _type +# if __has_feature(generalized_swift_name) +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR SWIFT_ENUM_EXTRA _name : _type +# else +# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) SWIFT_ENUM(_type, _name) +# endif +#endif +#if !defined(SWIFT_UNAVAILABLE) +# define SWIFT_UNAVAILABLE __attribute__((unavailable)) +#endif +#if !defined(SWIFT_UNAVAILABLE_MSG) +# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg))) +#endif +#if !defined(SWIFT_AVAILABILITY) +# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__))) +#endif +#if !defined(SWIFT_DEPRECATED) +# define SWIFT_DEPRECATED __attribute__((deprecated)) +#endif +#if !defined(SWIFT_DEPRECATED_MSG) +# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__))) +#endif +#if __has_feature(attribute_diagnose_if_objc) +# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning"))) +#else +# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg) +#endif +#if __has_feature(modules) +@import Foundation; +@import UIKit; +#endif + +#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" +#pragma clang diagnostic ignored "-Wduplicate-method-arg" +#if __has_warning("-Wpragma-clang-attribute") +# pragma clang diagnostic ignored "-Wpragma-clang-attribute" +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" +#pragma clang diagnostic ignored "-Wnullability" + +#if __has_attribute(external_source_symbol) +# pragma push_macro("any") +# undef any +# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="RileyLinkKitUI",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol)) +# pragma pop_macro("any") +#endif + + + +@class NSCoder; + +SWIFT_CLASS("_TtC14RileyLinkKitUI28RileyLinkDeviceTableViewCell") +@interface RileyLinkDeviceTableViewCell : UITableViewCell +- (nonnull instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString * _Nullable)reuseIdentifier OBJC_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER; +- (void)awakeFromNib; +- (void)layoutSubviews; +- (void)prepareForReuse; +@end + +@class UITableView; +@class NSBundle; + +SWIFT_CLASS("_TtC14RileyLinkKitUI34RileyLinkDeviceTableViewController") +@interface RileyLinkDeviceTableViewController : UITableViewController +- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER; +- (void)viewDidLoad; +- (void)viewWillAppear:(BOOL)animated; +- (void)viewWillDisappear:(BOOL)animated; +- (NSInteger)numberOfSectionsInTableView:(UITableView * _Nonnull)tableView SWIFT_WARN_UNUSED_RESULT; +- (NSInteger)tableView:(UITableView * _Nonnull)tableView numberOfRowsInSection:(NSInteger)section SWIFT_WARN_UNUSED_RESULT; +- (UITableViewCell * _Nonnull)tableView:(UITableView * _Nonnull)tableView cellForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath SWIFT_WARN_UNUSED_RESULT; +- (NSString * _Nullable)tableView:(UITableView * _Nonnull)tableView titleForHeaderInSection:(NSInteger)section SWIFT_WARN_UNUSED_RESULT; +- (BOOL)tableView:(UITableView * _Nonnull)tableView shouldHighlightRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath SWIFT_WARN_UNUSED_RESULT; +- (void)tableView:(UITableView * _Nonnull)tableView didSelectRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath; +- (nonnull instancetype)initWithStyle:(UITableViewStyle)style SWIFT_UNAVAILABLE; +- (nonnull instancetype)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil SWIFT_UNAVAILABLE; +@end + + + +@class UITextField; + +SWIFT_CLASS("_TtC14RileyLinkKitUI28TextFieldTableViewController") +@interface TextFieldTableViewController : UITableViewController +- (nonnull instancetype)init SWIFT_UNAVAILABLE; ++ (nonnull instancetype)new SWIFT_DEPRECATED_MSG("-init is unavailable"); +- (void)viewDidLoad; +- (void)viewDidAppear:(BOOL)animated; +- (NSInteger)tableView:(UITableView * _Nonnull)tableView numberOfRowsInSection:(NSInteger)section SWIFT_WARN_UNUSED_RESULT; +- (UITableViewCell * _Nonnull)tableView:(UITableView * _Nonnull)tableView cellForRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath SWIFT_WARN_UNUSED_RESULT; +- (NSString * _Nullable)tableView:(UITableView * _Nonnull)tableView titleForFooterInSection:(NSInteger)section SWIFT_WARN_UNUSED_RESULT; +- (BOOL)textFieldShouldEndEditing:(UITextField * _Nonnull)textField SWIFT_WARN_UNUSED_RESULT; +- (BOOL)textFieldShouldReturn:(UITextField * _Nonnull)textField SWIFT_WARN_UNUSED_RESULT; +- (nonnull instancetype)initWithStyle:(UITableViewStyle)style OBJC_DESIGNATED_INITIALIZER; +- (nonnull instancetype)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil OBJC_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER; +@end + + + + + +#if __has_attribute(external_source_symbol) +# pragma clang attribute pop +#endif +#pragma clang diagnostic pop diff --git a/Carthage/Build/iOS/RileyLinkKitUI.framework/Headers/RileyLinkKitUI.h b/Carthage/Build/iOS/RileyLinkKitUI.framework/Headers/RileyLinkKitUI.h new file mode 100644 index 0000000000..236c99f79c --- /dev/null +++ b/Carthage/Build/iOS/RileyLinkKitUI.framework/Headers/RileyLinkKitUI.h @@ -0,0 +1,18 @@ +// +// RileyLinkKitUI.h +// RileyLinkKitUI +// +// Copyright © 2017 Pete Schwamb. All rights reserved. +// + +#import + +//! Project version number for RileyLinkKitUI. +FOUNDATION_EXPORT double RileyLinkKitUIVersionNumber; + +//! Project version string for RileyLinkKitUI. +FOUNDATION_EXPORT const unsigned char RileyLinkKitUIVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/Carthage/Build/iOS/RileyLinkKitUI.framework/Info.plist b/Carthage/Build/iOS/RileyLinkKitUI.framework/Info.plist new file mode 100644 index 0000000000..277931a2e6 Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkKitUI.framework/Info.plist differ diff --git a/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/arm.swiftdoc b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/arm.swiftdoc new file mode 100644 index 0000000000..ff1e4cdd71 Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/arm.swiftdoc differ diff --git a/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/arm.swiftmodule b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/arm.swiftmodule new file mode 100644 index 0000000000..a6529ab2b2 Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/arm.swiftmodule differ diff --git a/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/arm64.swiftdoc b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/arm64.swiftdoc new file mode 100644 index 0000000000..4082c8ca6c Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/arm64.swiftdoc differ diff --git a/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/arm64.swiftmodule b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/arm64.swiftmodule new file mode 100644 index 0000000000..fe50a6db5b Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/arm64.swiftmodule differ diff --git a/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/i386.swiftdoc b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/i386.swiftdoc new file mode 100644 index 0000000000..6a900caf68 Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/i386.swiftdoc differ diff --git a/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/i386.swiftmodule b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/i386.swiftmodule new file mode 100644 index 0000000000..d70d4a8750 Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/i386.swiftmodule differ diff --git a/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/x86_64.swiftdoc b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/x86_64.swiftdoc new file mode 100644 index 0000000000..9347052a5b Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/x86_64.swiftdoc differ diff --git a/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/x86_64.swiftmodule b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/x86_64.swiftmodule new file mode 100644 index 0000000000..72dbb65486 Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/RileyLinkKitUI.swiftmodule/x86_64.swiftmodule differ diff --git a/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/module.modulemap b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/module.modulemap new file mode 100644 index 0000000000..a1d1cc1793 --- /dev/null +++ b/Carthage/Build/iOS/RileyLinkKitUI.framework/Modules/module.modulemap @@ -0,0 +1,11 @@ +framework module RileyLinkKitUI { + umbrella header "RileyLinkKitUI.h" + + export * + module * { export * } +} + +module RileyLinkKitUI.Swift { + header "RileyLinkKitUI-Swift.h" + requires objc +} diff --git a/Carthage/Build/iOS/RileyLinkKitUI.framework/RileyLinkKitUI b/Carthage/Build/iOS/RileyLinkKitUI.framework/RileyLinkKitUI new file mode 100755 index 0000000000..e535b2c3da Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkKitUI.framework/RileyLinkKitUI differ diff --git a/Carthage/Build/iOS/RileyLinkKitUI.framework/TextFieldTableViewCell.nib b/Carthage/Build/iOS/RileyLinkKitUI.framework/TextFieldTableViewCell.nib new file mode 100644 index 0000000000..ce1a4b7986 Binary files /dev/null and b/Carthage/Build/iOS/RileyLinkKitUI.framework/TextFieldTableViewCell.nib differ diff --git a/Carthage/Build/iOS/xDripG5.framework/Headers/xDripG5.h b/Carthage/Build/iOS/xDripG5.framework/Headers/xDripG5.h deleted file mode 100644 index 3b949160bf..0000000000 --- a/Carthage/Build/iOS/xDripG5.framework/Headers/xDripG5.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// xDripG5.h -// xDripG5 -// -// Created by Nathan Racklyeft on 12/30/15. -// Copyright © 2015 Nathan Racklyeft. All rights reserved. -// - -#import -#import - -//! Project version number for xDripG5. -FOUNDATION_EXPORT double xDripG5VersionNumber; - -//! Project version string for xDripG5. -FOUNDATION_EXPORT const unsigned char xDripG5VersionString[]; - diff --git a/Carthage/Build/iOS/xDripG5.framework/Modules/module.modulemap b/Carthage/Build/iOS/xDripG5.framework/Modules/module.modulemap deleted file mode 100644 index b06c009300..0000000000 --- a/Carthage/Build/iOS/xDripG5.framework/Modules/module.modulemap +++ /dev/null @@ -1,11 +0,0 @@ -framework module xDripG5 { - umbrella header "xDripG5.h" - - export * - module * { export * } -} - -module xDripG5.Swift { - header "xDripG5-Swift.h" - requires objc -} diff --git a/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/arm.swiftdoc b/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/arm.swiftdoc deleted file mode 100644 index a899917d94..0000000000 Binary files a/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/arm.swiftdoc and /dev/null differ diff --git a/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/arm.swiftmodule b/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/arm.swiftmodule deleted file mode 100644 index 5f74c75ae9..0000000000 Binary files a/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/arm.swiftmodule and /dev/null differ diff --git a/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/arm64.swiftdoc b/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/arm64.swiftdoc deleted file mode 100644 index 3275fb60f7..0000000000 Binary files a/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/arm64.swiftdoc and /dev/null differ diff --git a/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/arm64.swiftmodule b/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/arm64.swiftmodule deleted file mode 100644 index 91875a8116..0000000000 Binary files a/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/arm64.swiftmodule and /dev/null differ diff --git a/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/i386.swiftdoc b/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/i386.swiftdoc deleted file mode 100644 index 14d737c598..0000000000 Binary files a/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/i386.swiftdoc and /dev/null differ diff --git a/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/i386.swiftmodule b/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/i386.swiftmodule deleted file mode 100644 index ed515c50b4..0000000000 Binary files a/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/i386.swiftmodule and /dev/null differ diff --git a/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/x86_64.swiftdoc b/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/x86_64.swiftdoc deleted file mode 100644 index b3b2dee8c7..0000000000 Binary files a/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/x86_64.swiftdoc and /dev/null differ diff --git a/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/x86_64.swiftmodule b/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/x86_64.swiftmodule deleted file mode 100644 index 6b10f6298a..0000000000 Binary files a/Carthage/Build/iOS/xDripG5.framework/Modules/xDripG5.swiftmodule/x86_64.swiftmodule and /dev/null differ diff --git a/Carthage/Build/iOS/xDripG5.framework/xDripG5 b/Carthage/Build/iOS/xDripG5.framework/xDripG5 deleted file mode 100755 index 89f4cb3d5a..0000000000 Binary files a/Carthage/Build/iOS/xDripG5.framework/xDripG5 and /dev/null differ diff --git a/Common/Extensions/NumberFormatter.swift b/Common/Extensions/NumberFormatter.swift index b3f41c0fca..785a185676 100644 --- a/Common/Extensions/NumberFormatter.swift +++ b/Common/Extensions/NumberFormatter.swift @@ -36,6 +36,14 @@ extension NumberFormatter { ) } + func decibleString(from decibles: Int?) -> String? { + if let decibles = decibles { + return string(from: Double(decibles), unit: "dB") + } else { + return nil + } + } + func describingGlucose(_ value: Double, for unit: HKUnit) -> String? { return string(from: value, unit: unit.glucoseUnitDisplayString) } diff --git a/Common/Models/GlucoseRangeScheduleOverrideUserInfo.swift b/Common/Models/GlucoseRangeScheduleOverrideUserInfo.swift new file mode 100644 index 0000000000..651d425fe4 --- /dev/null +++ b/Common/Models/GlucoseRangeScheduleOverrideUserInfo.swift @@ -0,0 +1,71 @@ +// +// GlucoseRangeScheduleOverrideUserInfo.swift +// Loop +// +// Created by Michael Pangburn on 12/30/17. +// Copyright © 2017 LoopKit Authors. All rights reserved. +// + +import Foundation + + +struct GlucoseRangeScheduleOverrideUserInfo { + enum Context: Int { + case workout + case preMeal + + static var allContexts: [Context] { + return [.workout, .preMeal] + } + } + + let context: Context + let startDate: Date + let endDate: Date? + + var effectiveEndDate: Date { + return endDate ?? .distantFuture + } +} + +extension GlucoseRangeScheduleOverrideUserInfo: RawRepresentable { + typealias RawValue = [String: Any] + + static let version = 1 + static let name = "GlucoseRangeScheduleOverrideUserInfo" + + init?(rawValue: RawValue) { + guard rawValue["v"] as? Int == type(of: self).version && rawValue["name"] as? String == GlucoseRangeScheduleOverrideUserInfo.name, + let contextRawValue = rawValue["context"] as? Int, + let context = Context(rawValue: contextRawValue), + let startDate = rawValue["startDate"] as? Date else + { + return nil + } + + self.context = context + self.startDate = startDate + self.endDate = rawValue["endDate"] as? Date + } + + var rawValue: RawValue { + var raw: RawValue = [ + "v": type(of: self).version, + "name": type(of: self).name, + "context": context.rawValue, + "startDate": startDate + ] + + if let endDate = endDate { + raw["endDate"] = endDate + } + + return raw + } + + /// The "raw value" of an override message intended to clear any active override + static let clearOverride: RawValue = [ + "v": version, + "name": name + ] +} diff --git a/Common/Models/StatusExtensionContext.swift b/Common/Models/StatusExtensionContext.swift index 9430895822..eb61df6dbd 100644 --- a/Common/Models/StatusExtensionContext.swift +++ b/Common/Models/StatusExtensionContext.swift @@ -257,10 +257,7 @@ extension DatedRangeContext: RawRepresentable { return nil } - self.startDate = startDate - self.endDate = endDate - self.minValue = minValue - self.maxValue = maxValue + self.init(startDate: startDate, endDate: endDate, minValue: minValue, maxValue: maxValue) } } @@ -287,7 +284,7 @@ struct StatusExtensionContext: RawRepresentable { } if let rawValue = rawValue["glucose"] as? [GlucoseContext.RawValue] { - glucose = rawValue.flatMap({return GlucoseContext(rawValue: $0)}) + glucose = rawValue.compactMap({return GlucoseContext(rawValue: $0)}) } if let rawValue = rawValue["predictedGlucose"] as? PredictedGlucoseContext.RawValue { @@ -311,7 +308,7 @@ struct StatusExtensionContext: RawRepresentable { activeInsulin = rawValue["activeInsulin"] as? Double if let rawValue = rawValue["targetRanges"] as? [DatedRangeContext.RawValue] { - targetRanges = rawValue.flatMap({return DatedRangeContext(rawValue: $0)}) + targetRanges = rawValue.compactMap({return DatedRangeContext(rawValue: $0)}) } if let rawValue = rawValue["temporaryOverride"] as? DatedRangeContext.RawValue { diff --git a/Common/Models/WatchContext.swift b/Common/Models/WatchContext.swift index e5e7af322f..1a3bb4da5e 100644 --- a/Common/Models/WatchContext.swift +++ b/Common/Models/WatchContext.swift @@ -22,6 +22,9 @@ final class WatchContext: NSObject, RawRepresentable { var eventualGlucose: HKQuantity? var glucoseDate: Date? + var glucoseRangeScheduleOverride: GlucoseRangeScheduleOverrideUserInfo? + var configuredOverrideContexts: [GlucoseRangeScheduleOverrideUserInfo.Context] = [] + var loopLastRunDate: Date? var lastNetTempBasalDose: Double? var lastNetTempBasalDate: Date? @@ -66,6 +69,16 @@ final class WatchContext: NSObject, RawRepresentable { glucoseTrendRawValue = rawValue["gt"] as? Int glucoseDate = rawValue["gd"] as? Date + if let overrideUserInfoRawValue = rawValue["grsoc"] as? GlucoseRangeScheduleOverrideUserInfo.RawValue, + let overrideUserInfo = GlucoseRangeScheduleOverrideUserInfo(rawValue: overrideUserInfoRawValue) + { + glucoseRangeScheduleOverride = overrideUserInfo + } + + if let configuredOverrideContextsRawValues = rawValue["coc"] as? [GlucoseRangeScheduleOverrideUserInfo.Context.RawValue] { + configuredOverrideContexts = configuredOverrideContextsRawValues.compactMap(GlucoseRangeScheduleOverrideUserInfo.Context.init(rawValue:)) + } + IOB = rawValue["iob"] as? Double reservoir = rawValue["r"] as? Double reservoirPercentage = rawValue["rp"] as? Double @@ -97,6 +110,8 @@ final class WatchContext: NSObject, RawRepresentable { raw["gt"] = glucoseTrendRawValue raw["gd"] = glucoseDate + raw["grsoc"] = glucoseRangeScheduleOverride?.rawValue + raw["coc"] = configuredOverrideContexts.map { $0.rawValue } raw["iob"] = IOB raw["ld"] = loopLastRunDate raw["mb"] = maxBolus diff --git a/DoseMathTests/DoseMathTests.swift b/DoseMathTests/DoseMathTests.swift index e28f2fd4cf..f54990834b 100644 --- a/DoseMathTests/DoseMathTests.swift +++ b/DoseMathTests/DoseMathTests.swift @@ -326,7 +326,7 @@ class RecommendTempBasalTests: XCTestCase { lastTempBasal: nil ) - XCTAssertEqualWithAccuracy(1.425, dose!.unitsPerHour, accuracy: 1.0 / 40.0) + XCTAssertEqual(1.425, dose!.unitsPerHour, accuracy: 1.0 / 40.0) XCTAssertEqual(TimeInterval(minutes: 30), dose!.duration) } @@ -344,7 +344,7 @@ class RecommendTempBasalTests: XCTestCase { lastTempBasal: nil ) - XCTAssertEqualWithAccuracy(1.475, dose!.unitsPerHour, accuracy: 1.0 / 40.0) + XCTAssertEqual(1.475, dose!.unitsPerHour, accuracy: 1.0 / 40.0) XCTAssertEqual(TimeInterval(minutes: 30), dose!.duration) } @@ -379,7 +379,7 @@ class RecommendTempBasalTests: XCTestCase { lastTempBasal: nil ) - XCTAssertEqualWithAccuracy(2.975, dose!.unitsPerHour, accuracy: 1.0 / 40.0) + XCTAssertEqual(2.975, dose!.unitsPerHour, accuracy: 1.0 / 40.0) XCTAssertEqual(TimeInterval(minutes: 30), dose!.duration) } @@ -682,7 +682,7 @@ class RecommendBolusTests: XCTestCase { maxBolus: maxBolus ) - XCTAssertEqualWithAccuracy(1.575, dose.amount, accuracy: 1.0 / 40.0) + XCTAssertEqual(1.575, dose.amount, accuracy: 1.0 / 40.0) } func testHighAndFalling() { @@ -698,7 +698,7 @@ class RecommendBolusTests: XCTestCase { maxBolus: maxBolus ) - XCTAssertEqualWithAccuracy(0.325, dose.amount, accuracy: 1.0 / 40.0) + XCTAssertEqual(0.325, dose.amount, accuracy: 1.0 / 40.0) } func testInRangeAndRising() { @@ -714,7 +714,7 @@ class RecommendBolusTests: XCTestCase { maxBolus: maxBolus ) - XCTAssertEqualWithAccuracy(0.325, dose.amount, accuracy: 1.0 / 40.0) + XCTAssertEqual(0.325, dose.amount, accuracy: 1.0 / 40.0) // Less existing temp @@ -728,7 +728,7 @@ class RecommendBolusTests: XCTestCase { maxBolus: maxBolus ) - XCTAssertEqualWithAccuracy(0, dose.amount, accuracy: 1e-13) + XCTAssertEqual(0, dose.amount, accuracy: .ulpOfOne) } func testStartLowEndJustAboveRange() { @@ -775,7 +775,7 @@ class RecommendBolusTests: XCTestCase { maxBolus: maxBolus ) - XCTAssertEqualWithAccuracy(1.25, dose.amount, accuracy: 1.0 / 40.0) + XCTAssertEqual(1.25, dose.amount, accuracy: 1.0 / 40.0) } func testRiseAfterDIA() { diff --git a/DoseMathTests/Info.plist b/DoseMathTests/Info.plist index 766853d4a4..5bd34daaf6 100644 --- a/DoseMathTests/Info.plist +++ b/DoseMathTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.5.3 + 1.5.4 CFBundleSignature ???? CFBundleVersion diff --git a/Loop Status Extension/Info.plist b/Loop Status Extension/Info.plist index ce93395a48..dc0776ea87 100644 --- a/Loop Status Extension/Info.plist +++ b/Loop Status Extension/Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 1.5.3 + 1.5.4 CFBundleVersion $(CURRENT_PROJECT_VERSION) AppGroupIdentifier diff --git a/Loop.xcodeproj/project.pbxproj b/Loop.xcodeproj/project.pbxproj index 2ae66a22c0..f2db8960cc 100644 --- a/Loop.xcodeproj/project.pbxproj +++ b/Loop.xcodeproj/project.pbxproj @@ -52,6 +52,8 @@ 434FF1EA1CF26C29000DB779 /* IdentifiableClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434FF1E91CF26C29000DB779 /* IdentifiableClass.swift */; }; 434FF1EE1CF27EEF000DB779 /* UITableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 434FF1ED1CF27EEF000DB779 /* UITableViewCell.swift */; }; 43523EDB1CC35083001850F1 /* RileyLinkKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43523EDA1CC35083001850F1 /* RileyLinkKit.framework */; }; + 4353D176203D4D3C007B4ECD /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4353D175203D4D3C007B4ECD /* HealthKit.framework */; }; + 4353D178203D4DDA007B4ECD /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4353D177203D4DDA007B4ECD /* CoreBluetooth.framework */; }; 435400311C9F744E00D5819C /* BolusSuggestionUserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435400301C9F744E00D5819C /* BolusSuggestionUserInfo.swift */; }; 435400321C9F745500D5819C /* BolusSuggestionUserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435400301C9F744E00D5819C /* BolusSuggestionUserInfo.swift */; }; 435400341C9F878D00D5819C /* SetBolusUserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 435400331C9F878D00D5819C /* SetBolusUserInfo.swift */; }; @@ -67,6 +69,8 @@ 43776F901B8022E90074EA36 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43776F8F1B8022E90074EA36 /* AppDelegate.swift */; }; 43776F971B8022E90074EA36 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 43776F951B8022E90074EA36 /* Main.storyboard */; }; 43776F991B8022E90074EA36 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 43776F981B8022E90074EA36 /* Assets.xcassets */; }; + 437AFEE42035252A008C4892 /* RileyLinkBLEKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 434AB0B11CBB4C3300422F4A /* RileyLinkBLEKit.framework */; }; + 437AFEE520352591008C4892 /* NotificationCenter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F70C1DD1DE8DCA7006380B7 /* NotificationCenter.framework */; }; 437CCADA1D284ADF0075D2C3 /* AuthenticationTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437CCAD91D284ADF0075D2C3 /* AuthenticationTableViewCell.swift */; }; 437CCADC1D284B830075D2C3 /* ButtonTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437CCADB1D284B830075D2C3 /* ButtonTableViewCell.swift */; }; 437CCADE1D2858FD0075D2C3 /* AuthenticationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437CCADD1D2858FD0075D2C3 /* AuthenticationViewController.swift */; }; @@ -81,12 +85,11 @@ 438849EC1D29EC34003B3F23 /* AmplitudeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 438849EB1D29EC34003B3F23 /* AmplitudeService.swift */; }; 438849EE1D2A1EBB003B3F23 /* MLabService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 438849ED1D2A1EBB003B3F23 /* MLabService.swift */; }; 4389916B1E91B689000EEF90 /* ChartSettings+Loop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4389916A1E91B689000EEF90 /* ChartSettings+Loop.swift */; }; - 438A95A81D8B9B24009D12E1 /* xDripG5.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 438A95A71D8B9B24009D12E1 /* xDripG5.framework */; }; + 438A95A81D8B9B24009D12E1 /* CGMBLEKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 438A95A71D8B9B24009D12E1 /* CGMBLEKit.framework */; }; 438D42F91D7C88BC003244B0 /* PredictionInputEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 438D42F81D7C88BC003244B0 /* PredictionInputEffect.swift */; }; 438D42FB1D7D11A4003244B0 /* PredictionInputEffectTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 438D42FA1D7D11A4003244B0 /* PredictionInputEffectTableViewCell.swift */; }; 43947D731F529FAA00A07D31 /* GlucoseRangeSchedule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C513181E864C4E001547C7 /* GlucoseRangeSchedule.swift */; }; 439897371CD2F80600223065 /* AnalyticsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439897361CD2F80600223065 /* AnalyticsManager.swift */; }; - 4398973B1CD2FC2000223065 /* NSDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4398973A1CD2FC2000223065 /* NSDateFormatter.swift */; }; 439BED2A1E76093C00B0AED5 /* CGMManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439BED291E76093C00B0AED5 /* CGMManager.swift */; }; 439BED2C1E760A7A00B0AED5 /* DexCGMManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439BED2B1E760A7A00B0AED5 /* DexCGMManager.swift */; }; 439BED2E1E760BC600B0AED5 /* EnliteCGMManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 439BED2D1E760BC600B0AED5 /* EnliteCGMManager.swift */; }; @@ -95,7 +98,6 @@ 43A567691C94880B00334FAC /* LoopDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43A567681C94880B00334FAC /* LoopDataManager.swift */; }; 43A5676B1C96155700334FAC /* SwitchTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43A5676A1C96155700334FAC /* SwitchTableViewCell.swift */; }; 43A943761B926B7B0051FA24 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 43A943741B926B7B0051FA24 /* Interface.storyboard */; }; - 43A943781B926B7B0051FA24 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 43A943771B926B7B0051FA24 /* Assets.xcassets */; }; 43A9437F1B926B7B0051FA24 /* WatchApp Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 43A9437E1B926B7B0051FA24 /* WatchApp Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 43A943881B926B7B0051FA24 /* ExtensionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43A943871B926B7B0051FA24 /* ExtensionDelegate.swift */; }; 43A9438A1B926B7B0051FA24 /* NotificationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43A943891B926B7B0051FA24 /* NotificationController.swift */; }; @@ -195,7 +197,6 @@ 4F526D611DF8D9A900A04910 /* NetBasal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F526D601DF8D9A900A04910 /* NetBasal.swift */; }; 4F526D621DF9D95200A04910 /* NSBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 430DA58D1D4AEC230097D1CA /* NSBundle.swift */; }; 4F6663941E905FD2009E74FC /* ChartColorPalette+Loop.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F6663931E905FD2009E74FC /* ChartColorPalette+Loop.swift */; }; - 4F70C1DE1DE8DCA7006380B7 /* NotificationCenter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F70C1DD1DE8DCA7006380B7 /* NotificationCenter.framework */; }; 4F70C1E11DE8DCA7006380B7 /* StatusViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F70C1E01DE8DCA7006380B7 /* StatusViewController.swift */; }; 4F70C1E41DE8DCA7006380B7 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4F70C1E21DE8DCA7006380B7 /* MainInterface.storyboard */; }; 4F70C1E81DE8DCA7006380B7 /* Loop Status Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 4F70C1DC1DE8DCA7006380B7 /* Loop Status Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; @@ -247,6 +248,9 @@ 7D70765E1FE06EE3004AC8EA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D7076601FE06EE3004AC8EA /* Localizable.strings */; }; 7D7076631FE06EE4004AC8EA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D7076651FE06EE4004AC8EA /* Localizable.strings */; }; 7D7076681FE0702F004AC8EA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7D70766A1FE0702F004AC8EA /* InfoPlist.strings */; }; + 894B91CD1FF9F45900DA65F5 /* GlucoseRangeScheduleOverrideUserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 894B91CC1FF9F45900DA65F5 /* GlucoseRangeScheduleOverrideUserInfo.swift */; }; + 894B91CE1FF9F45900DA65F5 /* GlucoseRangeScheduleOverrideUserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 894B91CC1FF9F45900DA65F5 /* GlucoseRangeScheduleOverrideUserInfo.swift */; }; + 894F71E21FFEC4D8007D365C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 894F71E11FFEC4D8007D365C /* Assets.xcassets */; }; C10428971D17BAD400DD539A /* NightscoutUploadKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C10428961D17BAD400DD539A /* NightscoutUploadKit.framework */; }; C10B28461EA9BA5E006EA1FC /* far_future_high_bg_forecast.json in Resources */ = {isa = PBXBuildFile; fileRef = C10B28451EA9BA5E006EA1FC /* far_future_high_bg_forecast.json */; }; C11C87DD1E21E53500BB71D3 /* GlucoseThreshold.swift in Sources */ = {isa = PBXBuildFile; fileRef = C178249D1E19B62300D9D25C /* GlucoseThreshold.swift */; }; @@ -260,6 +264,7 @@ C17824A31E19EAB600D9D25C /* recommend_temp_basal_start_very_low_end_high.json in Resources */ = {isa = PBXBuildFile; fileRef = C17824A21E19EAB600D9D25C /* recommend_temp_basal_start_very_low_end_high.json */; }; C17824A51E1AD4D100D9D25C /* BolusRecommendation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C17824A41E1AD4D100D9D25C /* BolusRecommendation.swift */; }; C17824A61E1AF91F00D9D25C /* BolusRecommendation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C17824A41E1AD4D100D9D25C /* BolusRecommendation.swift */; }; + C18852E22082AB1B00BECC8C /* RileyLinkKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C18852E12082AB1A00BECC8C /* RileyLinkKitUI.framework */; }; C18C8C511D5A351900E043FB /* NightscoutDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C18C8C501D5A351900E043FB /* NightscoutDataManager.swift */; }; C1C6591C1E1B1FDA0025CC58 /* recommend_temp_basal_dropping_then_rising.json in Resources */ = {isa = PBXBuildFile; fileRef = C1C6591B1E1B1FDA0025CC58 /* recommend_temp_basal_dropping_then_rising.json */; }; C1C73F0D1DE3D0270022FC89 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C1C73F0F1DE3D0270022FC89 /* InfoPlist.strings */; }; @@ -416,19 +421,21 @@ 43441A9B1EDB34810087958C /* StatusExtensionContext+LoopKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "StatusExtensionContext+LoopKit.swift"; sourceTree = ""; }; 43441A9F1EDB4D390087958C /* OSLog.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OSLog.swift; sourceTree = ""; }; 4346D1E61C77F5FE00ABAFE3 /* ChartTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ChartTableViewCell.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - 4346D1EF1C781BEA00ABAFE3 /* SwiftCharts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftCharts.framework; path = Carthage/Build/iOS/SwiftCharts.framework; sourceTree = ""; }; + 4346D1EF1C781BEA00ABAFE3 /* SwiftCharts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftCharts.framework; path = Carthage/Build/iOS/SwiftCharts.framework; sourceTree = SOURCE_ROOT; }; 4346D1F51C78501000ABAFE3 /* ChartPoint+Loop.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ChartPoint+Loop.swift"; sourceTree = ""; }; - 434AB0B11CBB4C3300422F4A /* RileyLinkBLEKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RileyLinkBLEKit.framework; path = Carthage/Build/iOS/RileyLinkBLEKit.framework; sourceTree = ""; }; + 434AB0B11CBB4C3300422F4A /* RileyLinkBLEKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RileyLinkBLEKit.framework; path = Carthage/Build/iOS/RileyLinkBLEKit.framework; sourceTree = SOURCE_ROOT; }; 434F54561D287FDB002A9274 /* NibLoadable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NibLoadable.swift; sourceTree = ""; }; 434F54581D28805E002A9274 /* ButtonTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ButtonTableViewCell.xib; sourceTree = ""; }; 434F545A1D2880D4002A9274 /* AuthenticationTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = AuthenticationTableViewCell.xib; sourceTree = ""; }; 434F545E1D288345002A9274 /* ShareService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShareService.swift; sourceTree = ""; }; 434F54601D28859B002A9274 /* ServiceCredential.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServiceCredential.swift; sourceTree = ""; }; 434F54621D28DD80002A9274 /* ValidatingIndicatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidatingIndicatorView.swift; sourceTree = ""; }; - 434FB6451D68F1CD007B9C70 /* Amplitude.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Amplitude.framework; path = Carthage/Build/iOS/Amplitude.framework; sourceTree = ""; }; + 434FB6451D68F1CD007B9C70 /* Amplitude.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Amplitude.framework; path = Carthage/Build/iOS/Amplitude.framework; sourceTree = SOURCE_ROOT; }; 434FF1E91CF26C29000DB779 /* IdentifiableClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IdentifiableClass.swift; sourceTree = ""; }; 434FF1ED1CF27EEF000DB779 /* UITableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITableViewCell.swift; sourceTree = ""; }; - 43523EDA1CC35083001850F1 /* RileyLinkKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RileyLinkKit.framework; path = Carthage/Build/iOS/RileyLinkKit.framework; sourceTree = ""; }; + 43523EDA1CC35083001850F1 /* RileyLinkKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RileyLinkKit.framework; path = Carthage/Build/iOS/RileyLinkKit.framework; sourceTree = SOURCE_ROOT; }; + 4353D175203D4D3C007B4ECD /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS4.2.sdk/System/Library/Frameworks/HealthKit.framework; sourceTree = DEVELOPER_DIR; }; + 4353D177203D4DDA007B4ECD /* CoreBluetooth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreBluetooth.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS4.2.sdk/System/Library/Frameworks/CoreBluetooth.framework; sourceTree = DEVELOPER_DIR; }; 435400301C9F744E00D5819C /* BolusSuggestionUserInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BolusSuggestionUserInfo.swift; sourceTree = ""; }; 435400331C9F878D00D5819C /* SetBolusUserInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetBolusUserInfo.swift; sourceTree = ""; }; 435CB6221F37967800C320C7 /* InsulinModelSettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InsulinModelSettingsViewController.swift; sourceTree = ""; }; @@ -466,13 +473,12 @@ 438849ED1D2A1EBB003B3F23 /* MLabService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MLabService.swift; sourceTree = ""; }; 438991661E91B563000EEF90 /* ChartPoint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChartPoint.swift; sourceTree = ""; }; 4389916A1E91B689000EEF90 /* ChartSettings+Loop.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ChartSettings+Loop.swift"; sourceTree = ""; }; - 438A95A71D8B9B24009D12E1 /* xDripG5.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = xDripG5.framework; path = Carthage/Build/iOS/xDripG5.framework; sourceTree = ""; }; + 438A95A71D8B9B24009D12E1 /* CGMBLEKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CGMBLEKit.framework; path = Carthage/Build/iOS/CGMBLEKit.framework; sourceTree = SOURCE_ROOT; }; 438D42F81D7C88BC003244B0 /* PredictionInputEffect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PredictionInputEffect.swift; sourceTree = ""; }; 438D42FA1D7D11A4003244B0 /* PredictionInputEffectTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PredictionInputEffectTableViewCell.swift; sourceTree = ""; }; 438DADC71CDE8F8B007697A5 /* LoopStateView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoopStateView.swift; sourceTree = ""; }; 439897341CD2F7DE00223065 /* NSTimeInterval.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSTimeInterval.swift; sourceTree = ""; }; 439897361CD2F80600223065 /* AnalyticsManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = AnalyticsManager.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; - 4398973A1CD2FC2000223065 /* NSDateFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSDateFormatter.swift; sourceTree = ""; }; 439BED291E76093C00B0AED5 /* CGMManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGMManager.swift; sourceTree = ""; }; 439BED2B1E760A7A00B0AED5 /* DexCGMManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DexCGMManager.swift; sourceTree = ""; }; 439BED2D1E760BC600B0AED5 /* EnliteCGMManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnliteCGMManager.swift; sourceTree = ""; }; @@ -482,7 +488,6 @@ 43A5676A1C96155700334FAC /* SwitchTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwitchTableViewCell.swift; sourceTree = ""; }; 43A943721B926B7B0051FA24 /* WatchApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WatchApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 43A943751B926B7B0051FA24 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = ""; }; - 43A943771B926B7B0051FA24 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 43A9437E1B926B7B0051FA24 /* WatchApp Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "WatchApp Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 43A943841B926B7B0051FA24 /* PushNotificationPayload.apns */ = {isa = PBXFileReference; lastKnownFileType = text; path = PushNotificationPayload.apns; sourceTree = ""; }; 43A943871B926B7B0051FA24 /* ExtensionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDelegate.swift; sourceTree = ""; }; @@ -492,7 +497,7 @@ 43A943911B926B7B0051FA24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 43B260481ED248FB008CAA77 /* CarbEntryTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CarbEntryTableViewCell.swift; sourceTree = ""; }; 43B371851CE583890013C5A6 /* BasalStateView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasalStateView.swift; sourceTree = ""; }; - 43B371871CE597D10013C5A6 /* ShareClient.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ShareClient.framework; path = Carthage/Build/iOS/ShareClient.framework; sourceTree = ""; }; + 43B371871CE597D10013C5A6 /* ShareClient.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ShareClient.framework; path = Carthage/Build/iOS/ShareClient.framework; sourceTree = SOURCE_ROOT; }; 43BFF0B11E45C18400FF19A9 /* UIColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIColor.swift; sourceTree = ""; }; 43BFF0B31E45C1BE00FF19A9 /* NumberFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumberFormatter.swift; sourceTree = ""; }; 43BFF0BB1E45C80600FF19A9 /* UIColor+Loop.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Loop.swift"; sourceTree = ""; }; @@ -502,12 +507,12 @@ 43BFF0CA1E466C0900FF19A9 /* StateColorPalette.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StateColorPalette.swift; sourceTree = ""; }; 43BFF0CC1E466C8400FF19A9 /* StateColorPalette.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StateColorPalette.swift; sourceTree = ""; }; 43C094491CACCC73001F6403 /* NotificationManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationManager.swift; sourceTree = ""; }; - 43C246A71D89990F0031F8D1 /* Crypto.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Crypto.framework; path = Carthage/Build/iOS/Crypto.framework; sourceTree = ""; }; + 43C246A71D89990F0031F8D1 /* Crypto.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Crypto.framework; path = Carthage/Build/iOS/Crypto.framework; sourceTree = SOURCE_ROOT; }; 43C2FAE01EB656A500364AFF /* GlucoseEffectVelocity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlucoseEffectVelocity.swift; sourceTree = ""; }; 43C418B41CE0575200405B6A /* ShareGlucose+GlucoseKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ShareGlucose+GlucoseKit.swift"; sourceTree = ""; }; 43C513181E864C4E001547C7 /* GlucoseRangeSchedule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlucoseRangeSchedule.swift; sourceTree = ""; }; 43C6407B1DA051850093E25D /* InsulinKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = InsulinKit.framework; path = Carthage/Build/iOS/InsulinKit.framework; sourceTree = ""; }; - 43CA93361CB98079000026B5 /* MinimedKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MinimedKit.framework; path = Carthage/Build/iOS/MinimedKit.framework; sourceTree = ""; }; + 43CA93361CB98079000026B5 /* MinimedKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MinimedKit.framework; path = Carthage/Build/iOS/MinimedKit.framework; sourceTree = SOURCE_ROOT; }; 43CB2B2A1D924D450079823D /* WCSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WCSession.swift; sourceTree = ""; }; 43CE7CDD1CA8B63E003CC1B0 /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; 43CEE6E51E56AFD400CB9116 /* NightscoutUploader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NightscoutUploader.swift; sourceTree = ""; }; @@ -558,9 +563,9 @@ 43F78D251C8FC000002152D1 /* DoseMath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoseMath.swift; sourceTree = ""; }; 43F78D481C914197002152D1 /* CarbKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CarbKit.framework; path = Carthage/Build/iOS/CarbKit.framework; sourceTree = ""; }; 43F78D491C914197002152D1 /* GlucoseKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GlucoseKit.framework; path = Carthage/Build/iOS/GlucoseKit.framework; sourceTree = ""; }; - 43F78D4B1C914197002152D1 /* LoopKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LoopKit.framework; path = Carthage/Build/iOS/LoopKit.framework; sourceTree = ""; }; + 43F78D4B1C914197002152D1 /* LoopKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LoopKit.framework; path = Carthage/Build/iOS/LoopKit.framework; sourceTree = SOURCE_ROOT; }; 43FBEDD71D73843700B21F22 /* LevelMaskView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LevelMaskView.swift; sourceTree = ""; }; - 4D3B40021D4A9DFE00BC6334 /* G4ShareSpy.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = G4ShareSpy.framework; path = Carthage/Build/iOS/G4ShareSpy.framework; sourceTree = ""; }; + 4D3B40021D4A9DFE00BC6334 /* G4ShareSpy.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = G4ShareSpy.framework; path = Carthage/Build/iOS/G4ShareSpy.framework; sourceTree = SOURCE_ROOT; }; 4D5B7A4A1D457CCA00796CA9 /* GlucoseG4.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GlucoseG4.swift; path = Loop/Models/GlucoseG4.swift; sourceTree = SOURCE_ROOT; }; 4F08DE7C1E7BB6E5006741EA /* ChartAxisValueDoubleLog.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChartAxisValueDoubleLog.swift; sourceTree = ""; }; 4F08DE7D1E7BB6E5006741EA /* ChartAxisValueDoubleUnit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChartAxisValueDoubleUnit.swift; sourceTree = ""; }; @@ -625,7 +630,9 @@ 7DD382771F8DBFC60071272B /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Main.strings; sourceTree = ""; }; 7DD382781F8DBFC60071272B /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/MainInterface.strings; sourceTree = ""; }; 7DD382791F8DBFC60071272B /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Interface.strings; sourceTree = ""; }; - C10428961D17BAD400DD539A /* NightscoutUploadKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NightscoutUploadKit.framework; path = Carthage/Build/iOS/NightscoutUploadKit.framework; sourceTree = ""; }; + 894B91CC1FF9F45900DA65F5 /* GlucoseRangeScheduleOverrideUserInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlucoseRangeScheduleOverrideUserInfo.swift; sourceTree = ""; }; + 894F71E11FFEC4D8007D365C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + C10428961D17BAD400DD539A /* NightscoutUploadKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NightscoutUploadKit.framework; path = Carthage/Build/iOS/NightscoutUploadKit.framework; sourceTree = SOURCE_ROOT; }; C10B28451EA9BA5E006EA1FC /* far_future_high_bg_forecast.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = far_future_high_bg_forecast.json; sourceTree = ""; }; C12F21A61DFA79CB00748193 /* recommend_temp_basal_very_low_end_in_range.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = recommend_temp_basal_very_low_end_in_range.json; sourceTree = ""; }; C15713811DAC6983005BC4D2 /* MealBolusNightscoutTreatment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MealBolusNightscoutTreatment.swift; sourceTree = ""; }; @@ -634,6 +641,7 @@ C178249F1E19CF9800D9D25C /* GlucoseThresholdTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlucoseThresholdTableViewController.swift; sourceTree = ""; }; C17824A21E19EAB600D9D25C /* recommend_temp_basal_start_very_low_end_high.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = recommend_temp_basal_start_very_low_end_high.json; sourceTree = ""; }; C17824A41E1AD4D100D9D25C /* BolusRecommendation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BolusRecommendation.swift; sourceTree = ""; }; + C18852E12082AB1A00BECC8C /* RileyLinkKitUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RileyLinkKitUI.framework; path = Carthage/Build/iOS/RileyLinkKitUI.framework; sourceTree = ""; }; C18C8C501D5A351900E043FB /* NightscoutDataManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NightscoutDataManager.swift; sourceTree = ""; }; C1C6591B1E1B1FDA0025CC58 /* recommend_temp_basal_dropping_then_rising.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = recommend_temp_basal_dropping_then_rising.json; sourceTree = ""; }; C1C73F0E1DE3D0270022FC89 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -653,20 +661,22 @@ buildActionMask = 2147483647; files = ( 4F7528941DFE1E9500C322D6 /* LoopUI.framework in Frameworks */, - 43C6407C1DA051850093E25D /* InsulinKit.framework in Frameworks */, - 438A95A81D8B9B24009D12E1 /* xDripG5.framework in Frameworks */, - 43C246A81D89990F0031F8D1 /* Crypto.framework in Frameworks */, 434FB6461D68F1CD007B9C70 /* Amplitude.framework in Frameworks */, - C10428971D17BAD400DD539A /* NightscoutUploadKit.framework in Frameworks */, 43F78D4C1C914197002152D1 /* CarbKit.framework in Frameworks */, + 43C246A81D89990F0031F8D1 /* Crypto.framework in Frameworks */, 4D3B40041D4A9E1A00BC6334 /* G4ShareSpy.framework in Frameworks */, 43F78D4D1C914197002152D1 /* GlucoseKit.framework in Frameworks */, 43F5C2C91B929C09003EB13D /* HealthKit.framework in Frameworks */, + 43C6407C1DA051850093E25D /* InsulinKit.framework in Frameworks */, 43F78D4F1C914197002152D1 /* LoopKit.framework in Frameworks */, 43CA93371CB98079000026B5 /* MinimedKit.framework in Frameworks */, + C10428971D17BAD400DD539A /* NightscoutUploadKit.framework in Frameworks */, + 437AFEE42035252A008C4892 /* RileyLinkBLEKit.framework in Frameworks */, 43523EDB1CC35083001850F1 /* RileyLinkKit.framework in Frameworks */, + C18852E22082AB1B00BECC8C /* RileyLinkKitUI.framework in Frameworks */, 43B371881CE597D10013C5A6 /* ShareClient.framework in Frameworks */, 4F08DE9B1E7BC4ED006741EA /* SwiftCharts.framework in Frameworks */, + 438A95A81D8B9B24009D12E1 /* CGMBLEKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -674,6 +684,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 4353D178203D4DDA007B4ECD /* CoreBluetooth.framework in Frameworks */, + 4353D176203D4D3C007B4ECD /* HealthKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -697,7 +709,7 @@ buildActionMask = 2147483647; files = ( 4F7528951DFE1E9B00C322D6 /* LoopUI.framework in Frameworks */, - 4F70C1DE1DE8DCA7006380B7 /* NotificationCenter.framework in Frameworks */, + 437AFEE520352591008C4892 /* NotificationCenter.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -856,8 +868,8 @@ 43A943731B926B7B0051FA24 /* WatchApp */ = { isa = PBXGroup; children = ( + 894F71E11FFEC4D8007D365C /* Assets.xcassets */, C1C73F0F1DE3D0270022FC89 /* InfoPlist.strings */, - 43A943771B926B7B0051FA24 /* Assets.xcassets */, 43F5C2D61B92A4DC003EB13D /* Info.plist */, 43A943741B926B7B0051FA24 /* Interface.storyboard */, ); @@ -941,7 +953,6 @@ C15713811DAC6983005BC4D2 /* MealBolusNightscoutTreatment.swift */, 438172D81F4E9E37003C3328 /* NewPumpEvent.swift */, 43CEE6E51E56AFD400CB9116 /* NightscoutUploader.swift */, - 4398973A1CD2FC2000223065 /* NSDateFormatter.swift */, 43E344A31B9E1B1C00C85C07 /* NSUserDefaults.swift */, 43441A9F1EDB4D390087958C /* OSLog.swift */, 4381D2251F3C0FDD004ACCF9 /* RileyLinkDevice.swift */, @@ -1132,6 +1143,7 @@ children = ( 435400301C9F744E00D5819C /* BolusSuggestionUserInfo.swift */, 43DE92581C5479E4001FFDE1 /* CarbEntryUserInfo.swift */, + 894B91CC1FF9F45900DA65F5 /* GlucoseRangeScheduleOverrideUserInfo.swift */, 43EA285E1D50ED3D001BC233 /* GlucoseTrend.swift */, 435400331C9F878D00D5819C /* SetBolusUserInfo.swift */, 4F70C2111DE900EA006380B7 /* StatusExtensionContext.swift */, @@ -1159,6 +1171,9 @@ 968DCD53F724DE56FFE51920 /* Frameworks */ = { isa = PBXGroup; children = ( + C18852E12082AB1A00BECC8C /* RileyLinkKitUI.framework */, + 4353D177203D4DDA007B4ECD /* CoreBluetooth.framework */, + 4353D175203D4D3C007B4ECD /* HealthKit.framework */, 434FB6451D68F1CD007B9C70 /* Amplitude.framework */, 43F78D481C914197002152D1 /* CarbKit.framework */, 43C246A71D89990F0031F8D1 /* Crypto.framework */, @@ -1174,7 +1189,7 @@ 43523EDA1CC35083001850F1 /* RileyLinkKit.framework */, 43B371871CE597D10013C5A6 /* ShareClient.framework */, 4346D1EF1C781BEA00ABAFE3 /* SwiftCharts.framework */, - 438A95A71D8B9B24009D12E1 /* xDripG5.framework */, + 438A95A71D8B9B24009D12E1 /* CGMBLEKit.framework */, ); name = Frameworks; sourceTree = ""; @@ -1333,7 +1348,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0730; - LastUpgradeCheck = 0900; + LastUpgradeCheck = 0930; ORGANIZATIONNAME = "LoopKit Authors"; TargetAttributes = { 43776F8B1B8022E90074EA36 = { @@ -1376,6 +1391,9 @@ com.apple.HealthKit = { enabled = 0; }; + com.apple.HealthKit.watchos = { + enabled = 1; + }; com.apple.Keychain = { enabled = 0; }; @@ -1450,8 +1468,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 43A943781B926B7B0051FA24 /* Assets.xcassets in Resources */, C1C73F0D1DE3D0270022FC89 /* InfoPlist.strings in Resources */, + 894F71E21FFEC4D8007D365C /* Assets.xcassets in Resources */, 43A943761B926B7B0051FA24 /* Interface.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1545,7 +1563,7 @@ files = ( ); inputPaths = ( - "$(SRCROOT)/Carthage/Build/iOS/xDripG5.framework", + "$(SRCROOT)/Carthage/Build/iOS/CGMBLEKit.framework", "$(SRCROOT)/Carthage/Build/iOS/CarbKit.framework", "$(SRCROOT)/Carthage/Build/iOS/GlucoseKit.framework", "$(SRCROOT)/Carthage/Build/iOS/InsulinKit.framework", @@ -1559,13 +1577,29 @@ "$(SRCROOT)/Carthage/Build/iOS/NightscoutUploadKit.framework", "$(SRCROOT)/Carthage/Build/iOS/Crypto.framework", "$(SRCROOT)/Carthage/Build/iOS/G4ShareSpy.framework", + "$(SRCROOT)/Carthage/Build/iOS/RileyLinkKitUI.framework", ); name = "Copy Frameworks with Carthage"; outputPaths = ( + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/CGMBLEKit.framework", + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/CarbKit.framework", + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/GlucoseKit.framework", + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/InsulinKit.framework", + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/LoopKit.framework", + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/SwiftCharts.framework", + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/MinimedKit.framework", + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/RileyLinkBLEKit.framework", + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/RileyLinkKit.framework", + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Amplitude.framework", + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/ShareClient.framework", + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/NightscoutUploadKit.framework", + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Crypto.framework", + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/G4ShareSpy.framework", + "$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/RileyLinkKitUI.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# /usr/local/bin/carthage build --platform \"$PLATFORM_NAME\" \"$SRCROOT\"\n# Only run this script if we're not using a workspace or installing\nif [ ! -d $PROJECT_DIR/Loop.xcworkspace ] || [ \"$ACTION\" = \"install\" ]; then\n /usr/local/bin/carthage copy-frameworks\nfi"; + shellScript = "# Rebuild using cache if we're developing in a workspace\nif [ -d $PROJECT_DIR/Loop2.xcworkspace ]; then\n /usr/local/bin/carthage build --platform \"$PLATFORM_NAME\" --cache-builds --project-directory \"$SRCROOT\"\nfi\n\n/usr/local/bin/carthage copy-frameworks"; }; /* End PBXShellScriptBuildPhase section */ @@ -1650,6 +1684,7 @@ 4F08DE8F1E7BB871006741EA /* CollectionType+Loop.swift in Sources */, 435400341C9F878D00D5819C /* SetBolusUserInfo.swift in Sources */, 437D9BA31D7BC977007245E8 /* PredictionTableViewController.swift in Sources */, + 894B91CD1FF9F45900DA65F5 /* GlucoseRangeScheduleOverrideUserInfo.swift in Sources */, 43F41C371D3BF32400C11ED6 /* UIAlertController.swift in Sources */, 433EA4C41D9F71C800CD78FB /* CommandResponseViewController.swift in Sources */, 43D2E8231F00425400AE5CBF /* BolusViewController+LoopDataManager.swift in Sources */, @@ -1658,7 +1693,6 @@ 43CEE6E61E56AFD400CB9116 /* NightscoutUploader.swift in Sources */, 4328E0331CFC091100E199AA /* WatchContext+LoopKit.swift in Sources */, 4F526D611DF8D9A900A04910 /* NetBasal.swift in Sources */, - 4398973B1CD2FC2000223065 /* NSDateFormatter.swift in Sources */, 540DED971E14C75F002B2491 /* EnliteSensorDisplayable.swift in Sources */, 436A0DA51D236A2A00104B24 /* LoopError.swift in Sources */, 435CB6231F37967800C320C7 /* InsulinModelSettingsViewController.swift in Sources */, @@ -1704,6 +1738,7 @@ 4328E02A1CFBE2C500E199AA /* UIColor.swift in Sources */, 4328E01B1CFBE1DA00E199AA /* BolusInterfaceController.swift in Sources */, 4328E02B1CFBE2C500E199AA /* WKAlertAction.swift in Sources */, + 894B91CE1FF9F45900DA65F5 /* GlucoseRangeScheduleOverrideUserInfo.swift in Sources */, 4328E0281CFBE2C500E199AA /* CLKComplicationTemplate.swift in Sources */, 4328E01E1CFBE25F00E199AA /* AddCarbsInterfaceController.swift in Sources */, 43846ADB1D91057000799272 /* ContextUpdatable.swift in Sources */, @@ -2003,12 +2038,14 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -2018,7 +2055,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer: loudnate@gmail.com (XZN842LDLT)"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 44; + CURRENT_PROJECT_VERSION = 46; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -2068,12 +2105,14 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -2083,7 +2122,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer: loudnate@gmail.com (XZN842LDLT)"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 44; + CURRENT_PROJECT_VERSION = 46; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -2149,12 +2188,13 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; + CODE_SIGN_ENTITLEMENTS = "WatchApp Extension/WatchApp Extension.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=watchos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "WatchApp Extension/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "$(MAIN_APP_BUNDLE_IDENTIFIER).watchkitapp.watchkitextension"; + PRODUCT_BUNDLE_IDENTIFIER = "$(MAIN_APP_BUNDLE_IDENTIFIER).LoopWatch.watchkitextension"; PRODUCT_NAME = "${TARGET_NAME}"; PROVISIONING_PROFILE = ""; SDKROOT = watchos; @@ -2167,12 +2207,13 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; + CODE_SIGN_ENTITLEMENTS = "WatchApp Extension/WatchApp Extension.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=watchos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "WatchApp Extension/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "$(MAIN_APP_BUNDLE_IDENTIFIER).watchkitapp.watchkitextension"; + PRODUCT_BUNDLE_IDENTIFIER = "$(MAIN_APP_BUNDLE_IDENTIFIER).LoopWatch.watchkitextension"; PRODUCT_NAME = "${TARGET_NAME}"; PROVISIONING_PROFILE = ""; SDKROOT = watchos; @@ -2192,7 +2233,7 @@ IBSC_MODULE = WatchApp_Extension; INFOPLIST_FILE = WatchApp/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "$(MAIN_APP_BUNDLE_IDENTIFIER).watchkitapp"; + PRODUCT_BUNDLE_IDENTIFIER = "$(MAIN_APP_BUNDLE_IDENTIFIER).LoopWatch"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; SDKROOT = watchos; @@ -2212,7 +2253,7 @@ IBSC_MODULE = WatchApp_Extension; INFOPLIST_FILE = WatchApp/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "$(MAIN_APP_BUNDLE_IDENTIFIER).watchkitapp"; + PRODUCT_BUNDLE_IDENTIFIER = "$(MAIN_APP_BUNDLE_IDENTIFIER).LoopWatch"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; SDKROOT = watchos; @@ -2323,11 +2364,11 @@ CLANG_WARN_SUSPICIOUS_MOVES = YES; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - CURRENT_PROJECT_VERSION = 44; + CURRENT_PROJECT_VERSION = 46; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 44; + DYLIB_CURRENT_VERSION = 46; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = LoopUI/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -2350,11 +2391,11 @@ CLANG_WARN_SUSPICIOUS_MOVES = YES; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - CURRENT_PROJECT_VERSION = 44; + CURRENT_PROJECT_VERSION = 46; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 44; + DYLIB_CURRENT_VERSION = 46; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = LoopUI/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; diff --git a/Loop.xcodeproj/xcshareddata/xcschemes/Complication - WatchApp.xcscheme b/Loop.xcodeproj/xcshareddata/xcschemes/Complication - WatchApp.xcscheme index 2d94260fca..ab563e3f5a 100644 --- a/Loop.xcodeproj/xcshareddata/xcschemes/Complication - WatchApp.xcscheme +++ b/Loop.xcodeproj/xcshareddata/xcschemes/Complication - WatchApp.xcscheme @@ -1,6 +1,6 @@ @@ -61,7 +60,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "" selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn" - language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/Loop.xcodeproj/xcshareddata/xcschemes/Loop.xcscheme b/Loop.xcodeproj/xcshareddata/xcschemes/Loop.xcscheme index b2c46e209e..301b74132b 100644 --- a/Loop.xcodeproj/xcshareddata/xcschemes/Loop.xcscheme +++ b/Loop.xcodeproj/xcshareddata/xcschemes/Loop.xcscheme @@ -1,6 +1,6 @@ + codeCoverageEnabled = "YES" + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -57,7 +56,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/Loop.xcodeproj/xcshareddata/xcschemes/LoopTests.xcscheme b/Loop.xcodeproj/xcshareddata/xcschemes/LoopTests.xcscheme index b74e4c3f3e..337f33d7fa 100644 --- a/Loop.xcodeproj/xcshareddata/xcschemes/LoopTests.xcscheme +++ b/Loop.xcodeproj/xcshareddata/xcschemes/LoopTests.xcscheme @@ -1,6 +1,6 @@ HKQuantity { return HKQuantity(unit: unit, doubleValue: value(at: date).minValue) } diff --git a/Loop/Extensions/NSDateFormatter.swift b/Loop/Extensions/NSDateFormatter.swift deleted file mode 100644 index f353a4ddb5..0000000000 --- a/Loop/Extensions/NSDateFormatter.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// NSDateFormatter.swift -// Naterade -// -// Created by Nathan Racklyeft on 11/25/15. -// Copyright © 2015 Nathan Racklyeft. All rights reserved. -// - -import Foundation - - -extension DateFormatter { - static func ISO8601StrictDateFormatter() -> Self { - let dateFormatter = self.init() - - dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" - dateFormatter.locale = Locale(identifier: "en_US_POSIX") - - return dateFormatter - } -} diff --git a/Loop/Extensions/NSUserDefaults.swift b/Loop/Extensions/NSUserDefaults.swift index 98515b8fec..88101cb1b5 100644 --- a/Loop/Extensions/NSUserDefaults.swift +++ b/Loop/Extensions/NSUserDefaults.swift @@ -11,6 +11,30 @@ import LoopKit import InsulinKit import MinimedKit import HealthKit +import RileyLinkKit + +extension UserDefaults { + static let appGroup: UserDefaults = { + let shared = UserDefaults(suiteName: Bundle.main.appGroupSuiteName) + let standard = UserDefaults.standard + + // Use an old key as a migration sentinel + if let shared = shared, standard.basalRateSchedule != nil && shared.basalRateSchedule == nil { + shared.basalRateSchedule = standard.basalRateSchedule + shared.carbRatioSchedule = standard.carbRatioSchedule + shared.cgm = standard.cgm + shared.connectedPeripheralIDs = standard.connectedPeripheralIDs + shared.loopSettings = standard.loopSettings + shared.insulinModelSettings = standard.insulinModelSettings + shared.insulinCounteractionEffects = standard.insulinCounteractionEffects + shared.insulinSensitivitySchedule = standard.insulinSensitivitySchedule + shared.preferredInsulinDataSource = standard.preferredInsulinDataSource + shared.batteryChemistry = standard.batteryChemistry + } + + return shared ?? standard + }() +} extension UserDefaults { @@ -25,10 +49,8 @@ extension UserDefaults { case insulinModelSettings = "com.loopkit.Loop.insulinModelSettings" case insulinSensitivitySchedule = "com.loudnate.Naterade.InsulinSensitivitySchedule" case preferredInsulinDataSource = "com.loudnate.Loop.PreferredInsulinDataSource" - case pumpID = "com.loudnate.Naterade.PumpID" - case pumpModelNumber = "com.loudnate.Naterade.PumpModelNumber" - case pumpRegion = "com.loopkit.Loop.PumpRegion" - case pumpTimeZone = "com.loudnate.Naterade.PumpTimeZone" + case pumpSettings = "com.loopkit.Loop.PumpSettings" + case pumpState = "com.loopkit.Loop.PumpState" } var basalRateSchedule: BasalRateSchedule? { @@ -184,7 +206,7 @@ extension UserDefaults { guard let rawValue = array(forKey: Key.insulinCounteractionEffects.rawValue) as? [GlucoseEffectVelocity.RawValue] else { return nil } - return rawValue.flatMap { + return rawValue.compactMap { GlucoseEffectVelocity(rawValue: $0) } } @@ -219,48 +241,70 @@ extension UserDefaults { } } - var pumpID: String? { + var pumpSettings: PumpSettings? { get { - return string(forKey: Key.pumpID.rawValue) - } - set { - set(newValue, forKey: Key.pumpID.rawValue) - } - } + if let raw = dictionary(forKey: Key.pumpSettings.rawValue) { + return PumpSettings(rawValue: raw) + } else { + // Migrate the version 0 case + let standard = UserDefaults.standard + defer { + standard.removeObject(forKey: "com.loudnate.Naterade.PumpID") + standard.removeObject(forKey: "com.loopkit.Loop.PumpRegion") + } - var pumpModelNumber: String? { - get { - return string(forKey: Key.pumpModelNumber.rawValue) - } - set { - set(newValue, forKey: Key.pumpModelNumber.rawValue) - } - } + guard let pumpID = standard.string(forKey: "com.loudnate.Naterade.PumpID") else { + return nil + } - var pumpRegion: PumpRegion? { - get { - // Defaults to 0 / northAmerica - return PumpRegion(rawValue: integer(forKey: Key.pumpRegion.rawValue)) + let settings = PumpSettings( + pumpID: pumpID, + // Defaults to 0 / northAmerica + pumpRegion: PumpRegion(rawValue: standard.integer(forKey: "com.loopkit.Loop.PumpRegion")) + ) + + self.pumpSettings = settings + + return settings + } } set { - set(newValue?.rawValue, forKey: Key.pumpRegion.rawValue) + set(newValue?.rawValue, forKey: Key.pumpSettings.rawValue) } } - var pumpTimeZone: TimeZone? { + var pumpState: PumpState? { get { - if let offset = object(forKey: Key.pumpTimeZone.rawValue) as? NSNumber { - return TimeZone(secondsFromGMT: offset.intValue) + if let raw = dictionary(forKey: Key.pumpState.rawValue) { + return PumpState(rawValue: raw) } else { - return nil - } - } set { - if let value = newValue { - set(NSNumber(value: value.secondsFromGMT() as Int), forKey: Key.pumpTimeZone.rawValue) - } else { - removeObject(forKey: Key.pumpTimeZone.rawValue) + // Migrate the version 0 case + let standard = UserDefaults.standard + defer { + standard.removeObject(forKey: "com.loudnate.Naterade.PumpModelNumber") + standard.removeObject(forKey: "com.loudnate.Naterade.PumpTimeZone") + } + + var state = PumpState() + + if let pumpModelNumber = standard.string(forKey: "com.loudnate.Naterade.PumpModelNumber") { + state.pumpModel = PumpModel(rawValue: pumpModelNumber) + } + + if let offset = standard.object(forKey: "com.loudnate.Naterade.PumpTimeZone") as? NSNumber, + let timeZone = TimeZone(secondsFromGMT: offset.intValue) + { + state.timeZone = timeZone + } + + self.pumpState = state + + return state } } + set { + set(newValue?.rawValue, forKey: Key.pumpState.rawValue) + } } var batteryChemistry: BatteryChemistryType? { diff --git a/Loop/Extensions/OSLog.swift b/Loop/Extensions/OSLog.swift index b0902d98c7..995281eb88 100644 --- a/Loop/Extensions/OSLog.swift +++ b/Loop/Extensions/OSLog.swift @@ -9,6 +9,10 @@ import os.log extension OSLog { + convenience init(category: String) { + self.init(subsystem: "com.loopkit.Loop", category: category) + } + func debug(_ message: StaticString, _ args: CVarArg...) { log(message, type: .debug, args) } @@ -21,7 +25,18 @@ extension OSLog { log(message, type: .error, args) } - private func log(_ message: StaticString, type: OSLogType, _ args: CVarArg...) { - os_log(message, log: self, type: type, args) + private func log(_ message: StaticString, type: OSLogType, _ args: [CVarArg]) { + switch args.count { + case 0: + os_log(message, log: self, type: type) + case 1: + os_log(message, log: self, type: type, args[0]) + case 2: + os_log(message, log: self, type: type, args[0], args[1]) + case 3: + os_log(message, log: self, type: type, args[0], args[1], args[2]) + default: + os_log(message, log: self, type: type, args) + } } } diff --git a/Loop/Extensions/RileyLinkDevice.swift b/Loop/Extensions/RileyLinkDevice.swift index c4eb8bdb9d..4f90bdbaee 100644 --- a/Loop/Extensions/RileyLinkDevice.swift +++ b/Loop/Extensions/RileyLinkDevice.swift @@ -8,18 +8,19 @@ import HealthKit import MinimedKit import RileyLinkKit +import RileyLinkBLEKit -extension RileyLinkDevice { - var device: HKDevice? { +extension RileyLinkDevice.Status { + func device(settings: PumpSettings?, pumpState: PumpState?) -> HKDevice { return HKDevice( name: name, manufacturer: "Medtronic", model: pumpState?.pumpModel?.rawValue, hardwareVersion: nil, - firmwareVersion: firmwareVersion, + firmwareVersion: radioFirmwareVersion?.description, softwareVersion: String(RileyLinkKitVersionNumber), - localIdentifier: pumpState?.pumpID, + localIdentifier: settings?.pumpID, udiDeviceIdentifier: nil ) } diff --git a/Loop/Info.plist b/Loop/Info.plist index 47f665b094..da472e2b0c 100644 --- a/Loop/Info.plist +++ b/Loop/Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.5.3 + 1.5.4 CFBundleSignature ???? CFBundleURLTypes @@ -50,6 +50,8 @@ Glucose data from the Health database is used for graphing and momentum calculat NSHealthUpdateUsageDescription Carbohydrate meal data entered in the app and on the watch is stored in the Health database. Glucose data retrieved from the CGM is stored securely in HealthKit. + NSFaceIDUsageDescription + Face ID is used to authenticate insulin boluses. UIBackgroundModes bluetooth-central diff --git a/Loop/Managers/CGM/CGMManager.swift b/Loop/Managers/CGM/CGMManager.swift index 64615f545a..82424119b3 100644 --- a/Loop/Managers/CGM/CGMManager.swift +++ b/Loop/Managers/CGM/CGMManager.swift @@ -38,7 +38,7 @@ protocol CGMManagerDelegate: class { protocol CGMManager: CustomDebugStringConvertible { - weak var delegate: CGMManagerDelegate? { get set } + var delegate: CGMManagerDelegate? { get set } /// Whether the device is capable of waking the app var providesBLEHeartbeat: Bool { get } diff --git a/Loop/Managers/CGM/DexCGMManager.swift b/Loop/Managers/CGM/DexCGMManager.swift index 9e013db1e4..a6dfa6ba36 100644 --- a/Loop/Managers/CGM/DexCGMManager.swift +++ b/Loop/Managers/CGM/DexCGMManager.swift @@ -9,7 +9,7 @@ import G4ShareSpy import HealthKit import LoopUI import ShareClient -import xDripG5 +import CGMBLEKit class DexCGMManager: CGMManager { @@ -67,7 +67,7 @@ final class ShareClientManager: CGMManager { let managedDataInterval: TimeInterval? = nil - private var latestBackfill: ShareGlucose? + fileprivate var latestBackfill: ShareGlucose? func fetchNewDataIfNeeded(with deviceManager: DeviceDataManager, _ completion: @escaping (CGMResult) -> Void) { guard let shareClient = deviceManager.remoteDataManager.shareService.client else { @@ -116,12 +116,16 @@ final class ShareClientManager: CGMManager { final class G5CGMManager: DexCGMManager, TransmitterDelegate { + func transmitter(_ transmitter: Transmitter, didReadBackfill glucose: [Glucose]) { + // Not implemented yet + } + private let transmitter: Transmitter? let logger = DiagnosticLogger.shared!.forCategory("G5CGMManager") init(transmitterID: String?) { if let transmitterID = transmitterID { - self.transmitter = Transmitter(ID: transmitterID, passiveModeEnabled: true) + self.transmitter = Transmitter(id: transmitterID, passiveModeEnabled: true) } else { self.transmitter = nil } @@ -136,7 +140,14 @@ final class G5CGMManager: DexCGMManager, TransmitterDelegate { } override var sensorState: SensorDisplayable? { - return latestReading ?? super.sensorState + let transmitterDate = latestReading?.readDate ?? .distantPast + let shareDate = shareManager?.latestBackfill?.startDate ?? .distantPast + + if transmitterDate > shareDate { + return latestReading + } else { + return super.sensorState + } } override var managedDataInterval: TimeInterval? { @@ -170,12 +181,12 @@ final class G5CGMManager: DexCGMManager, TransmitterDelegate { override var device: HKDevice? { return HKDevice( - name: "xDripG5", + name: "CGMBLEKit", manufacturer: "Dexcom", model: "G5 Mobile", hardwareVersion: nil, firmwareVersion: nil, - softwareVersion: String(xDripG5VersionNumber), + softwareVersion: String(CGMBLEKitVersionNumber), localIdentifier: nil, udiDeviceIdentifier: "00386270000002" ) @@ -186,6 +197,7 @@ final class G5CGMManager: DexCGMManager, TransmitterDelegate { "## G5CGMManager", "latestReading: \(String(describing: latestReading))", "transmitter: \(String(describing: transmitter))", + "providesBLEHeartbeat: \(providesBLEHeartbeat)", super.debugDescription, "" ].joined(separator: "\n") @@ -290,6 +302,7 @@ final class G4CGMManager: DexCGMManager, ReceiverDelegate { "## G4CGMManager", "latestReading: \(String(describing: latestReading))", "receiver: \(receiver)", + "providesBLEHeartbeat: \(providesBLEHeartbeat)", super.debugDescription, "" ].joined(separator: "\n") @@ -321,7 +334,7 @@ final class G4CGMManager: DexCGMManager, ReceiverDelegate { func receiver(_ receiver: Receiver, didLogBluetoothEvent event: String) { // Uncomment to debug communication - // NSLog(["event": "\(event)", "collectedAt": NSDateFormatter.ISO8601StrictDateFormatter().stringFromDate(NSDate())]) + // NSLog("\(#function): \(event)") } } @@ -333,22 +346,25 @@ extension CalibrationError: LocalizedError { var errorDescription: String? { switch self { case .unreliableState(let state): - return state.description + return state.localizedDescription } } } -extension CalibrationState: CustomStringConvertible { - public var description: String { +extension CalibrationState { + public var localizedDescription: String { switch self { - case .needCalibration, .needFirstInitialCalibration, .needSecondInitialCalibration: - return NSLocalizedString("Sensor needs calibration", comment: "The description of sensor calibration state when sensor needs calibration.") - case .ok: - return NSLocalizedString("Sensor calibration is OK", comment: "The description of sensor calibration state when sensor calibration is ok.") - case .stopped: - return NSLocalizedString("Sensor is stopped", comment: "The description of sensor calibration state when sensor sensor is stopped.") - case .warmup: - return NSLocalizedString("Sensor is warming up", comment: "The description of sensor calibration state when sensor sensor is warming up.") + case .known(let state): + switch state { + case .needCalibration7, .needCalibration14, .needFirstInitialCalibration, .needSecondInitialCalibration, .calibrationError8, .calibrationError9, .calibrationError10, .calibrationError13: + return NSLocalizedString("Sensor needs calibration", comment: "The description of sensor calibration state when sensor needs calibration.") + case .ok: + return NSLocalizedString("Sensor calibration is OK", comment: "The description of sensor calibration state when sensor calibration is ok.") + case .stopped, .sensorFailure11, .sensorFailure12, .sessionFailure15, .sessionFailure16, .sessionFailure17: + return NSLocalizedString("Sensor is stopped", comment: "The description of sensor calibration state when sensor sensor is stopped.") + case .warmup, .questionMarks: + return NSLocalizedString("Sensor is warming up", comment: "The description of sensor calibration state when sensor sensor is warming up.") + } case .unknown(let rawValue): return String(format: NSLocalizedString("Sensor is in unknown state %1$d", comment: "The description of sensor calibration state when raw value is unknown. (1: missing data details)"), rawValue) } diff --git a/Loop/Managers/CGM/EnliteCGMManager.swift b/Loop/Managers/CGM/EnliteCGMManager.swift index 247137c803..25a9c23358 100644 --- a/Loop/Managers/CGM/EnliteCGMManager.swift +++ b/Loop/Managers/CGM/EnliteCGMManager.swift @@ -9,6 +9,7 @@ import HealthKit import LoopUI import MinimedKit +import RileyLinkKit final class EnliteCGMManager: CGMManager { @@ -21,42 +22,47 @@ final class EnliteCGMManager: CGMManager { let managedDataInterval: TimeInterval? = nil func fetchNewDataIfNeeded(with deviceManager: DeviceDataManager, _ completion: @escaping (CGMResult) -> Void) { - guard let device = deviceManager.rileyLinkManager.firstConnectedDevice?.ops - else { - completion(.noData) + deviceManager.rileyLinkManager.getDevices { (devices) in + guard let device = devices.firstConnected else { + completion(.error(LoopError.connectionError)) return - } - - let latestGlucoseDate = self.delegate?.startDateToFilterNewData(for: self) ?? Date(timeIntervalSinceNow: TimeInterval(hours: -24)) + } - guard latestGlucoseDate.timeIntervalSinceNow <= TimeInterval(minutes: -4.5) else { - completion(.noData) - return - } + guard let ops = deviceManager.pumpOps else { + completion(.error(LoopError.configurationError("Pump ID"))) + return + } - device.getGlucoseHistoryEvents(since: latestGlucoseDate.addingTimeInterval(TimeInterval(minutes: 1))) { (result) in - switch result { - case .success(let events): + let latestGlucoseDate = self.delegate?.startDateToFilterNewData(for: self) ?? Date(timeIntervalSinceNow: TimeInterval(hours: -24)) - _ = deviceManager.remoteDataManager.nightscoutService.uploader?.processGlucoseEvents(events, source: device.device.deviceURI) + guard latestGlucoseDate.timeIntervalSinceNow <= TimeInterval(minutes: -4.5) else { + completion(.noData) + return + } - if let latestSensorEvent = events.flatMap({ $0.glucoseEvent as? RelativeTimestampedGlucoseEvent }).last { - self.sensorState = EnliteSensorDisplayable(latestSensorEvent) + ops.runSession(withName: "Fetch Enlite History", using: device) { (session) in + do { + let events = try session.getGlucoseHistoryEvents(since: latestGlucoseDate.addingTimeInterval(.minutes(1))) + _ = deviceManager.remoteDataManager.nightscoutService.uploader?.processGlucoseEvents(events, source: device.deviceURI) + + if let latestSensorEvent = events.compactMap({ $0.glucoseEvent as? RelativeTimestampedGlucoseEvent }).last { + self.sensorState = EnliteSensorDisplayable(latestSensorEvent) + } + + let unit = HKUnit.milligramsPerDeciliter() + let glucoseValues = events + // TODO: Is the { $0.date > latestGlucoseDate } filter duplicative? + .filter({ $0.glucoseEvent is SensorValueGlucoseEvent && $0.date > latestGlucoseDate }) + .map({ (e:TimestampedGlucoseEvent) -> (quantity: HKQuantity, date: Date, isDisplayOnly: Bool) in + let glucoseEvent = e.glucoseEvent as! SensorValueGlucoseEvent + let quantity = HKQuantity(unit: unit, doubleValue: Double(glucoseEvent.sgv)) + return (quantity: quantity, date: e.date, isDisplayOnly: false) + }) + + completion(.newData(glucoseValues)) + } catch let error { + completion(.error(error)) } - - let unit = HKUnit.milligramsPerDeciliter() - let glucoseValues = events - // TODO: Is the { $0.date > latestGlucoseDate } filter duplicative? - .filter({ $0.glucoseEvent is SensorValueGlucoseEvent && $0.date > latestGlucoseDate }) - .map({ (e:TimestampedGlucoseEvent) -> (quantity: HKQuantity, date: Date, isDisplayOnly: Bool) in - let glucoseEvent = e.glucoseEvent as! SensorValueGlucoseEvent - let quantity = HKQuantity(unit: unit, doubleValue: Double(glucoseEvent.sgv)) - return (quantity: quantity, date: e.date, isDisplayOnly: false) - }) - - completion(.newData(glucoseValues)) - case .failure(let error): - completion(.error(error)) } } } diff --git a/Loop/Managers/DeviceDataManager.swift b/Loop/Managers/DeviceDataManager.swift index e96f7cb504..146ecc5d08 100644 --- a/Loop/Managers/DeviceDataManager.swift +++ b/Loop/Managers/DeviceDataManager.swift @@ -17,16 +17,18 @@ import LoopUI import MinimedKit import NightscoutUploadKit import RileyLinkKit +import RileyLinkKitUI +import RileyLinkBLEKit final class DeviceDataManager { - // MARK: - Utilities + private let queue = DispatchQueue(label: "com.loopkit.DeviceManagerQueue", qos: .utility) let logger = DiagnosticLogger.shared! /// Remember the launch date of the app for diagnostic reporting - fileprivate let launchDate = Date() + private let launchDate = Date() /// Manages all the RileyLinks let rileyLinkManager: RileyLinkDeviceManager @@ -36,17 +38,23 @@ final class DeviceDataManager { private var nightscoutDataManager: NightscoutDataManager! - fileprivate var latestPumpStatus: RileyLinkKit.PumpStatus? + // TODO: Isolate to queue + private var latestPumpStatus: RileyLinkKit.PumpStatus? + // Main queue access only private(set) var lastError: (date: Date, error: Error)? - fileprivate func setLastError(error: Error) { + /// Isolated to queue + private var lastTimerTick: Date = .distantPast + + private func setLastError(error: Error) { DispatchQueue.main.async { // Synchronize writes self.lastError = (date: Date(), error: error) // TODO: Notify observers of change } } + // TODO: Isolate to queue // Returns a value in the range 0 - 1 var pumpBatteryChargeRemaining: Double? { get { @@ -61,7 +69,7 @@ final class DeviceDataManager { } // Battery monitor - fileprivate func observeBatteryDuring(_ block: () -> Void) { + private func observeBatteryDuring(_ block: () -> Void) { let oldVal = pumpBatteryChargeRemaining block() if let newVal = pumpBatteryChargeRemaining { @@ -77,21 +85,38 @@ final class DeviceDataManager { // MARK: - RileyLink - @objc private func receivedRileyLinkManagerNotification(_ note: Notification) { - NotificationCenter.default.post(name: note.name, object: self, userInfo: note.userInfo) - + @objc private func deviceStatusDidChange(_ note: Notification) { switch note.name { case Notification.Name.DeviceConnectionStateDidChange, Notification.Name.DeviceNameDidChange: - // Update the HKDevice to include the name or connection status change - if let device = rileyLinkManager.firstConnectedDevice?.device { - loopManager.doseStore.setDevice(device) - } + updateDoseStoreDeviceFromRileyLink(state: pumpState) default: break } } + private func updateDoseStoreDeviceFromRileyLink(state: PumpState?) { + // Update the HKDevice to include the name, pump model, or connection status change + rileyLinkManager.getDevices { (devices) in + devices.firstConnected?.getStatus { (status) in + self.loopManager.doseStore.setDevice(status.device(settings: self.pumpSettings, pumpState: state)) + } + } + } + + @objc private func deviceStateDidChange(_ note: Notification) { + guard + let device = note.object as? RileyLinkDevice, + let deviceState = note.userInfo?[RileyLinkDevice.notificationDeviceStateKey] as? DeviceState + else { + return + } + + queue.async { + self.deviceStates[device.peripheralIdentifier] = deviceState + } + } + /** Called when a new idle message is received by the RileyLink. @@ -100,59 +125,74 @@ final class DeviceDataManager { - parameter note: The notification object */ @objc private func receivedRileyLinkPacketNotification(_ note: Notification) { - if let - device = note.object as? RileyLinkDevice, - let data = note.userInfo?[RileyLinkDevice.IdleMessageDataKey] as? Data, - let message = PumpMessage(rxData: data) - { - switch message.packetType { - case .mySentry: - switch message.messageBody { - case let body as MySentryPumpStatusMessageBody: - updatePumpStatus(body, from: device) - case is MySentryAlertMessageBody, is MySentryAlertClearedMessageBody: - break - case let body: - logger.forCategory("MySentry").info(["messageType": Int(message.messageType.rawValue), "messageBody": body.txData.hexadecimalString]) - } - default: + guard let device = note.object as? RileyLinkDevice, + let packet = note.userInfo?[RileyLinkDevice.notificationPacketKey] as? RFPacket, + let data = MinimedPacket(encodedData: packet.data)?.data, + let message = PumpMessage(rxData: data), + let address = pumpSettings?.pumpID, + message.address.hexadecimalString == address, + case .mySentry = message.packetType + else { + return + } + + queue.async { + switch message.messageBody { + case let body as MySentryPumpStatusMessageBody: + self.updatePumpStatus(body, from: device) + case is MySentryAlertMessageBody, is MySentryAlertClearedMessageBody: break + case let body: + // TODO: I think we've learned everything we're going to learn here. + self.logger.forCategory("MySentry").info(["messageType": Int(message.messageType.rawValue), "messageBody": body.txData.hexadecimalString]) } } } @objc private func receivedRileyLinkTimerTickNotification(_: Notification) { - cgmManager?.fetchNewDataIfNeeded(with: self) { (result) in - self.cgmManager(self.cgmManager!, didUpdateWith: result) + queue.async { + self.lastTimerTick = Date() + + self.cgmManager?.fetchNewDataIfNeeded(with: self) { (result) in + // TODO: Isolate to queue? + self.cgmManager(self.cgmManager!, didUpdateWith: result) + } } } func connectToRileyLink(_ device: RileyLinkDevice) { - connectedPeripheralIDs.insert(device.peripheral.identifier.uuidString) + queue.async { + self.connectedPeripheralIDs.insert(device.peripheralIdentifier.uuidString) - rileyLinkManager.connectDevice(device) + self.rileyLinkManager.connect(device) - AnalyticsManager.shared.didChangeRileyLinkConnectionState() + AnalyticsManager.shared.didChangeRileyLinkConnectionState() + } } func disconnectFromRileyLink(_ device: RileyLinkDevice) { - connectedPeripheralIDs.remove(device.peripheral.identifier.uuidString) + queue.async { + self.connectedPeripheralIDs.remove(device.peripheralIdentifier.uuidString) - rileyLinkManager.disconnectDevice(device) + self.rileyLinkManager.disconnect(device) - AnalyticsManager.shared.didChangeRileyLinkConnectionState() + AnalyticsManager.shared.didChangeRileyLinkConnectionState() - if connectedPeripheralIDs.count == 0 { - NotificationManager.clearPendingNotificationRequests() + if self.connectedPeripheralIDs.count == 0 { + NotificationManager.clearPendingNotificationRequests() + } } } - fileprivate func updateTimerTickPreference() { - /// Controls the management of the RileyLink timer tick, which is a reliably-changing BLE - /// characteristic which can cause the app to wake. For most users, the G5 Transmitter and - /// G4 Receiver are reliable as hearbeats, but users who find their resources extremely constrained - /// due to greedy apps or older devices may choose to always enable the timer by always setting `true` - rileyLinkManager.timerTickEnabled = pumpDataIsStale() || !(cgmManager?.providesBLEHeartbeat == true) + /// TODO: Isolate to queue + func updateTimerTickPreference() { + queue.async { + /// Controls the management of the RileyLink timer tick, which is a reliably-changing BLE + /// characteristic which can cause the app to wake. For most users, the G5 Transmitter and + /// G4 Receiver are reliable as hearbeats, but users who find their resources extremely constrained + /// due to greedy apps or older devices may choose to always enable the timer by always setting `true` + self.rileyLinkManager.timerTickEnabled = self.isPumpDataStale() || !(self.cgmManager?.providesBLEHeartbeat == true) + } } /** @@ -161,31 +201,53 @@ final class DeviceDataManager { - parameter device: The RileyLink device */ private func troubleshootPumpComms(using device: RileyLinkDevice) { + /// TODO: Isolate to queue? // Ensuring timer tick is enabled will allow more tries to bring the pump data up-to-date. updateTimerTickPreference() + guard let pumpOps = pumpOps else { + return + } + // How long we should wait before we re-tune the RileyLink let tuneTolerance = TimeInterval(minutes: 14) - if device.lastTuned == nil || device.lastTuned!.timeIntervalSinceNow <= -tuneTolerance { - device.tunePump { (result) in - switch result { - case .success(let scanResult): + let deviceState = deviceStates[device.peripheralIdentifier, default: DeviceState()] + let lastTuned = deviceState.lastTuned ?? .distantPast + + if lastTuned.timeIntervalSinceNow <= -tuneTolerance { + pumpOps.runSession(withName: "Tune pump", using: device) { (session) in + do { + let scanResult = try session.tuneRadio(current: deviceState.lastValidFrequency) self.logger.addError("Device \(device.name ?? "") auto-tuned to \(scanResult.bestFrequency) MHz", fromSource: "RileyLink") - case .failure(let error): + + self.queue.async { + self.deviceStates[device.peripheralIdentifier] = DeviceState( + lastTuned: Date(), + lastValidFrequency: scanResult.bestFrequency + ) + } + } catch let error { self.logger.addError("Device \(device.name ?? "") auto-tune failed with error: \(error)", fromSource: "RileyLink") - self.rileyLinkManager.deprioritizeDevice(device: device) + self.rileyLinkManager.deprioritize(device) self.setLastError(error: error) } } } else { - rileyLinkManager.deprioritizeDevice(device: device) + rileyLinkManager.deprioritize(device) } } // MARK: Pump data - fileprivate var latestPumpStatusFromMySentry: MySentryPumpStatusMessageBody? + /// TODO: Isolate to queue + fileprivate var latestPumpStatusFromMySentry: MySentryPumpStatusMessageBody? { + didSet { + if let manager = cgmManager as? EnliteCGMManager { + manager.sensorState = latestPumpStatusFromMySentry + } + } + } /** Handles receiving a MySentry status message, which are only posted by MM x23 pumps. @@ -198,6 +260,8 @@ final class DeviceDataManager { - parameter device: The RileyLink that received the message */ private func updatePumpStatus(_ status: MySentryPumpStatusMessageBody, from device: RileyLinkDevice) { + dispatchPrecondition(condition: .onQueue(queue)) + var pumpDateComponents = status.pumpDateComponents var glucoseDateComponents = status.glucoseDateComponents @@ -215,7 +279,7 @@ final class DeviceDataManager { // Gather PumpStatus from MySentry packet let pumpStatus: NightscoutUploadKit.PumpStatus? - if let pumpID = pumpID { + if let pumpID = pumpSettings?.pumpID { let batteryStatus = BatteryStatus(percent: status.batteryRemainingPercent) let iobStatus = IOBStatus(timestamp: pumpDate, iob: status.iob) @@ -225,8 +289,12 @@ final class DeviceDataManager { logger.addError("Could not interpret pump clock: \(pumpDateComponents)", fromSource: "RileyLink") } - // Trigger device status upload, even if something is wrong with pumpStatus - nightscoutDataManager.uploadDeviceStatus(pumpStatus, rileylinkDevice: device) + device.getStatus { (status) in + // Trigger device status upload, even if something is wrong with pumpStatus + self.queue.async { + self.nightscoutDataManager.uploadDeviceStatus(pumpStatus, rileylinkDevice: status, deviceState: self.deviceStates[device.peripheralIdentifier]) + } + } switch status.glucose { case .active(glucose: let glucose): @@ -259,7 +327,7 @@ final class DeviceDataManager { remoteDataManager.nightscoutService.uploader?.uploadSGVFromMySentryPumpStatus(status, device: device.deviceURI) // Sentry packets are sent in groups of 3, 5s apart. Wait 11s before allowing the loop data to continue to avoid conflicting comms. - DispatchQueue.global(qos: .utility).asyncAfter(deadline: .now() + .seconds(11)) { + queue.asyncAfter(deadline: .now() + .seconds(11)) { self.updateReservoirVolume(status.reservoirRemainingUnits, at: pumpDate, withTimeLeft: TimeInterval(minutes: Double(status.reservoirRemainingMinutes))) } } @@ -273,6 +341,8 @@ final class DeviceDataManager { */ private func updateReservoirVolume(_ units: Double, at date: Date, withTimeLeft timeLeft: TimeInterval?) { loopManager.addReservoirValue(units, at: date) { (result) in + /// TODO: Isolate to queue + switch result { case .failure(let error): self.setLastError(error: error) @@ -319,84 +389,130 @@ final class DeviceDataManager { } } + /// TODO: Isolate to queue /// Polls the pump for new history events and passes them to the loop manager /// /// - Parameters: /// - completion: A closure called once upon completion /// - error: An error describing why the fetch and/or store failed - fileprivate func fetchPumpHistory(_ completion: @escaping (_ error: Error?) -> Void) { - guard let device = rileyLinkManager.firstConnectedDevice else { - completion(LoopError.connectionError) - return - } + private func fetchPumpHistory(_ completion: @escaping (_ error: Error?) -> Void) { + rileyLinkManager.getDevices { (devices) in + guard let device = devices.firstConnected else { + completion(LoopError.connectionError) + return + } + + guard let ops = self.pumpOps else { + completion(LoopError.configurationError("Pump ID")) + return + } - let startDate = loopManager.doseStore.pumpEventQueryAfterDate + ops.runSession(withName: "Fetch Pump History", using: device) { (session) in + do { + // TODO: This should isn't safe to access synchronously + let startDate = self.loopManager.doseStore.pumpEventQueryAfterDate - device.ops?.getHistoryEvents(since: startDate) { (result) in - switch result { - case let .success(events, model): - self.loopManager.addPumpEvents(events, from: model) { (error) in - if let error = error { - self.logger.addError("Failed to store history: \(error)", fromSource: "DoseStore") + let (events, model) = try session.getHistoryEvents(since: startDate) + self.loopManager.addPumpEvents(events, from: model) { (error) in + if let error = error { + self.logger.addError("Failed to store history: \(error)", fromSource: "DoseStore") + } + + completion(error) } + } catch let error { + self.troubleshootPumpComms(using: device) + self.logger.addError("Failed to fetch history: \(error)", fromSource: "RileyLink") completion(error) } - case .failure(let error): - self.rileyLinkManager.deprioritizeDevice(device: device) - self.logger.addError("Failed to fetch history: \(error)", fromSource: "RileyLink") - - completion(error) } } } - private func pumpDataIsStale() -> Bool { + /// TODO: Isolate to queue + private func isPumpDataStale() -> Bool { // How long should we wait before we poll for new pump data? - let pumpStatusAgeTolerance = rileyLinkManager.idleListeningEnabled ? TimeInterval(minutes: 9) : TimeInterval(minutes: 4) + let pumpStatusAgeTolerance = rileyLinkManager.idleListeningEnabled ? TimeInterval(minutes: 6) : TimeInterval(minutes: 4) + + return isReservoirDataOlderThan(timeIntervalSinceNow: -pumpStatusAgeTolerance) + } + + private func isReservoirDataOlderThan(timeIntervalSinceNow: TimeInterval) -> Bool { + // TODO: lastReservoirValue isn't safe to read from any queue + var lastReservoirDate = loopManager.doseStore.lastReservoirValue?.startDate ?? .distantPast - return loopManager.doseStore.lastReservoirValue == nil - || loopManager.doseStore.lastReservoirValue!.startDate.timeIntervalSinceNow <= -pumpStatusAgeTolerance + // Look for reservoir data from MySentry that hasn't yet been written (due to 11-second imposed delay) + if let sentryStatus = latestPumpStatusFromMySentry, let timeZone = pumpState?.timeZone { + var components = sentryStatus.pumpDateComponents + components.timeZone = timeZone + + lastReservoirDate = max(components.date ?? .distantPast, lastReservoirDate) + } + + return lastReservoirDate.timeIntervalSinceNow <= timeIntervalSinceNow } /** Ensures pump data is current by either waking and polling, or ensuring we're listening to sentry packets. */ - fileprivate func assertCurrentPumpData() { - guard let device = rileyLinkManager.firstConnectedDevice else { - self.setLastError(error: LoopError.connectionError) + /// TODO: Isolate to queue + private func assertCurrentPumpData() { + rileyLinkManager.assertIdleListening(forcingRestart: true) + + guard isPumpDataStale() else { return } - device.assertIdleListening() + rileyLinkManager.getDevices { (devices) in + guard let device = devices.firstConnected else { + let error = LoopError.connectionError + self.logger.addError("Failed to fetch pump status: \(error)", fromSource: "RileyLink") + self.setLastError(error: error) + return + } - guard pumpDataIsStale() else { - return - } + guard let ops = self.pumpOps else { + let error = LoopError.configurationError("Pump ID") + self.setLastError(error: error) + return + } - rileyLinkManager.readPumpData { (result) in - let nsPumpStatus: NightscoutUploadKit.PumpStatus? - switch result { - case .success(let (status, date)): - self.observeBatteryDuring { - self.latestPumpStatus = status - } + ops.runSession(withName: "Get Pump Status", using: device) { (session) in + let nsPumpStatus: NightscoutUploadKit.PumpStatus? + do { + let status = try session.getCurrentPumpStatus() + guard let date = status.clock.date else { + assertionFailure("Could not interpret a valid date from \(status.clock) in the system calendar") + return + } - self.updateReservoirVolume(status.reservoir, at: date, withTimeLeft: nil) - let battery = BatteryStatus(voltage: status.batteryVolts, status: BatteryIndicator(batteryStatus: status.batteryStatus)) + self.observeBatteryDuring { + self.latestPumpStatus = status + } - nsPumpStatus = NightscoutUploadKit.PumpStatus(clock: date, pumpID: status.pumpID, iob: nil, battery: battery, suspended: status.suspended, bolusing: status.bolusing, reservoir: status.reservoir) - case .failure(let error): - self.logger.addError("Failed to fetch pump status: \(error)", fromSource: "RileyLink") - self.setLastError(error: error) - self.troubleshootPumpComms(using: device) - self.nightscoutDataManager.uploadLoopStatus(loopError: error) - nsPumpStatus = nil + self.updateReservoirVolume(status.reservoir, at: date, withTimeLeft: nil) + let battery = BatteryStatus(voltage: status.batteryVolts, status: BatteryIndicator(batteryStatus: status.batteryStatus)) + + nsPumpStatus = NightscoutUploadKit.PumpStatus(clock: date, pumpID: status.pumpID, iob: nil, battery: battery, suspended: status.suspended, bolusing: status.bolusing, reservoir: status.reservoir) + } catch let error { + self.logger.addError("Failed to fetch pump status: \(error)", fromSource: "RileyLink") + self.setLastError(error: error) + self.troubleshootPumpComms(using: device) + self.nightscoutDataManager.uploadLoopStatus(loopError: error) + nsPumpStatus = nil + } + + device.getStatus { (status) in + self.queue.async { + self.nightscoutDataManager.uploadDeviceStatus(nsPumpStatus, rileylinkDevice: status, deviceState: self.deviceStates[device.peripheralIdentifier]) + } + } } - self.nightscoutDataManager.uploadDeviceStatus(nsPumpStatus, rileylinkDevice: device) } } + /// TODO: Isolate to queue /// Send a bolus command and handle the result /// /// - parameter units: The number of units to deliver @@ -416,78 +532,84 @@ final class DeviceDataManager { return } - guard let device = rileyLinkManager.firstConnectedDevice else { - notify(LoopError.connectionError) + guard let ops = pumpOps else { + notify(LoopError.configurationError("Pump ID")) return } - guard let ops = device.ops else { - notify(LoopError.configurationError("PumpOps")) - return - } + // If we don't have recent pump data, or the pump was recently rewound, read new pump data before bolusing. + let shouldReadReservoir = isReservoirDataOlderThan(timeIntervalSinceNow: .minutes(-6)) - let setBolus = { - self.loopManager.addRequestedBolus(units: units, at: Date()) { - ops.setNormalBolus(units: units) { (error) in - if let error = error { - self.logger.addError(error, fromSource: "Bolus") - notify(error) - } else { - self.loopManager.addConfirmedBolus(units: units, at: Date()) { - notify(nil) - } - } - } + ops.runSession(withName: "Bolus", using: rileyLinkManager.firstConnectedDevice) { (session) in + guard let session = session else { + notify(LoopError.connectionError) + return } - } - // If we don't have recent pump data, or the pump was recently rewound, read new pump data before bolusing. - if loopManager.doseStore.lastReservoirValue == nil || - loopManager.doseStore.lastReservoirVolumeDrop < 0 || - loopManager.doseStore.lastReservoirValue!.startDate.timeIntervalSinceNow <= TimeInterval(minutes: -6) - { - rileyLinkManager.readPumpData { (result) in - switch result { - case .success(let (status, date)): - self.loopManager.addReservoirValue(status.reservoir, at: date) { (result) in + if shouldReadReservoir { + do { + let reservoir = try session.getRemainingInsulin() + + self.loopManager.addReservoirValue(reservoir.units, at: reservoir.clock.date!) { (result) in switch result { case .failure(let error): self.logger.addError(error, fromSource: "Bolus") - notify(error) case .success: - setBolus() + break } } - case .failure(let error): + } catch let error as PumpOpsError { + self.logger.addError("Failed to fetch pump status: \(error)", fromSource: "RileyLink") + notify(SetBolusError.certain(error)) + return + } catch let error as PumpCommandError { + self.logger.addError("Failed to fetch pump status: \(error)", fromSource: "RileyLink") switch error { - case let error as PumpCommsError: + case .arguments(let error): + notify(SetBolusError.certain(error)) + case .command(let error): notify(SetBolusError.certain(error)) - default: - notify(error) } + return + } catch let error { + notify(error) + return + } + } - self.logger.addError("Failed to fetch pump status: \(error)", fromSource: "RileyLink") + do { + let semaphore = DispatchSemaphore(value: 0) + self.loopManager.addRequestedBolus(units: units, at: Date()) { + semaphore.signal() + } + semaphore.wait() + + try session.setNormalBolus(units: units) + self.loopManager.addConfirmedBolus(units: units, at: Date()) { + notify(nil) } + } catch let error { + self.logger.addError(error, fromSource: "Bolus") + notify(error) } - } else { - setBolus() } } // MARK: - CGM - var cgm: CGM? = UserDefaults.standard.cgm { + var cgm: CGM? = UserDefaults.appGroup.cgm { didSet { if cgm != oldValue { setupCGM() } - UserDefaults.standard.cgm = cgm + UserDefaults.appGroup.cgm = cgm } } private(set) var cgmManager: CGMManager? + /// TODO: Isolate to queue private func setupCGM() { cgmManager = cgm?.createManager() cgmManager?.delegate = self @@ -497,109 +619,94 @@ final class DeviceDataManager { } var sensorInfo: SensorDisplayable? { - return cgmManager?.sensorState ?? latestPumpStatusFromMySentry + return cgmManager?.sensorState } // MARK: - Configuration // MARK: Pump - private var connectedPeripheralIDs: Set = Set(UserDefaults.standard.connectedPeripheralIDs) { + /// TODO: Isolate to queue + private var connectedPeripheralIDs: Set = Set(UserDefaults.appGroup.connectedPeripheralIDs) { didSet { - UserDefaults.standard.connectedPeripheralIDs = Array(connectedPeripheralIDs) + UserDefaults.appGroup.connectedPeripheralIDs = Array(connectedPeripheralIDs) } } - var pumpID: String? { - get { - return pumpState?.pumpID - } - set { - guard newValue != pumpState?.pumpID else { - return - } + // TODO: Isolate to queue + private var deviceStates: [UUID: DeviceState] = [:] - var pumpID = newValue + func getStateForDevice(_ device: RileyLinkDevice, completion: @escaping (_ deviceState: DeviceState, _ pumpState: PumpState?, _ pumpSettings: PumpSettings?, _ pumpOps: PumpOps?) -> Void) { + queue.async { + completion(self.deviceStates[device.peripheralIdentifier, default: DeviceState()], self.pumpState, self.pumpSettings, self.pumpOps) + } + } - if let pumpID = pumpID, pumpID.count == 6 { - let pumpState = PumpState(pumpID: pumpID, pumpRegion: self.pumpState?.pumpRegion ?? .northAmerica) + private(set) var pumpOps: PumpOps? { + didSet { + if pumpOps == nil { + UserDefaults.appGroup.pumpState = nil + } + } + } - if let timeZone = self.pumpState?.timeZone { - pumpState.timeZone = timeZone + private(set) var pumpSettings: PumpSettings? { + get { + return UserDefaults.appGroup.pumpSettings + } + set { + if let settings = newValue { + if let pumpOps = pumpOps { + pumpOps.updateSettings(settings) + } else { + pumpOps = PumpOps(pumpSettings: settings, pumpState: nil, delegate: self) } - - self.pumpState = pumpState } else { - pumpID = nil - self.pumpState = nil + pumpOps = nil + loopManager.doseStore.resetPumpData() } - remoteDataManager.nightscoutService.uploader?.reset() - - loopManager.doseStore.resetPumpData() - - UserDefaults.standard.pumpID = pumpID + UserDefaults.appGroup.pumpSettings = newValue } } - var pumpState: PumpState? { - didSet { - rileyLinkManager.pumpState = pumpState + func setPumpID(_ pumpID: String?) { + var newValue = pumpID - if let oldValue = oldValue { - NotificationCenter.default.removeObserver(self, name: .PumpStateValuesDidChange, object: oldValue) - } + if newValue?.count != 6 { + newValue = nil + } - if let pumpState = pumpState { - NotificationCenter.default.addObserver(self, selector: #selector(pumpStateValuesDidChange(_:)), name: .PumpStateValuesDidChange, object: pumpState) + if let newValue = newValue { + if pumpSettings != nil { + pumpSettings?.pumpID = newValue + } else { + pumpSettings = PumpSettings(pumpID: newValue) } } } - @objc private func pumpStateValuesDidChange(_ note: Notification) { - switch note.userInfo?[PumpState.PropertyKey] as? String { - case "timeZone"?: - UserDefaults.standard.pumpTimeZone = pumpState?.timeZone - - if let pumpTimeZone = pumpState?.timeZone { - loopManager.setScheduleTimeZone(pumpTimeZone) - } - case "pumpModel"?: - if let sentrySupported = pumpState?.pumpModel?.hasMySentry, !sentrySupported { - rileyLinkManager.idleListeningEnabled = false - } - - // Update the HKDevice to include the model change - if let device = rileyLinkManager.firstConnectedDevice?.device { - loopManager.doseStore.setDevice(device) - } - - // Update the preference for basal profile start events - if let recordsBasalProfileStartEvents = pumpState?.pumpModel?.recordsBasalProfileStartEvents { - loopManager.doseStore.pumpRecordsBasalProfileStartEvents = recordsBasalProfileStartEvents - } + func setPumpRegion(_ pumpRegion: PumpRegion) { + pumpSettings?.pumpRegion = pumpRegion + } - UserDefaults.standard.pumpModelNumber = pumpState?.pumpModel?.rawValue - case "pumpRegion"?: - UserDefaults.standard.pumpRegion = pumpState?.pumpRegion - case "lastHistoryDump"?, "awakeUntil"?: - break - default: - break - } + var pumpState: PumpState? { + return UserDefaults.appGroup.pumpState } + // TODO: Isolate to queue /// The user's preferred method of fetching insulin data from the pump - var preferredInsulinDataSource = UserDefaults.standard.preferredInsulinDataSource ?? .pumpHistory { + var preferredInsulinDataSource = UserDefaults.appGroup.preferredInsulinDataSource ?? .pumpHistory { didSet { - UserDefaults.standard.preferredInsulinDataSource = preferredInsulinDataSource + UserDefaults.appGroup.preferredInsulinDataSource = preferredInsulinDataSource } } - + + // TODO: Isolate to queue /// The pump battery chemistry, for voltage -> percentage calculation - var batteryChemistry = UserDefaults.standard.batteryChemistry ?? .alkaline { + var batteryChemistry = UserDefaults.appGroup.batteryChemistry ?? .alkaline { didSet { - UserDefaults.standard.batteryChemistry = batteryChemistry + UserDefaults.appGroup.batteryChemistry = batteryChemistry } } @@ -616,43 +723,31 @@ final class DeviceDataManager { private(set) var loopManager: LoopDataManager! init() { - let pumpID = UserDefaults.standard.pumpID + rileyLinkManager = RileyLinkDeviceManager( + autoConnectIDs: connectedPeripheralIDs + ) + // Pump communication var idleListeningEnabled = true - if let pumpID = pumpID { - let pumpState = PumpState(pumpID: pumpID, pumpRegion: UserDefaults.standard.pumpRegion ?? .northAmerica) - - if let timeZone = UserDefaults.standard.pumpTimeZone { - pumpState.timeZone = timeZone - } else { - UserDefaults.standard.pumpTimeZone = TimeZone.current - } + if let pumpSettings = UserDefaults.appGroup.pumpSettings { + let pumpState = self.pumpState - if let pumpModelNumber = UserDefaults.standard.pumpModelNumber { - if let model = PumpModel(rawValue: pumpModelNumber) { - pumpState.pumpModel = model + idleListeningEnabled = pumpState?.pumpModel?.hasMySentry ?? true - idleListeningEnabled = model.hasMySentry - } - } - - self.pumpState = pumpState + self.pumpOps = PumpOps(pumpSettings: pumpSettings, pumpState: pumpState, delegate: self) } - rileyLinkManager = RileyLinkDeviceManager( - pumpState: self.pumpState, - autoConnectIDs: connectedPeripheralIDs - ) - rileyLinkManager.idleListeningEnabled = idleListeningEnabled + rileyLinkManager.idleListeningState = idleListeningEnabled ? LoopSettings.idleListeningEnabledDefaults : .disabled - NotificationCenter.default.addObserver(self, selector: #selector(receivedRileyLinkManagerNotification(_:)), name: nil, object: rileyLinkManager) - NotificationCenter.default.addObserver(self, selector: #selector(receivedRileyLinkPacketNotification(_:)), name: .RileyLinkDeviceDidReceiveIdleMessage, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(receivedRileyLinkTimerTickNotification(_:)), name: .RileyLinkDeviceDidUpdateTimerTick, object: nil) + // Listen for device notifications + NotificationCenter.default.addObserver(self, selector: #selector(receivedRileyLinkPacketNotification(_:)), name: .DevicePacketReceived, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(receivedRileyLinkTimerTickNotification(_:)), name: .DeviceTimerDidTick, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(deviceStatusDidChange(_:)), name: .DeviceConnectionStateDidChange, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(deviceStatusDidChange(_:)), name: .DeviceNameDidChange, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(deviceStateDidChange(_:)), name: .DeviceStateDidChange, object: nil) - if let pumpState = pumpState { - NotificationCenter.default.addObserver(self, selector: #selector(pumpStateValuesDidChange(_:)), name: .PumpStateValuesDidChange, object: pumpState) - } + NotificationCenter.default.addObserver(self, selector: #selector(deviceStatusDidChange(_:)), name: .ManagerDevicesDidChange, object: rileyLinkManager) remoteDataManager.delegate = self statusExtensionManager = StatusExtensionDataManager(deviceDataManager: self) @@ -685,6 +780,7 @@ extension DeviceDataManager: RemoteDataManagerDelegate { extension DeviceDataManager: CGMManagerDelegate { func cgmManager(_ manager: CGMManager, didUpdateWith result: CGMResult) { + /// TODO: Isolate to queue switch result { case .newData(let values): loopManager.addGlucose(values, from: manager.device) { _ in @@ -702,6 +798,7 @@ extension DeviceDataManager: CGMManagerDelegate { } func startDateToFilterNewData(for manager: CGMManager) -> Date? { + // TODO: This shouldn't be safe to access synchronously return loopManager.glucoseStore.latestGlucose?.startDate } } @@ -712,6 +809,7 @@ extension DeviceDataManager: DoseStoreDelegate { hasEventsNeedingUpload pumpEvents: [PersistedPumpEvent], completion completionHandler: @escaping (_ uploadedObjects: [NSManagedObjectID]) -> Void ) { + /// TODO: Isolate to queue guard let uploader = remoteDataManager.nightscoutService.uploader, let pumpModel = pumpState?.pumpModel else { completionHandler(pumpEvents.map({ $0.objectID })) return @@ -732,14 +830,13 @@ extension DeviceDataManager: DoseStoreDelegate { extension DeviceDataManager: LoopDataManagerDelegate { - func loopDataManager(_ manager: LoopDataManager, didRecommendBasalChange basal: (recommendation: TempBasalRecommendation, date: Date), completion: @escaping (_ result: Result) -> Void) { - guard let device = rileyLinkManager.firstConnectedDevice else { - completion(.failure(LoopError.connectionError)) - return - } - - guard let ops = device.ops else { - completion(.failure(LoopError.configurationError("PumpOps"))) + func loopDataManager( + _ manager: LoopDataManager, + didRecommendBasalChange basal: (recommendation: TempBasalRecommendation, date: Date), + completion: @escaping (_ result: Result) -> Void + ) { + guard let pumpOps = pumpOps else { + completion(.failure(LoopError.configurationError("Pump ID"))) return } @@ -755,20 +852,26 @@ extension DeviceDataManager: LoopDataManagerDelegate { } } - ops.setTempBasal(rate: basal.recommendation.unitsPerHour, duration: basal.recommendation.duration) { (result) -> Void in - switch result { - case .success(let body): + pumpOps.runSession(withName: "Set Temp Basal", using: rileyLinkManager.firstConnectedDevice) { (session) in + guard let session = session else { + completion(.failure(LoopError.connectionError)) + return + } + + do { + let response = try session.setTempBasal(basal.recommendation.unitsPerHour, duration: basal.recommendation.duration) + let now = Date() - let endDate = now.addingTimeInterval(body.timeRemaining) + let endDate = now.addingTimeInterval(response.timeRemaining) let startDate = endDate.addingTimeInterval(-basal.recommendation.duration) notify(.success(DoseEntry( type: .tempBasal, startDate: startDate, endDate: endDate, - value: body.rate, + value: response.rate, unit: .unitsPerHour ))) - case .failure(let error): + } catch let error { notify(.failure(error)) } } @@ -776,6 +879,28 @@ extension DeviceDataManager: LoopDataManagerDelegate { } +extension DeviceDataManager: PumpOpsDelegate { + func pumpOps(_ pumpOps: PumpOps, didChange state: PumpState) { + if let sentrySupported = pumpState?.pumpModel?.hasMySentry { + rileyLinkManager.idleListeningState = sentrySupported ? LoopSettings.idleListeningEnabledDefaults : .disabled + } + + UserDefaults.appGroup.pumpState = state + + // Update the pump-schedule based settings + loopManager.setScheduleTimeZone(state.timeZone) + + // Update the HKDevice to include the model change + updateDoseStoreDeviceFromRileyLink(state: state) + + // Update the preference for basal profile start events + if let recordsBasalProfileStartEvents = state.pumpModel?.recordsBasalProfileStartEvents { + loopManager.doseStore.pumpRecordsBasalProfileStartEvents = recordsBasalProfileStartEvents + } + } +} + + extension DeviceDataManager: CustomDebugStringConvertible { var debugDescription: String { return [ @@ -783,10 +908,17 @@ extension DeviceDataManager: CustomDebugStringConvertible { "## DeviceDataManager", "launchDate: \(launchDate)", "cgm: \(String(describing: cgm))", + "connectedPeripheralIDs: \(String(reflecting: connectedPeripheralIDs))", + "deviceStates: \(String(reflecting: deviceStates))", "lastError: \(String(describing: lastError))", + "lastTimerTick: \(String(describing: lastTimerTick))", + "latestPumpStatus: \(String(describing: latestPumpStatus))", "latestPumpStatusFromMySentry: \(String(describing: latestPumpStatusFromMySentry))", + "pumpBatteryChargeRemaining: \(String(reflecting: pumpBatteryChargeRemaining))", + "pumpSettings: \(String(reflecting: pumpSettings))", "pumpState: \(String(reflecting: pumpState))", "preferredInsulinDataSource: \(preferredInsulinDataSource)", + "sensorInfo: \(String(reflecting: sensorInfo))", cgmManager != nil ? String(reflecting: cgmManager!) : "", String(reflecting: rileyLinkManager), String(reflecting: statusExtensionManager!), diff --git a/Loop/Managers/LoopDataManager.swift b/Loop/Managers/LoopDataManager.swift index fcf0f16ac9..75abd492c3 100644 --- a/Loop/Managers/LoopDataManager.swift +++ b/Loop/Managers/LoopDataManager.swift @@ -41,12 +41,12 @@ final class LoopDataManager { delegate: LoopDataManagerDelegate, lastLoopCompleted: Date?, lastTempBasal: DoseEntry?, - basalRateSchedule: BasalRateSchedule? = UserDefaults.standard.basalRateSchedule, - carbRatioSchedule: CarbRatioSchedule? = UserDefaults.standard.carbRatioSchedule, - insulinModelSettings: InsulinModelSettings? = UserDefaults.standard.insulinModelSettings, - insulinCounteractionEffects: [GlucoseEffectVelocity]? = UserDefaults.standard.insulinCounteractionEffects, - insulinSensitivitySchedule: InsulinSensitivitySchedule? = UserDefaults.standard.insulinSensitivitySchedule, - settings: LoopSettings = UserDefaults.standard.loopSettings ?? LoopSettings() + basalRateSchedule: BasalRateSchedule? = UserDefaults.appGroup.basalRateSchedule, + carbRatioSchedule: CarbRatioSchedule? = UserDefaults.appGroup.carbRatioSchedule, + insulinModelSettings: InsulinModelSettings? = UserDefaults.appGroup.insulinModelSettings, + insulinCounteractionEffects: [GlucoseEffectVelocity]? = UserDefaults.appGroup.insulinCounteractionEffects, + insulinSensitivitySchedule: InsulinSensitivitySchedule? = UserDefaults.appGroup.insulinSensitivitySchedule, + settings: LoopSettings = UserDefaults.appGroup.loopSettings ?? LoopSettings() ) { self.delegate = delegate self.logger = DiagnosticLogger.shared!.forCategory("LoopDataManager") @@ -98,7 +98,7 @@ final class LoopDataManager { /// These are not thread-safe. var settings: LoopSettings { didSet { - UserDefaults.standard.loopSettings = settings + UserDefaults.appGroup.loopSettings = settings notify(forChange: .preferences) AnalyticsManager.shared.didChangeLoopSettings(from: oldValue, to: settings) } @@ -111,7 +111,7 @@ final class LoopDataManager { } set { doseStore.basalProfile = newValue - UserDefaults.standard.basalRateSchedule = newValue + UserDefaults.appGroup.basalRateSchedule = newValue notify(forChange: .preferences) } } @@ -124,7 +124,7 @@ final class LoopDataManager { } set { carbStore.carbRatioSchedule = newValue - UserDefaults.standard.carbRatioSchedule = newValue + UserDefaults.appGroup.carbRatioSchedule = newValue // Invalidate cached effects based on this schedule carbEffect = nil @@ -152,7 +152,7 @@ final class LoopDataManager { } set { doseStore.insulinModel = newValue?.model - UserDefaults.standard.insulinModelSettings = newValue + UserDefaults.appGroup.insulinModelSettings = newValue self.dataAccessQueue.async { // Invalidate cached effects based on this schedule @@ -168,7 +168,7 @@ final class LoopDataManager { /// A timeline of average velocity of glucose change counteracting predicted insulin effects fileprivate var insulinCounteractionEffects: [GlucoseEffectVelocity] { didSet { - UserDefaults.standard.insulinCounteractionEffects = insulinCounteractionEffects + UserDefaults.appGroup.insulinCounteractionEffects = insulinCounteractionEffects carbEffect = nil carbsOnBoard = nil } @@ -184,7 +184,7 @@ final class LoopDataManager { carbStore.insulinSensitivitySchedule = newValue doseStore.insulinSensitivitySchedule = newValue - UserDefaults.standard.insulinSensitivitySchedule = newValue + UserDefaults.appGroup.insulinSensitivitySchedule = newValue dataAccessQueue.async { // Invalidate cached effects based on this schedule @@ -1012,7 +1012,7 @@ protocol LoopState { /// Calculates a recommended bolus based on predicted glucose /// /// - Returns: A bolus recommendation - /// - Throws: An error describing why a bolus couldn't be computed + /// - Throws: An error describing why a bolus couldnʼt be computed /// - LoopError.configurationError /// - LoopError.glucoseTooOld /// - LoopError.missingDataError diff --git a/Loop/Managers/NightscoutDataManager.swift b/Loop/Managers/NightscoutDataManager.swift index c4ae3ffcc0..5e7706cce4 100644 --- a/Loop/Managers/NightscoutDataManager.swift +++ b/Loop/Managers/NightscoutDataManager.swift @@ -13,6 +13,8 @@ import HealthKit import InsulinKit import LoopKit import RileyLinkKit +import RileyLinkBLEKit + final class NightscoutDataManager { @@ -157,7 +159,7 @@ final class NightscoutDataManager { return UploaderStatus(name: uploaderDevice.name, timestamp: Date(), battery: battery) } - func uploadDeviceStatus(_ pumpStatus: NightscoutUploadKit.PumpStatus? = nil, loopStatus: LoopStatus? = nil, rileylinkDevice: RileyLinkKit.RileyLinkDevice? = nil, includeUploaderStatus: Bool = true) { + func uploadDeviceStatus(_ pumpStatus: NightscoutUploadKit.PumpStatus? = nil, loopStatus: LoopStatus? = nil, rileylinkDevice: RileyLinkDevice.Status? = nil, deviceState: DeviceState? = nil, includeUploaderStatus: Bool = true) { guard let uploader = deviceDataManager.remoteDataManager.nightscoutService.uploader else { return @@ -177,7 +179,15 @@ final class NightscoutDataManager { var radioAdapter: NightscoutUploadKit.RadioAdapter? = nil if let device = rileylinkDevice { - radioAdapter = NightscoutUploadKit.RadioAdapter(hardware: "RileyLink", frequency: device.radioFrequency, name: device.name ?? "Unknown", lastTuned: device.lastTuned, firmwareVersion: device.firmwareVersion ?? "Unknown", RSSI: device.RSSI, pumpRSSI: device.pumpRSSI) + radioAdapter = NightscoutUploadKit.RadioAdapter( + hardware: "RileyLink", + frequency: deviceState?.lastValidFrequency?.value, + name: device.name ?? "Unknown", + lastTuned: deviceState?.lastTuned, + firmwareVersion: device.firmwareDescription, + RSSI: nil, // TODO: device.RSSI, + pumpRSSI: nil // TODO: device.pumpRSSI + ) } // Build DeviceStatus diff --git a/Loop/Managers/RileyLinkDeviceManager.swift b/Loop/Managers/RileyLinkDeviceManager.swift index 99e0d05afb..3a999fcfd6 100644 --- a/Loop/Managers/RileyLinkDeviceManager.swift +++ b/Loop/Managers/RileyLinkDeviceManager.swift @@ -5,38 +5,12 @@ // Copyright © 2017 LoopKit Authors. All rights reserved. // -import RileyLinkKit - +import RileyLinkBLEKit extension RileyLinkDeviceManager { - /// Read the pump's current state, including reservoir and clock - /// - /// - Parameter completion: A closure called after the command is complete. This closure takes a single Result argument: - /// - Parameter result: - /// - success(status, date): The pump status, and the resolved date according to the pump's clock - /// - failure(error): An error describing why the command failed - func readPumpData(_ completion: @escaping (_ result: RileyLinkKit.Either<(status: RileyLinkKit.PumpStatus, date: Date), Error>) -> Void) { - guard let device = firstConnectedDevice, let ops = device.ops else { - completion(.failure(LoopError.connectionError)) - return - } - - ops.readPumpStatus { (result) in - switch result { - case .success(let status): - var clock = status.clock - clock.timeZone = ops.pumpState.timeZone - - guard let date = clock.date else { - let errorStr = "Could not interpret pump clock: \(clock)" - completion(.failure(LoopError.invalidData(details: errorStr))) - return - } - completion(.success((status: status, date: date))) - case .failure(let error): - completion(.failure(error)) - } + func firstConnectedDevice(_ completion: @escaping (_ device: RileyLinkDevice?) -> Void) { + getDevices { (devices) in + completion(devices.firstConnected) } } - } diff --git a/Loop/Managers/StatusExtensionDataManager.swift b/Loop/Managers/StatusExtensionDataManager.swift index d77e8a0b6a..094b4d98dd 100644 --- a/Loop/Managers/StatusExtensionDataManager.swift +++ b/Loop/Managers/StatusExtensionDataManager.swift @@ -24,7 +24,7 @@ final class StatusExtensionDataManager { } fileprivate var defaults: UserDefaults? { - return UserDefaults(suiteName: Bundle.main.appGroupSuiteName) + return UserDefaults.appGroup } var context: StatusExtensionContext? { diff --git a/Loop/Managers/WatchDataManager.swift b/Loop/Managers/WatchDataManager.swift index 101012339f..44255cd80f 100644 --- a/Loop/Managers/WatchDataManager.swift +++ b/Loop/Managers/WatchDataManager.swift @@ -11,7 +11,6 @@ import UIKit import WatchConnectivity import CarbKit import LoopKit -import xDripG5 final class WatchDataManager: NSObject, WCSessionDelegate { @@ -37,16 +36,36 @@ final class WatchDataManager: NSObject, WCSessionDelegate { } }() + private var lastActiveOverrideContext: GlucoseRangeSchedule.Override.Context? + private var lastConfiguredOverrideContexts: [GlucoseRangeSchedule.Override.Context] = [] + @objc private func updateWatch(_ notification: Notification) { guard - let rawContext = notification.userInfo?[LoopDataManager.LoopUpdateContextKey] as? LoopDataManager.LoopUpdateContext.RawValue, - let context = LoopDataManager.LoopUpdateContext(rawValue: rawContext), - case .tempBasal = context, + let rawUpdateContext = notification.userInfo?[LoopDataManager.LoopUpdateContextKey] as? LoopDataManager.LoopUpdateContext.RawValue, + let updateContext = LoopDataManager.LoopUpdateContext(rawValue: rawUpdateContext), let session = watchSession else { return } + switch updateContext { + case .tempBasal: + break + case .preferences: + let activeOverrideContext = deviceDataManager.loopManager.settings.glucoseTargetRangeSchedule?.activeOverrideContext + let configuredOverrideContexts = deviceDataManager.loopManager.settings.glucoseTargetRangeSchedule?.configuredOverrideContexts ?? [] + defer { + lastActiveOverrideContext = activeOverrideContext + lastConfiguredOverrideContexts = configuredOverrideContexts + } + + guard activeOverrideContext != lastActiveOverrideContext || configuredOverrideContexts != lastConfiguredOverrideContexts else { + return + } + default: + return + } + switch session.activationState { case .notActivated, .inactive: session.activate() @@ -109,6 +128,20 @@ final class WatchDataManager: NSObject, WCSessionDelegate { context.recommendedBolusDose = try? state.recommendBolus().amount context.maxBolus = manager.settings.maximumBolus + if let glucoseTargetRangeSchedule = manager.settings.glucoseTargetRangeSchedule { + if let override = glucoseTargetRangeSchedule.override { + context.glucoseRangeScheduleOverride = GlucoseRangeScheduleOverrideUserInfo( + context: override.context.correspondingUserInfoContext, + startDate: override.start, + endDate: override.end + ) + } + + let configuredOverrideContexts = self.deviceDataManager.loopManager.settings.glucoseTargetRangeSchedule?.configuredOverrideContexts ?? [] + let configuredUserInfoOverrideContexts = configuredOverrideContexts.map { $0.correspondingUserInfoContext } + context.configuredOverrideContexts = configuredUserInfoOverrideContexts + } + if let trend = self.deviceDataManager.sensorInfo?.trendType { context.glucoseTrendRawValue = trend.rawValue } @@ -144,7 +177,7 @@ final class WatchDataManager: NSObject, WCSessionDelegate { // MARK: WCSessionDelegate - func session(_ session: WCSession, didReceiveMessage message: [String : Any], replyHandler: @escaping ([String: Any]) -> Void) { + func session(_ session: WCSession, didReceiveMessage message: [String: Any], replyHandler: @escaping ([String: Any]) -> Void) { switch message["name"] as? String { case CarbEntryUserInfo.name?: addCarbEntryFromWatchMessage(message) { (units) in @@ -160,12 +193,32 @@ final class WatchDataManager: NSObject, WCSessionDelegate { } replyHandler([:]) + case GlucoseRangeScheduleOverrideUserInfo.name?: + if let overrideUserInfo = GlucoseRangeScheduleOverrideUserInfo(rawValue: message) { + let overrideContext = overrideUserInfo.context.correspondingOverrideContext + + // update the recorded last active override context prior to enabling the actual override + // to prevent the Watch context being unnecessarily sent in response to the override being enabled + let previousActiveOverrideContext = lastActiveOverrideContext + lastActiveOverrideContext = overrideContext + let overrideSuccess = deviceDataManager.loopManager.settings.glucoseTargetRangeSchedule?.setOverride(overrideContext, from: overrideUserInfo.startDate, until: overrideUserInfo.effectiveEndDate) + + if overrideSuccess == false { + lastActiveOverrideContext = previousActiveOverrideContext + } + + replyHandler([:]) + } else { + lastActiveOverrideContext = nil + deviceDataManager.loopManager.settings.glucoseTargetRangeSchedule?.clearOverride() + replyHandler([:]) + } default: replyHandler([:]) } } - func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any]) { + func session(_ session: WCSession, didReceiveUserInfo userInfo: [String: Any]) { addCarbEntryFromWatchMessage(userInfo) } @@ -195,5 +248,26 @@ final class WatchDataManager: NSObject, WCSessionDelegate { watchSession?.delegate = self watchSession?.activate() } +} + +fileprivate extension GlucoseRangeSchedule.Override.Context { + var correspondingUserInfoContext: GlucoseRangeScheduleOverrideUserInfo.Context { + switch self { + case .preMeal: + return .preMeal + case .workout: + return .workout + } + } +} +fileprivate extension GlucoseRangeScheduleOverrideUserInfo.Context { + var correspondingOverrideContext: GlucoseRangeSchedule.Override.Context { + switch self { + case .preMeal: + return .preMeal + case .workout: + return .workout + } + } } diff --git a/Loop/Models/Glucose.swift b/Loop/Models/Glucose.swift index 5a57920ebe..dc614aecef 100644 --- a/Loop/Models/Glucose.swift +++ b/Loop/Models/Glucose.swift @@ -8,12 +8,12 @@ import Foundation import LoopUI -import xDripG5 +import CGMBLEKit extension Glucose: SensorDisplayable { public var isStateValid: Bool { - return state == .ok && status == .ok + return state == .known(.ok) && status == .ok } public var stateDescription: String { diff --git a/Loop/Models/LoopSettings.swift b/Loop/Models/LoopSettings.swift index b01a463683..24d374a153 100644 --- a/Loop/Models/LoopSettings.swift +++ b/Loop/Models/LoopSettings.swift @@ -6,6 +6,7 @@ // import LoopKit +import RileyLinkBLEKit struct LoopSettings { @@ -25,6 +26,12 @@ struct LoopSettings { } +// MARK: - Static configuration +extension LoopSettings { + static let idleListeningEnabledDefaults: RileyLinkDevice.IdleListeningState = .enabled(timeout: .minutes(4), channel: 0) +} + + extension LoopSettings { var enabledEffects: PredictionInputEffect { var inputs = PredictionInputEffect.all diff --git a/Loop/Models/WatchContext+LoopKit.swift b/Loop/Models/WatchContext+LoopKit.swift index ae24ada8ae..bf6ac5b603 100644 --- a/Loop/Models/WatchContext+LoopKit.swift +++ b/Loop/Models/WatchContext+LoopKit.swift @@ -10,8 +10,6 @@ import Foundation import HealthKit import InsulinKit import LoopKit -import xDripG5 - extension WatchContext { convenience init(glucose: GlucoseValue?, eventualGlucose: GlucoseValue?, glucoseUnit: HKUnit?) { diff --git a/Loop/View Controllers/RadioSelectionTableViewController.swift b/Loop/View Controllers/RadioSelectionTableViewController.swift index fc13d26427..1b119e30cb 100644 --- a/Loop/View Controllers/RadioSelectionTableViewController.swift +++ b/Loop/View Controllers/RadioSelectionTableViewController.swift @@ -78,7 +78,7 @@ extension RadioSelectionTableViewController { let vc = T() vc.selectedIndex = value.rawValue - vc.options = (0..<2).flatMap({ InsulinDataSource(rawValue: $0) }).map { String(describing: $0) } + vc.options = (0..<2).compactMap({ InsulinDataSource(rawValue: $0) }).map { String(describing: $0) } vc.contextHelp = NSLocalizedString("Insulin delivery can be determined from the pump by either interpreting the event history or comparing the reservoir volume over time. Reading event history allows for a more accurate status graph and uploading up-to-date treatment data to Nightscout, at the cost of faster pump battery drain and the possibility of a higher radio error rate compared to reading only reservoir volume. If the selected source cannot be used for any reason, the system will attempt to fall back to the other option.", comment: "Instructions on selecting an insulin data source") return vc @@ -88,7 +88,7 @@ extension RadioSelectionTableViewController { let vc = T() vc.selectedIndex = value.rawValue - vc.options = (0..<2).flatMap({ BatteryChemistryType(rawValue: $0) }).map { String(describing: $0) } + vc.options = (0..<2).compactMap({ BatteryChemistryType(rawValue: $0) }).map { String(describing: $0) } vc.contextHelp = NSLocalizedString("Alkaline and Lithium batteries decay at differing rates. Alkaline tend to have a linear voltage drop over time whereas lithium cell batteries tend to maintain voltage until halfway through their lifespan. Under normal usage in a Non-MySentry compatible Minimed (x22/x15) insulin pump running Loop, Alkaline batteries last approximately 4 to 5 days. Lithium batteries last between 1-2 weeks. This selection will use different battery voltage decay rates for each of the battery chemistry types and alert the user when a battery is approximately 8 to 10 hours from failure.", comment: "Instructions on selecting battery chemistry type") return vc diff --git a/Loop/View Controllers/SettingsTableViewController.swift b/Loop/View Controllers/SettingsTableViewController.swift index 4c530cff8b..660b64fe18 100644 --- a/Loop/View Controllers/SettingsTableViewController.swift +++ b/Loop/View Controllers/SettingsTableViewController.swift @@ -10,8 +10,10 @@ import UIKit import HealthKit import InsulinKit import LoopKit -import RileyLinkKit import MinimedKit +import RileyLinkBLEKit +import RileyLinkKit +import RileyLinkKitUI private let ConfigCellIdentifier = "ConfigTableViewCell" @@ -29,32 +31,25 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = 44 - tableView.register(RileyLinkDeviceTableViewCell.nib(), forCellReuseIdentifier: RileyLinkDeviceTableViewCell.className) + tableView.register(RileyLinkDeviceTableViewCell.self, forCellReuseIdentifier: RileyLinkDeviceTableViewCell.className) - dataManagerObserver = NotificationCenter.default.addObserver(forName: nil, object: dataManager, queue: nil) { [weak self = self] (note) -> Void in - DispatchQueue.main.async { - if let deviceManager = self?.dataManager.rileyLinkManager { - switch note.name { - case Notification.Name.DeviceManagerDidDiscoverDevice: - self?.tableView.insertRows(at: [IndexPath(row: deviceManager.devices.count - 1, section: Section.devices.rawValue)], with: .automatic) - case Notification.Name.DeviceConnectionStateDidChange, - Notification.Name.DeviceRSSIDidChange, - Notification.Name.DeviceNameDidChange: - if let device = note.userInfo?[RileyLinkDeviceManager.RileyLinkDeviceKey] as? RileyLinkDevice, let index = deviceManager.devices.index(where: { $0 === device }) { - self?.tableView.reloadRows(at: [IndexPath(row: index, section: Section.devices.rawValue)], with: .none) - } - default: - break - } - } - } + // Register for manager notifications + NotificationCenter.default.addObserver(self, selector: #selector(reloadDevices), name: .ManagerDevicesDidChange, object: dataManager.rileyLinkManager) + + // Register for device notifications + for name in [.DeviceConnectionStateDidChange, .DeviceRSSIDidChange, .DeviceNameDidChange] as [Notification.Name] { + NotificationCenter.default.addObserver(self, selector: #selector(deviceDidUpdate(_:)), name: name, object: nil) } + + reloadDevices() } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) - dataManager.rileyLinkManager.setDeviceScanningEnabled(true) + dataManager.rileyLinkManager.setScanningEnabled(true) + rssiFetchTimer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(updateRSSI), userInfo: nil, repeats: true) + updateRSSI() if case .some = dataManager.cgm, dataManager.loopManager.glucoseStore.authorizationRequired { dataManager.loopManager.glucoseStore.authorize { (success, error) -> Void in @@ -65,26 +60,15 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu AnalyticsManager.shared.didDisplaySettingsScreen() } - override func viewDidDisappear(_ animated: Bool) { - super.viewDidDisappear(animated) - - dataManager.rileyLinkManager.setDeviceScanningEnabled(false) - } + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) - deinit { - dataManagerObserver = nil + dataManager.rileyLinkManager.setScanningEnabled(false) + rssiFetchTimer = nil } var dataManager: DeviceDataManager! - private var dataManagerObserver: Any? { - willSet { - if let observer = dataManagerObserver { - NotificationCenter.default.removeObserver(observer) - } - } - } - fileprivate enum Section: Int, CaseCountable { case loop = 0 case devices @@ -188,7 +172,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu case .configuration: return ConfigurationRow.count case .devices: - return dataManager.rileyLinkManager.devices.count + return devices.count case .services: return ServiceRow.count } @@ -227,7 +211,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu switch PumpRow(rawValue: indexPath.row)! { case .pumpID: configCell.textLabel?.text = NSLocalizedString("Pump ID", comment: "The title text for the pump ID config value") - configCell.detailTextLabel?.text = dataManager.pumpID ?? TapToSetString + configCell.detailTextLabel?.text = dataManager.pumpSettings?.pumpID ?? TapToSetString case .batteryChemistry: configCell.textLabel?.text = NSLocalizedString("Pump Battery Type", comment: "The title text for the battery type value") configCell.detailTextLabel?.text = String(describing: dataManager.batteryChemistry) @@ -366,14 +350,14 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu return configCell case .devices: let deviceCell = tableView.dequeueReusableCell(withIdentifier: RileyLinkDeviceTableViewCell.className) as! RileyLinkDeviceTableViewCell - let device = dataManager.rileyLinkManager.devices[indexPath.row] + let device = devices[indexPath.row] deviceCell.configureCellWithName(device.name, - signal: device.RSSI, - peripheralState: device.peripheral.state + signal: valueNumberFormatter.decibleString(from: deviceRSSI[device.peripheralIdentifier]), + peripheralState: device.peripheralState ) - deviceCell.connectSwitch.addTarget(self, action: #selector(deviceConnectionChanged(_:)), for: .valueChanged) + deviceCell.connectSwitch?.addTarget(self, action: #selector(deviceConnectionChanged(_:)), for: .valueChanged) return deviceCell case .services: @@ -449,10 +433,10 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu let row = PumpRow(rawValue: indexPath.row)! switch row { case .pumpID: - let vc: TextFieldTableViewController + let vc: LoopKit.TextFieldTableViewController switch row { case .pumpID: - vc = PumpIDTableViewController(pumpID: dataManager.pumpID, region: dataManager.pumpState?.pumpRegion) + vc = PumpIDTableViewController(pumpID: dataManager.pumpSettings?.pumpID, region: dataManager.pumpSettings?.pumpRegion) default: fatalError() } @@ -481,7 +465,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu show(vc, sender: sender) case .g5TransmitterID: - let vc: TextFieldTableViewController + let vc: LoopKit.TextFieldTableViewController var value: String? if case .g5(let transmitterID)? = dataManager.cgm { @@ -501,7 +485,7 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu let row = ConfigurationRow(rawValue: indexPath.row)! switch row { case .maxBasal, .maxBolus: - let vc: TextFieldTableViewController + let vc: LoopKit.TextFieldTableViewController switch row { case .maxBasal: @@ -617,10 +601,21 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu performSegue(withIdentifier: InsulinModelSettingsViewController.className, sender: sender) } case .devices: - let vc = RileyLinkDeviceTableViewController() - vc.device = dataManager.rileyLinkManager.devices[indexPath.row] + let device = devices[indexPath.row] - show(vc, sender: sender) + dataManager.getStateForDevice(device) { (deviceState, pumpState, pumpSettings, pumpOps) in + DispatchQueue.main.async { + let vc = RileyLinkDeviceTableViewController( + device: device, + deviceState: deviceState, + pumpSettings: pumpSettings, + pumpState: pumpState, + pumpOps: pumpOps + ) + + self.show(vc, sender: sender) + } + } case .loop: switch LoopRow(rawValue: indexPath.row)! { case .preferredInsulinDataSource: @@ -698,12 +693,70 @@ final class SettingsTableViewController: UITableViewController, DailyValueSchedu dataManager.loopManager.settings.dosingEnabled = sender.isOn } + @objc private func reloadDevices() { + self.dataManager.rileyLinkManager.getDevices { (devices) in + DispatchQueue.main.async { + self.devices = devices + } + } + } + + @objc private func deviceDidUpdate(_ note: Notification) { + DispatchQueue.main.async { + if let device = note.object as? RileyLinkDevice, let index = self.devices.index(where: { $0 === device }) { + if let rssi = note.userInfo?[RileyLinkDevice.notificationRSSIKey] as? Int { + self.deviceRSSI[device.peripheralIdentifier] = rssi + } + + if let cell = self.tableView.cellForRow(at: IndexPath(row: index, section: Section.devices.rawValue)) as? RileyLinkDeviceTableViewCell { + cell.configureCellWithName(device.name, + signal: self.valueNumberFormatter.decibleString(from: self.deviceRSSI[device.peripheralIdentifier]), + peripheralState: device.peripheralState + ) + } + } + } + } + + private var devices: [RileyLinkDevice] = [] { + didSet { + // Assume only appends are possible when count changes for algorithmic simplicity + guard oldValue.count < devices.count else { + tableView.reloadSections(IndexSet(integer: Section.devices.rawValue), with: .fade) + return + } + + tableView.beginUpdates() + + let insertedPaths = (oldValue.count.. IndexPath in + return IndexPath(row: index, section: Section.devices.rawValue) + } + tableView.insertRows(at: insertedPaths, with: .automatic) + + tableView.endUpdates() + } + } + + private var deviceRSSI: [UUID: Int] = [:] + + var rssiFetchTimer: Timer? { + willSet { + rssiFetchTimer?.invalidate() + } + } + + @objc func updateRSSI() { + for device in devices { + device.readRSSI() + } + } + @objc private func deviceConnectionChanged(_ connectSwitch: UISwitch) { let switchOrigin = connectSwitch.convert(CGPoint.zero, to: tableView) if let indexPath = tableView.indexPathForRow(at: switchOrigin), indexPath.section == Section.devices.rawValue { - let device = dataManager.rileyLinkManager.devices[indexPath.row] + let device = devices[indexPath.row] if connectSwitch.isOn { dataManager.connectToRileyLink(device) @@ -908,19 +961,19 @@ extension SettingsTableViewController: RadioSelectionTableViewControllerDelegate } } -extension SettingsTableViewController: TextFieldTableViewControllerDelegate { - func textFieldTableViewControllerDidEndEditing(_ controller: TextFieldTableViewController) { +extension SettingsTableViewController: LoopKit.TextFieldTableViewControllerDelegate { + func textFieldTableViewControllerDidEndEditing(_ controller: LoopKit.TextFieldTableViewController) { if let indexPath = controller.indexPath { switch Section(rawValue: indexPath.section)! { case .pump: switch PumpRow(rawValue: indexPath.row)! { case .pumpID: - dataManager.pumpID = controller.value + dataManager.setPumpID(controller.value) if let controller = controller as? PumpIDTableViewController, let region = controller.region { - dataManager.pumpState?.pumpRegion = region + dataManager.setPumpRegion(region) } default: assertionFailure() @@ -970,7 +1023,7 @@ extension SettingsTableViewController: TextFieldTableViewControllerDelegate { tableView.reloadData() } - func textFieldTableViewControllerDidReturn(_ controller: TextFieldTableViewController) { + func textFieldTableViewControllerDidReturn(_ controller: LoopKit.TextFieldTableViewController) { _ = navigationController?.popViewController(animated: true) } } @@ -979,7 +1032,7 @@ extension SettingsTableViewController: TextFieldTableViewControllerDelegate { extension SettingsTableViewController: PumpIDTableViewControllerDelegate { func pumpIDTableViewControllerDidChangePumpRegion(_ controller: PumpIDTableViewController) { if let region = controller.region { - dataManager.pumpState?.pumpRegion = region + dataManager.setPumpRegion(region) } } } diff --git a/Loop/View Controllers/TextFieldTableViewController.swift b/Loop/View Controllers/TextFieldTableViewController.swift index c343def6be..e59b5e5a5c 100644 --- a/Loop/View Controllers/TextFieldTableViewController.swift +++ b/Loop/View Controllers/TextFieldTableViewController.swift @@ -51,6 +51,7 @@ extension TextFieldTableViewController { vc.placeholder = NSLocalizedString("Enter a rate in units per hour", comment: "The placeholder text instructing users how to enter a maximum basal rate") vc.keyboardType = .decimalPad vc.unit = NSLocalizedString("U/hour", comment: "The unit string for units per hour") + vc.contextHelp = NSLocalizedString("Please check that the maximum basal rate entered here does not exceed the corresponding maximum basal rate setting in the pump.", comment: "Instructions to help get max basal rate setting correct.") if let maxBasal = value { vc.value = valueNumberFormatter.string(from: NSNumber(value: maxBasal)) diff --git a/Loop/gallery.ckcomplication/complicationManifest.json b/Loop/gallery.ckcomplication/complicationManifest.json index 4f8f78a91d..7c531785e5 100644 --- a/Loop/gallery.ckcomplication/complicationManifest.json +++ b/Loop/gallery.ckcomplication/complicationManifest.json @@ -8,5 +8,5 @@ "6" : "688917AC-E1E4-4B66-9B44-6EE17F1D19DB.json", "2" : "59939B64-2F84-4438-8860-91BB63BE827B.json" }, - "client ID" : "com.loudnate.Loop.watchkitapp.watchkitextension" -} \ No newline at end of file + "client ID" : "com.loudnate.Loop.LoopWatch.watchkitextension" +} diff --git a/LoopTests/Info.plist b/LoopTests/Info.plist index 766853d4a4..5bd34daaf6 100644 --- a/LoopTests/Info.plist +++ b/LoopTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.5.3 + 1.5.4 CFBundleSignature ???? CFBundleVersion diff --git a/LoopUI/Info.plist b/LoopUI/Info.plist index 94e5753cdd..3ac46b5881 100644 --- a/LoopUI/Info.plist +++ b/LoopUI/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.5.3 + 1.5.4 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/LoopUI/Managers/StatusChartsManager.swift b/LoopUI/Managers/StatusChartsManager.swift index 8019c33085..476990b437 100644 --- a/LoopUI/Managers/StatusChartsManager.swift +++ b/LoopUI/Managers/StatusChartsManager.swift @@ -417,7 +417,7 @@ public final class StatusChartsManager { frame: frame, innerFrame: innerFrame, settings: chartSettings, - layers: layers.flatMap { $0 } + layers: layers.compactMap { $0 } ) } @@ -487,7 +487,7 @@ public final class StatusChartsManager { iobLine, ] - return Chart(frame: frame, innerFrame: innerFrame, settings: chartSettings, layers: layers.flatMap { $0 }) + return Chart(frame: frame, innerFrame: innerFrame, settings: chartSettings, layers: layers.compactMap { $0 }) } public func cobChartWithFrame(_ frame: CGRect) -> Chart? { @@ -544,7 +544,7 @@ public final class StatusChartsManager { cobLine ] - return Chart(frame: frame, innerFrame: innerFrame, settings: chartSettings, layers: layers.flatMap { $0 }) + return Chart(frame: frame, innerFrame: innerFrame, settings: chartSettings, layers: layers.compactMap { $0 }) } public func doseChartWithFrame(_ frame: CGRect) -> Chart? { @@ -632,7 +632,7 @@ public final class StatusChartsManager { bolusLayer ] - return Chart(frame: frame, innerFrame: innerFrame, settings: chartSettings, layers: layers.flatMap { $0 }) + return Chart(frame: frame, innerFrame: innerFrame, settings: chartSettings, layers: layers.compactMap { $0 }) } // MARK: - Carb Effect @@ -765,7 +765,7 @@ public final class StatusChartsManager { frame: frame, innerFrame: innerFrame, settings: chartSettings, - layers: layers.flatMap { $0 } + layers: layers.compactMap { $0 } ) } @@ -893,7 +893,7 @@ public final class StatusChartsManager { frame: frame, innerFrame: coordsSpace.chartInnerFrame, settings: chartSettings, - layers: layers.flatMap { $0 } + layers: layers.compactMap { $0 } ) } diff --git a/LoopUI/Views/ChartPointsContextFillLayer.swift b/LoopUI/Views/ChartPointsContextFillLayer.swift index a2824336ce..220c5b9480 100644 --- a/LoopUI/Views/ChartPointsContextFillLayer.swift +++ b/LoopUI/Views/ChartPointsContextFillLayer.swift @@ -59,7 +59,7 @@ final class ChartPointsFillsLayer: ChartCoordsSpaceLayer { let fills: [ChartPointsFill] init?(xAxis: ChartAxis, yAxis: ChartAxis, fills: [ChartPointsFill?]) { - self.fills = fills.flatMap({ $0 }) + self.fills = fills.compactMap({ $0 }) guard fills.count > 0 else { return nil diff --git a/WatchApp Extension/Controllers/AddCarbsInterfaceController.swift b/WatchApp Extension/Controllers/AddCarbsInterfaceController.swift index cf4dc3dd8f..e21d0fe8ac 100644 --- a/WatchApp Extension/Controllers/AddCarbsInterfaceController.swift +++ b/WatchApp Extension/Controllers/AddCarbsInterfaceController.swift @@ -163,10 +163,14 @@ final class AddCarbsInterfaceController: WKInterfaceController, IdentifiableClas do { try WCSession.default.sendCarbEntryMessage(entry, replyHandler: { (suggestion) in - WKExtension.shared().rootInterfaceController?.presentController(withName: BolusInterfaceController.className, context: suggestion) + DispatchQueue.main.async { + WKExtension.shared().rootInterfaceController?.presentController(withName: BolusInterfaceController.className, context: suggestion) + } }, errorHandler: { (error) in - ExtensionDelegate.shared().present(error) + DispatchQueue.main.async { + ExtensionDelegate.shared().present(error) + } } ) } catch { diff --git a/WatchApp Extension/Controllers/BolusInterfaceController.swift b/WatchApp Extension/Controllers/BolusInterfaceController.swift index 721100ace6..991d55ce3d 100644 --- a/WatchApp Extension/Controllers/BolusInterfaceController.swift +++ b/WatchApp Extension/Controllers/BolusInterfaceController.swift @@ -137,7 +137,9 @@ final class BolusInterfaceController: WKInterfaceController, IdentifiableClass { do { try WCSession.default.sendBolusMessage(bolus) { (error) in - ExtensionDelegate.shared().present(error) + DispatchQueue.main.async { + ExtensionDelegate.shared().present(error) + } } } catch { presentAlert( diff --git a/WatchApp Extension/Controllers/StatusInterfaceController.swift b/WatchApp Extension/Controllers/StatusInterfaceController.swift index f1d4a31664..fafedbe369 100644 --- a/WatchApp Extension/Controllers/StatusInterfaceController.swift +++ b/WatchApp Extension/Controllers/StatusInterfaceController.swift @@ -7,7 +7,7 @@ // import WatchKit -import Foundation +import WatchConnectivity final class StatusInterfaceController: WKInterfaceController, ContextUpdatable { @@ -18,6 +18,73 @@ final class StatusInterfaceController: WKInterfaceController, ContextUpdatable { @IBOutlet weak var eventualGlucoseLabel: WKInterfaceLabel! @IBOutlet weak var statusLabel: WKInterfaceLabel! + @IBOutlet var preMealButton: WKInterfaceButton! + @IBOutlet var preMealButtonImage: WKInterfaceImage! + @IBOutlet var preMealButtonBackground: WKInterfaceGroup! + + @IBOutlet var workoutButton: WKInterfaceButton! + @IBOutlet var workoutButtonImage: WKInterfaceImage! + @IBOutlet var workoutButtonBackground: WKInterfaceGroup! + + private class ButtonGroup { + private let button: WKInterfaceButton + private let image: WKInterfaceImage + private let background: WKInterfaceGroup + private let onBackgroundColor: UIColor + private let offBackgroundColor: UIColor + + enum State { + case on + case off + case disabled + } + + var state: State = .off { + didSet { + let imageTintColor: UIColor + let backgroundColor: UIColor + switch state { + case .on: + imageTintColor = offBackgroundColor + backgroundColor = onBackgroundColor + case .off: + imageTintColor = onBackgroundColor + backgroundColor = offBackgroundColor + case .disabled: + imageTintColor = .disabledButtonColor + backgroundColor = .darkDisabledButtonColor + } + + button.setEnabled(state != .disabled) + image.setTintColor(imageTintColor) + background.setBackgroundColor(backgroundColor) + } + } + + init(button: WKInterfaceButton, image: WKInterfaceImage, background: WKInterfaceGroup, onBackgroundColor: UIColor, offBackgroundColor: UIColor) { + self.button = button + self.image = image + self.background = background + self.onBackgroundColor = onBackgroundColor + self.offBackgroundColor = offBackgroundColor + } + + func turnOff() { + switch state { + case .on: + state = .off + case .off, .disabled: + break + } + } + } + + private lazy var preMealButtonGroup = ButtonGroup(button: preMealButton, image: preMealButtonImage, background: preMealButtonBackground, onBackgroundColor: .carbsColor, offBackgroundColor: .darkCarbsColor) + + private lazy var workoutButtonGroup = ButtonGroup(button: workoutButton, image: workoutButtonImage, background: workoutButtonBackground, onBackgroundColor: .workoutColor, offBackgroundColor: .darkWorkoutColor) + + private var lastOverrideContext: GlucoseRangeScheduleOverrideUserInfo.Context? + private var lastContext: WatchContext? override func didAppear() { @@ -65,36 +132,77 @@ final class StatusInterfaceController: WKInterfaceController, ContextUpdatable { loopHUDImage.setLoopImage(.Unknown) } - guard let glucose = context?.glucose, - let unit = context?.preferredGlucoseUnit - else { - glucoseLabel.setHidden(true) - eventualGlucoseLabel.setHidden(true) - return - } + if let glucose = context?.glucose, let unit = context?.preferredGlucoseUnit { + let formatter = NumberFormatter.glucoseFormatter(for: unit) - let formatter = NumberFormatter.glucoseFormatter(for: unit) + if let glucoseValue = formatter.string(from: NSNumber(value: glucose.doubleValue(for: unit))) { + let trend = context?.glucoseTrend?.symbol ?? "" + self.glucoseLabel.setText(glucoseValue + trend) + self.glucoseLabel.setHidden(false) + } else { + glucoseLabel.setHidden(true) + } - if let glucoseValue = formatter.string(from: NSNumber(value: glucose.doubleValue(for: unit))){ - let trend = context?.glucoseTrend?.symbol ?? "" - self.glucoseLabel.setText(glucoseValue + trend) - self.glucoseLabel.setHidden(false) + if let eventualGlucose = context?.eventualGlucose { + let glucoseValue = formatter.string(from: NSNumber(value: eventualGlucose.doubleValue(for: unit))) + self.eventualGlucoseLabel.setText(glucoseValue) + self.eventualGlucoseLabel.setHidden(false) + } else { + eventualGlucoseLabel.setHidden(true) + } } else { glucoseLabel.setHidden(true) + eventualGlucoseLabel.setHidden(true) } - if let eventualGlucose = context?.eventualGlucose { - let glucoseValue = formatter.string(from: NSNumber(value: eventualGlucose.doubleValue(for: unit))) - self.eventualGlucoseLabel.setText(glucoseValue) - self.eventualGlucoseLabel.setHidden(false) + let overrideContext: GlucoseRangeScheduleOverrideUserInfo.Context? + if let glucoseRangeScheduleOverride = context?.glucoseRangeScheduleOverride, (glucoseRangeScheduleOverride.startDate...glucoseRangeScheduleOverride.effectiveEndDate).contains(Date()) + { + overrideContext = glucoseRangeScheduleOverride.context } else { - eventualGlucoseLabel.setHidden(true) + overrideContext = nil } - + updateForOverrideContext(overrideContext) + lastOverrideContext = overrideContext + + if let configuredOverrideContexts = context?.configuredOverrideContexts { + for overrideContext in GlucoseRangeScheduleOverrideUserInfo.Context.allContexts { + let contextButtonGroup = buttonGroup(for: overrideContext) + if !configuredOverrideContexts.contains(overrideContext) { + contextButtonGroup.state = .disabled + } else if contextButtonGroup.state == .disabled { + contextButtonGroup.state = .off + } + } + } + // TODO: Other elements statusLabel.setHidden(true) } + private func updateForOverrideContext(_ context: GlucoseRangeScheduleOverrideUserInfo.Context?) { + switch context { + case .preMeal?: + preMealButtonGroup.state = .on + workoutButtonGroup.turnOff() + case .workout?: + preMealButtonGroup.turnOff() + workoutButtonGroup.state = .on + case nil: + preMealButtonGroup.turnOff() + workoutButtonGroup.turnOff() + } + } + + private func buttonGroup(for overrideContext: GlucoseRangeScheduleOverrideUserInfo.Context) -> ButtonGroup { + switch overrideContext { + case .preMeal: + return preMealButtonGroup + case .workout: + return workoutButtonGroup + } + } + // MARK: - Menu Items @IBAction func addCarbs() { @@ -105,4 +213,66 @@ final class StatusInterfaceController: WKInterfaceController, ContextUpdatable { presentController(withName: BolusInterfaceController.className, context: lastContext?.bolusSuggestion) } + @IBAction func togglePreMealMode() { + let userInfo: GlucoseRangeScheduleOverrideUserInfo? + if preMealButtonGroup.state == .on { + userInfo = nil + } else { + userInfo = GlucoseRangeScheduleOverrideUserInfo(context: .preMeal, startDate: Date(), endDate: Date(timeIntervalSinceNow: .hours(1))) + } + + updateForOverrideContext(userInfo?.context) + sendGlucoseRangeOverride(userInfo: userInfo) + } + + @IBAction func toggleWorkoutMode() { + let userInfo: GlucoseRangeScheduleOverrideUserInfo? + if workoutButtonGroup.state == .on { + userInfo = nil + } else { + userInfo = GlucoseRangeScheduleOverrideUserInfo(context: .workout, startDate: Date(), endDate: nil) + } + + updateForOverrideContext(userInfo?.context) + sendGlucoseRangeOverride(userInfo: userInfo) + } + + private var pendingMessageResponses = 0 + + private func sendGlucoseRangeOverride(userInfo: GlucoseRangeScheduleOverrideUserInfo?) { + pendingMessageResponses += 1 + do { + try WCSession.default.sendGlucoseRangeScheduleOverrideMessage(userInfo, + replyHandler: { _ in + DispatchQueue.main.async { + self.pendingMessageResponses -= 1 + if self.pendingMessageResponses == 0 { + self.updateForOverrideContext(userInfo?.context) + } + self.lastOverrideContext = userInfo?.context + } + }, + errorHandler: { error in + DispatchQueue.main.async { + self.pendingMessageResponses -= 1 + if self.pendingMessageResponses == 0 { + self.updateForOverrideContext(self.lastOverrideContext) + } + ExtensionDelegate.shared().present(error) + } + } + ) + } catch { + pendingMessageResponses -= 1 + if pendingMessageResponses == 0 { + updateForOverrideContext(lastOverrideContext) + } + presentAlert( + withTitle: NSLocalizedString("Send Failed", comment: "The title of the alert controller displayed after a glucose range override send attempt fails"), + message: NSLocalizedString("Make sure your iPhone is nearby and try again", comment: "The recovery message displayed after a glucose range override send attempt fails"), + preferredStyle: .alert, + actions: [WKAlertAction.dismissAction()] + ) + } + } } diff --git a/WatchApp Extension/ExtensionDelegate.swift b/WatchApp Extension/ExtensionDelegate.swift index c77c95a126..2e76860093 100644 --- a/WatchApp Extension/ExtensionDelegate.swift +++ b/WatchApp Extension/ExtensionDelegate.swift @@ -164,7 +164,7 @@ final class ExtensionDelegate: NSObject, WKExtensionDelegate { extension ExtensionDelegate: WCSessionDelegate { func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) { - if activationState == .activated && lastContext == nil { + if activationState == .activated { updateContext(session.receivedApplicationContext) } } diff --git a/WatchApp Extension/Extensions/UIColor.swift b/WatchApp Extension/Extensions/UIColor.swift index 3995e6e60a..4f9d036a63 100644 --- a/WatchApp Extension/Extensions/UIColor.swift +++ b/WatchApp Extension/Extensions/UIColor.swift @@ -14,7 +14,17 @@ extension UIColor { @nonobjc static let carbsColor = UIColor(red: 99 / 255, green: 218 / 255, blue: 56 / 255, alpha: 1) - @nonobjc static let darkCarbsColor = UIColor.carbsColor.withAlphaComponent(0.14) + // Equivalent to carbsColor with alpha 0.14 on a black background + @nonobjc static let darkCarbsColor = UIColor(red: 0.07, green: 0.12, blue: 0.04, alpha: 1) + + @nonobjc static let workoutColor = UIColor(red: 79 / 255, green: 173 / 255, blue: 248 / 255, alpha: 1) + + // Equivalent to workoutColor with alpha 0.14 on a black background + @nonobjc static let darkWorkoutColor = UIColor(red: 0.02, green: 0.10, blue: 0.14, alpha: 1) + + @nonobjc static let disabledButtonColor = UIColor.gray + + @nonobjc static let darkDisabledButtonColor = UIColor.disabledButtonColor.withAlphaComponent(0.14) // MARK: - HIG colors // See: https://developer.apple.com/watch/human-interface-guidelines/visual-design/#color diff --git a/WatchApp Extension/Extensions/WCSession.swift b/WatchApp Extension/Extensions/WCSession.swift index 346b7ced61..11c9114131 100644 --- a/WatchApp Extension/Extensions/WCSession.swift +++ b/WatchApp Extension/Extensions/WCSession.swift @@ -28,7 +28,7 @@ extension WCSession { } sendMessage(carbEntry.rawValue, - replyHandler: { (reply) in + replyHandler: { reply in guard let suggestion = BolusSuggestionUserInfo(rawValue: reply as BolusSuggestionUserInfo.RawValue) else { errorHandler(MessageError.decodingError) return @@ -50,8 +50,22 @@ extension WCSession { } sendMessage(userInfo.rawValue, - replyHandler: { (reply) in - }, + replyHandler: { reply in }, + errorHandler: errorHandler + ) + } + + func sendGlucoseRangeScheduleOverrideMessage(_ userInfo: GlucoseRangeScheduleOverrideUserInfo?, replyHandler: @escaping ([String: Any]) -> Void, errorHandler: @escaping (Error) -> Void) throws { + guard activationState == .activated else { + throw MessageError.activationError + } + + guard isReachable else { + throw MessageError.reachabilityError + } + + sendMessage(userInfo?.rawValue ?? GlucoseRangeScheduleOverrideUserInfo.clearOverride, + replyHandler: replyHandler, errorHandler: errorHandler ) } diff --git a/WatchApp Extension/Info.plist b/WatchApp Extension/Info.plist index 524b525ef6..2d920e1e05 100644 --- a/WatchApp Extension/Info.plist +++ b/WatchApp Extension/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 1.5.3 + 1.5.4 CFBundleSignature ???? CFBundleVersion @@ -39,7 +39,7 @@ NSExtensionAttributes WKAppBundleIdentifier - $(MAIN_APP_BUNDLE_IDENTIFIER).watchkitapp + $(MAIN_APP_BUNDLE_IDENTIFIER).LoopWatch NSExtensionPointIdentifier com.apple.watchkit diff --git a/WatchApp Extension/WatchApp Extension.entitlements b/WatchApp Extension/WatchApp Extension.entitlements index 0c67376eba..e10f4302d5 100644 --- a/WatchApp Extension/WatchApp Extension.entitlements +++ b/WatchApp Extension/WatchApp Extension.entitlements @@ -1,5 +1,8 @@ - + + com.apple.developer.healthkit + + diff --git a/WatchApp/Assets.xcassets/bolus.imageset/Bolus Icon 42mm.png b/WatchApp/Assets.xcassets/bolus.imageset/Bolus Icon 42mm.png new file mode 100644 index 0000000000..5228f51731 Binary files /dev/null and b/WatchApp/Assets.xcassets/bolus.imageset/Bolus Icon 42mm.png differ diff --git a/WatchApp/Assets.xcassets/bolus.imageset/Bolus icon 38mm.png b/WatchApp/Assets.xcassets/bolus.imageset/Bolus icon 38mm.png new file mode 100644 index 0000000000..e15e0b86ac Binary files /dev/null and b/WatchApp/Assets.xcassets/bolus.imageset/Bolus icon 38mm.png differ diff --git a/WatchApp/Assets.xcassets/bolus.imageset/Contents.json b/WatchApp/Assets.xcassets/bolus.imageset/Contents.json index de9ac511db..2dbb853d5c 100644 --- a/WatchApp/Assets.xcassets/bolus.imageset/Contents.json +++ b/WatchApp/Assets.xcassets/bolus.imageset/Contents.json @@ -2,17 +2,13 @@ "images" : [ { "idiom" : "watch", - "scale" : "2x" - }, - { - "idiom" : "watch", - "filename" : "bolus_38mm.png", + "filename" : "Bolus icon 38mm.png", "screen-width" : "<=145", "scale" : "2x" }, { "idiom" : "watch", - "filename" : "bolus_42mm.png", + "filename" : "Bolus Icon 42mm.png", "screen-width" : ">145", "scale" : "2x" } diff --git a/WatchApp/Assets.xcassets/bolus.imageset/bolus_38mm.png b/WatchApp/Assets.xcassets/bolus.imageset/bolus_38mm.png deleted file mode 100644 index 39084fb101..0000000000 Binary files a/WatchApp/Assets.xcassets/bolus.imageset/bolus_38mm.png and /dev/null differ diff --git a/WatchApp/Assets.xcassets/bolus.imageset/bolus_42mm.png b/WatchApp/Assets.xcassets/bolus.imageset/bolus_42mm.png deleted file mode 100644 index 9593428950..0000000000 Binary files a/WatchApp/Assets.xcassets/bolus.imageset/bolus_42mm.png and /dev/null differ diff --git a/WatchApp/Assets.xcassets/carbs.imageset/Carbs Icon 42mm.png b/WatchApp/Assets.xcassets/carbs.imageset/Carbs Icon 42mm.png new file mode 100644 index 0000000000..f825624552 Binary files /dev/null and b/WatchApp/Assets.xcassets/carbs.imageset/Carbs Icon 42mm.png differ diff --git a/WatchApp/Assets.xcassets/carbs.imageset/Carbs icon 38mm.png b/WatchApp/Assets.xcassets/carbs.imageset/Carbs icon 38mm.png new file mode 100644 index 0000000000..252bce9b81 Binary files /dev/null and b/WatchApp/Assets.xcassets/carbs.imageset/Carbs icon 38mm.png differ diff --git a/WatchApp/Assets.xcassets/fork.imageset/Contents.json b/WatchApp/Assets.xcassets/carbs.imageset/Contents.json similarity index 72% rename from WatchApp/Assets.xcassets/fork.imageset/Contents.json rename to WatchApp/Assets.xcassets/carbs.imageset/Contents.json index 6888857814..ecb8ce2515 100644 --- a/WatchApp/Assets.xcassets/fork.imageset/Contents.json +++ b/WatchApp/Assets.xcassets/carbs.imageset/Contents.json @@ -2,17 +2,13 @@ "images" : [ { "idiom" : "watch", - "scale" : "2x" - }, - { - "idiom" : "watch", - "filename" : "fork_38.png", + "filename" : "Carbs icon 38mm.png", "screen-width" : "<=145", "scale" : "2x" }, { "idiom" : "watch", - "filename" : "fork_42.png", + "filename" : "Carbs Icon 42mm.png", "screen-width" : ">145", "scale" : "2x" } diff --git a/WatchApp/Assets.xcassets/fork.imageset/fork_38.png b/WatchApp/Assets.xcassets/fork.imageset/fork_38.png deleted file mode 100644 index 8326635151..0000000000 Binary files a/WatchApp/Assets.xcassets/fork.imageset/fork_38.png and /dev/null differ diff --git a/WatchApp/Assets.xcassets/fork.imageset/fork_42.png b/WatchApp/Assets.xcassets/fork.imageset/fork_42.png deleted file mode 100644 index 2dd03dde86..0000000000 Binary files a/WatchApp/Assets.xcassets/fork.imageset/fork_42.png and /dev/null differ diff --git a/WatchApp/Assets.xcassets/pre-meal.imageset/Contents.json b/WatchApp/Assets.xcassets/pre-meal.imageset/Contents.json new file mode 100644 index 0000000000..c8be362ad1 --- /dev/null +++ b/WatchApp/Assets.xcassets/pre-meal.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "watch", + "filename" : "Pre-Meal 38mm.png", + "screen-width" : "<=145", + "scale" : "2x" + }, + { + "idiom" : "watch", + "filename" : "Pre-Meal 42mm.png", + "screen-width" : ">145", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/WatchApp/Assets.xcassets/pre-meal.imageset/Pre-Meal 38mm.png b/WatchApp/Assets.xcassets/pre-meal.imageset/Pre-Meal 38mm.png new file mode 100644 index 0000000000..5da34d393b Binary files /dev/null and b/WatchApp/Assets.xcassets/pre-meal.imageset/Pre-Meal 38mm.png differ diff --git a/WatchApp/Assets.xcassets/pre-meal.imageset/Pre-Meal 42mm.png b/WatchApp/Assets.xcassets/pre-meal.imageset/Pre-Meal 42mm.png new file mode 100644 index 0000000000..f363b068f9 Binary files /dev/null and b/WatchApp/Assets.xcassets/pre-meal.imageset/Pre-Meal 42mm.png differ diff --git a/WatchApp/Assets.xcassets/workout.imageset/Contents.json b/WatchApp/Assets.xcassets/workout.imageset/Contents.json new file mode 100644 index 0000000000..d5d7862146 --- /dev/null +++ b/WatchApp/Assets.xcassets/workout.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "watch", + "filename" : "Workout 38mm.png", + "screen-width" : "<=145", + "scale" : "2x" + }, + { + "idiom" : "watch", + "filename" : "Workout 42mm.png", + "screen-width" : ">145", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/WatchApp/Assets.xcassets/workout.imageset/Workout 38mm.png b/WatchApp/Assets.xcassets/workout.imageset/Workout 38mm.png new file mode 100644 index 0000000000..d4432f3002 Binary files /dev/null and b/WatchApp/Assets.xcassets/workout.imageset/Workout 38mm.png differ diff --git a/WatchApp/Assets.xcassets/workout.imageset/Workout 42mm.png b/WatchApp/Assets.xcassets/workout.imageset/Workout 42mm.png new file mode 100644 index 0000000000..d43a70eea7 Binary files /dev/null and b/WatchApp/Assets.xcassets/workout.imageset/Workout 42mm.png differ diff --git a/WatchApp/Base.lproj/Interface.storyboard b/WatchApp/Base.lproj/Interface.storyboard index e8002aa8cf..f2b392d588 100644 --- a/WatchApp/Base.lproj/Interface.storyboard +++ b/WatchApp/Base.lproj/Interface.storyboard @@ -1,12 +1,12 @@ - - + + - - + + @@ -122,7 +122,7 @@ - + @@ -156,6 +156,9 @@ + + + @@ -163,7 +166,7 @@ + + + + + + + + + + + + + + + + + diff --git a/WatchApp/Info.plist b/WatchApp/Info.plist index 7a657af42e..1f9804bde7 100644 --- a/WatchApp/Info.plist +++ b/WatchApp/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.5.3 + 1.5.4 CFBundleSignature ???? CFBundleVersion