attempt to fix G5 : start scanning during init of cgmtransmitter, and transmitter id to uppercase - also initial code for follower mode
This commit is contained in:
parent
d71b386e7f
commit
10d916c384
|
@ -41,6 +41,7 @@
|
|||
F821CF5E229BF43A005C1E43 /* BgReading+NightScout.swift in Sources */ = {isa = PBXBuildFile; fileRef = F821CF53229BF43A005C1E43 /* BgReading+NightScout.swift */; };
|
||||
F821CF5F229BF43A005C1E43 /* ApplicationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F821CF55229BF43A005C1E43 /* ApplicationManager.swift */; };
|
||||
F821CF61229BF4A2005C1E43 /* NightScoutManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F821CF60229BF4A2005C1E43 /* NightScoutManager.swift */; };
|
||||
F821CF64229C6962005C1E43 /* FollowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F821CF63229C6962005C1E43 /* FollowManager.swift */; };
|
||||
F85DC2ED21CFE2F500B9F74A /* BgReading+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F85DC2E721CFE2F500B9F74A /* BgReading+CoreDataProperties.swift */; };
|
||||
F85DC2EF21CFE2F500B9F74A /* Sensor+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F85DC2E921CFE2F500B9F74A /* Sensor+CoreDataProperties.swift */; };
|
||||
F85DC2F321CFE3D400B9F74A /* Calibration+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F85DC2F021CFE3D400B9F74A /* Calibration+CoreDataClass.swift */; };
|
||||
|
@ -181,6 +182,7 @@
|
|||
F821CF53229BF43A005C1E43 /* BgReading+NightScout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BgReading+NightScout.swift"; sourceTree = "<group>"; };
|
||||
F821CF55229BF43A005C1E43 /* ApplicationManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationManager.swift; sourceTree = "<group>"; };
|
||||
F821CF60229BF4A2005C1E43 /* NightScoutManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NightScoutManager.swift; sourceTree = "<group>"; };
|
||||
F821CF63229C6962005C1E43 /* FollowManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowManager.swift; sourceTree = "<group>"; };
|
||||
F85DC2E721CFE2F500B9F74A /* BgReading+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "BgReading+CoreDataProperties.swift"; path = "../Extensions/BgReading+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||
F85DC2E921CFE2F500B9F74A /* Sensor+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Sensor+CoreDataProperties.swift"; path = "../Extensions/Sensor+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||
F85DC2F021CFE3D400B9F74A /* Calibration+CoreDataClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Calibration+CoreDataClass.swift"; sourceTree = "<group>"; };
|
||||
|
@ -451,6 +453,14 @@
|
|||
path = Application;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F821CF62229C6947005C1E43 /* Follower */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F821CF63229C6962005C1E43 /* FollowManager.swift */,
|
||||
);
|
||||
path = Follower;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F85DC29B21CFCEB800B9F74A /* Recovered References */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -461,6 +471,7 @@
|
|||
F85DC2F621D25E3A00B9F74A /* Managers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F821CF62229C6947005C1E43 /* Follower */,
|
||||
F821CF48229BF43A005C1E43 /* Alerts */,
|
||||
F821CF54229BF43A005C1E43 /* Application */,
|
||||
F821CF4D229BF43A005C1E43 /* CoreData */,
|
||||
|
@ -1070,6 +1081,7 @@
|
|||
F897AB1F22059EA000CDDD10 /* AuthRequestRxMessage.swift in Sources */,
|
||||
F897AB2A220742E900CDDD10 /* AESCrypt.m in Sources */,
|
||||
F8BDD4242218790E006EAB84 /* UserDefaults.swift in Sources */,
|
||||
F821CF64229C6962005C1E43 /* FollowManager.swift in Sources */,
|
||||
F8B3A7DF226E48C1004BA588 /* SoundPlayer.swift in Sources */,
|
||||
F8B3A820227DEC92004BA588 /* AlertTypesAccessor.swift in Sources */,
|
||||
F8B3A81E227DEC92004BA588 /* BgReadingsAccessor.swift in Sources */,
|
||||
|
@ -1308,7 +1320,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.johandegraeve.iosxdripreader;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.johandegraeve.beatit;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "xdrip/Transmitter/CGMBluetoothTransmitter/G5/G5Messages/xdrip-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
|
@ -1331,7 +1343,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.johandegraeve.iosxdripreader;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = net.johandegraeve.beatit;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "xdrip/Transmitter/CGMBluetoothTransmitter/G5/G5Messages/xdrip-Bridging-Header.h";
|
||||
SWIFT_VERSION = 4.2;
|
||||
|
|
|
@ -217,4 +217,11 @@ struct Constants {
|
|||
/// application name, appears in licenseInfo as title
|
||||
static let applicationName = "xDrip"
|
||||
}
|
||||
|
||||
// constants for follower mode
|
||||
enum Follower {
|
||||
|
||||
/// maximum days of readings to download
|
||||
static let maxiumDaysOfReadingsToDownlod = 1
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,12 +13,18 @@ extension UserDefaults {
|
|||
case lowMarkValue = "lowMarkValue"
|
||||
/// high value
|
||||
case highMarkValue = "highMarkValue"
|
||||
/// master or follower
|
||||
case isMaster = "isMaster"
|
||||
|
||||
// Transmitter
|
||||
|
||||
/// transmitter type
|
||||
case transmitterTypeAsString = "transmitterTypeAsString"
|
||||
/// transmitterid
|
||||
case transmitterId = "transmitterId"
|
||||
/// should readings be stored in healthkit, true or false
|
||||
case storeReadingsInHealthkit = "storeReadingsInHealthkit"
|
||||
|
||||
// Nightscout
|
||||
|
||||
/// should readings be uploaded to nightscout
|
||||
case uploadReadingsToNightScout = "uploadReadingsToNightScout"
|
||||
/// nightscout url
|
||||
|
@ -26,6 +32,9 @@ extension UserDefaults {
|
|||
/// nightscout api key
|
||||
case nightScoutAPIKey = "nightScoutAPIKey"
|
||||
/// should readings be uploaded to Dexcom share
|
||||
|
||||
// Dexcom Share
|
||||
|
||||
case uploadReadingstoDexcomShare = "uploadReadingstoDexcomShare"
|
||||
/// dexcom share account name
|
||||
case dexcomShareAccountName = "dexcomShareAccountName"
|
||||
|
@ -35,6 +44,14 @@ extension UserDefaults {
|
|||
case useUSDexcomShareurl = "useUSDexcomShareurl"
|
||||
/// dexcom share serial number
|
||||
case dexcomShareSerialNumber = "dexcomShareSerialNumber"
|
||||
|
||||
// Healthkit
|
||||
|
||||
/// should readings be stored in healthkit, true or false
|
||||
case storeReadingsInHealthkit = "storeReadingsInHealthkit"
|
||||
|
||||
// Speak readings
|
||||
|
||||
/// speak readings
|
||||
case speakReadings = "speakReadings"
|
||||
/// speak delta
|
||||
|
@ -127,6 +144,17 @@ extension UserDefaults {
|
|||
}
|
||||
}
|
||||
|
||||
/// true if device is master, false if follower
|
||||
@objc dynamic var isMaster: Bool {
|
||||
// default value for bool in userdefaults is false, false is for master, true is for follower
|
||||
get {
|
||||
return !bool(forKey: Key.isMaster.rawValue)
|
||||
}
|
||||
set {
|
||||
set(!newValue, forKey: Key.isMaster.rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
/// the highmarkvalue in unit selected by user ie, mgdl or mmol - rounded
|
||||
@objc dynamic var highMarkValueInUserChosenUnitRounded:String {
|
||||
get {
|
||||
|
|
|
@ -14,6 +14,8 @@ class ApplicationManager {
|
|||
/// list of closures to run when app will terminate
|
||||
private var closuresToRunWhenAppWillTerminate = [String : (() -> ())]()
|
||||
|
||||
// MARK: - public properties
|
||||
|
||||
/// access to shared instance of ApplicationManager
|
||||
static let shared = ApplicationManager()
|
||||
|
||||
|
@ -26,22 +28,6 @@ class ApplicationManager {
|
|||
setupNotificationHandling()
|
||||
}
|
||||
|
||||
private func setupNotificationHandling() {
|
||||
|
||||
/// define notification center
|
||||
let notificationCenter = NotificationCenter.default
|
||||
|
||||
/// add observer for did enter background
|
||||
notificationCenter.addObserver(self, selector: #selector(runWhenAppDidEnterBackground(_:)), name: UIApplication.didEnterBackgroundNotification, object: nil)
|
||||
|
||||
/// add observer for will enter foreground
|
||||
notificationCenter.addObserver(self, selector: #selector(runWhenAppWillEnterForeground(_:)), name: UIApplication.willEnterForegroundNotification, object: nil)
|
||||
|
||||
/// add observer for will terminate
|
||||
notificationCenter.addObserver(self, selector: #selector(runWhenAppWillTerminate(_:)), name: UIApplication.willTerminateNotification, object: nil)
|
||||
|
||||
}
|
||||
|
||||
// MARK: - public functions
|
||||
|
||||
/// adds closure to run identified by key, when app moved to background
|
||||
|
@ -67,6 +53,22 @@ class ApplicationManager {
|
|||
|
||||
// MARK: - private helper functions
|
||||
|
||||
private func setupNotificationHandling() {
|
||||
|
||||
/// define notification center
|
||||
let notificationCenter = NotificationCenter.default
|
||||
|
||||
/// add observer for did enter background
|
||||
notificationCenter.addObserver(self, selector: #selector(runWhenAppDidEnterBackground(_:)), name: UIApplication.didEnterBackgroundNotification, object: nil)
|
||||
|
||||
/// add observer for will enter foreground
|
||||
notificationCenter.addObserver(self, selector: #selector(runWhenAppWillEnterForeground(_:)), name: UIApplication.willEnterForegroundNotification, object: nil)
|
||||
|
||||
/// add observer for will terminate
|
||||
notificationCenter.addObserver(self, selector: #selector(runWhenAppWillTerminate(_:)), name: UIApplication.willTerminateNotification, object: nil)
|
||||
|
||||
}
|
||||
|
||||
@objc private func runWhenAppDidEnterBackground(_ : Notification) {
|
||||
// run the closures
|
||||
for closure in closuresToRunWhenAppDidEnterBackground {
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
import Foundation
|
||||
|
||||
/// instance of this class will do the follower functionality. Just make an instance, it will listen to the settings, do the regular download if needed - it could be deallocated when isMaster setting in Userdefaults changes, but that's not necessary to do
|
||||
class FollowManager {
|
||||
|
||||
// MARK: - public properties
|
||||
|
||||
// MARK: - private properties
|
||||
|
||||
// when to do next download
|
||||
private var nextFollowDownloadTimeStamp:Date
|
||||
|
||||
// reference to coredatamanager
|
||||
private var coreDataManager:CoreDataManager
|
||||
|
||||
// reference to BgReadingsAccessor
|
||||
private var bgReadingsAccessor:BgReadingsAccessor
|
||||
|
||||
// MARK: - initializer
|
||||
|
||||
/// init is private, to avoid creation
|
||||
private init(coreDataManager:CoreDataManager) {
|
||||
|
||||
// initialize nextFollowDownloadTimeStamp to now, which is at moment FollowManager is instantiated
|
||||
nextFollowDownloadTimeStamp = Date()
|
||||
|
||||
// initial non optional private properties
|
||||
self.coreDataManager = coreDataManager
|
||||
self.bgReadingsAccessor = BgReadingsAccessor(coreDataManager: coreDataManager)
|
||||
}
|
||||
|
||||
// MARK: - private functions
|
||||
|
||||
private func download() {
|
||||
|
||||
// maximum timeStamp to download initially set to 1 day back
|
||||
var timeStampOfFirstBgReadingToDowload = Date(timeIntervalSinceNow: TimeInterval(-Constants.Follower.maxiumDaysOfReadingsToDownlod * 24 * 3600))
|
||||
|
||||
// check timestamp of lastest stored bgreading with calculated value, if more recent then use this as timestamp
|
||||
let latestBgReadings = bgReadingsAccessor.getLatestBgReadings(limit: nil, howOld: 1, forSensor: nil, ignoreRawData: true, ignoreCalculatedValue: false)
|
||||
if latestBgReadings.count > 0 {
|
||||
timeStampOfFirstBgReadingToDowload = max(latestBgReadings[0].timeStamp, timeStampOfFirstBgReadingToDowload)
|
||||
}
|
||||
|
||||
// calculate count, which is a parameter in the nightscout api - divide by 60, worst case NightScout has a reading every minute, this can be the case for MiaoMiao
|
||||
let count = -timeStampOfFirstBgReadingToDowload.timeIntervalSinceNow / 60 + 1
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -30,3 +30,7 @@
|
|||
"settingsviews_speakTrend" = "Speak Trend";
|
||||
"settingsviews_speakDelta" = "Speak Delta";
|
||||
"settingsviews_speakInterval" = "Interval";
|
||||
"settingsviews_masterorfollower" = "Master or Follower ?";
|
||||
"settingsviews_master" = "Master";
|
||||
"settingsviews_follower" = "Follower";
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>xDrip</string>
|
||||
<string>BeatIt</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
|
@ -17,9 +17,9 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.0.1</string>
|
||||
<string>2.0.4</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>2.0.1</string>
|
||||
<string>2.0.4</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSBluetoothPeripheralUsageDescription</key>
|
||||
|
|
|
@ -28,6 +28,18 @@ class Texts_SettingsView {
|
|||
return NSLocalizedString("settingsviews_highValue", tableName: filename, bundle: Bundle.main, value: "High Value", comment: "general settings, high value")
|
||||
}()
|
||||
|
||||
static let labelMasterOrFollower: String = {
|
||||
return NSLocalizedString("settingsviews_masterorfollower", tableName: filename, bundle: Bundle.main, value: "Master or Follower ?", comment: "general settings, master or follower")
|
||||
}()
|
||||
|
||||
static let master: String = {
|
||||
return NSLocalizedString("settingsviews_master", tableName: filename, bundle: Bundle.main, value: "Master", comment: "general settings, literally master")
|
||||
}()
|
||||
|
||||
static let follower: String = {
|
||||
return NSLocalizedString("settingsviews_follower", tableName: filename, bundle: Bundle.main, value: "Follower", comment: "general settings, literally follower")
|
||||
}()
|
||||
|
||||
// MARK: - Section Transmitter
|
||||
|
||||
static let sectionTitleTransmitter: String = {
|
||||
|
|
|
@ -115,6 +115,8 @@ class CGMG5Transmitter:BluetoothTransmitter, BluetoothTransmitterDelegate, CGMTr
|
|||
// set self as delegate for BluetoothTransmitterDelegate - this parameter is defined in the parent class BluetoothTransmitter
|
||||
bluetoothTransmitterDelegate = self
|
||||
|
||||
// start scanning
|
||||
_ = startScanning()
|
||||
}
|
||||
|
||||
// MARK: public functions
|
||||
|
@ -265,10 +267,12 @@ class CGMG5Transmitter:BluetoothTransmitter, BluetoothTransmitterDelegate, CGMTr
|
|||
}
|
||||
case .authRequestRx:
|
||||
if let authRequestRxMessage = AuthRequestRxMessage(data: value), let receiveAuthenticationCharacteristic = receiveAuthenticationCharacteristic {
|
||||
debuglogging("transmitterid = " + transmitterId)
|
||||
guard let challengeHash = CGMG5Transmitter.computeHash(transmitterId, of: authRequestRxMessage.challenge) else {
|
||||
os_log(" failed to calculate challengeHash, no further processing", log: log, type: .error)
|
||||
return
|
||||
}
|
||||
debuglogging("challengehash = " + challengeHash.hexEncodedString())
|
||||
let authChallengeTxMessage = AuthChallengeTxMessage(challengeHash: challengeHash)
|
||||
_ = writeDataToPeripheral(data: authChallengeTxMessage.data, characteristicToWriteTo: receiveAuthenticationCharacteristic, type: .withResponse)
|
||||
} else {
|
||||
|
|
|
@ -243,17 +243,24 @@ class BluetoothTransmitter: NSObject, CBCentralManagerDelegate, CBPeripheralDele
|
|||
/// the result of the attempt to try to find such device, is returned
|
||||
fileprivate func retrievePeripherals(_ central:CBCentralManager) -> Bool {
|
||||
if let deviceAddress = deviceAddress {
|
||||
debuglogging("in retrievePeripherals, deviceaddress is not nil")
|
||||
if let uuid = UUID(uuidString: deviceAddress) {
|
||||
debuglogging(" in retrievePeripherals, uuid is not nil")
|
||||
var peripheralArr = central.retrievePeripherals(withIdentifiers: [uuid])
|
||||
if peripheralArr.count > 0 {
|
||||
peripheral = peripheralArr[0]
|
||||
if let peripheral = peripheral {
|
||||
debuglogging(" in retrievePeripherals, peripheral is not nil")
|
||||
os_log("in retrievePeripherals, trying to connect", log: log, type: .info)
|
||||
peripheral.delegate = self
|
||||
central.connect(peripheral, options: nil)
|
||||
return true
|
||||
} else {
|
||||
debuglogging(" in retrievePeripherals, peripheral isfstart nil")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
debuglogging(" in retrievePeripherals, uuid is nil")
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
|
|
@ -118,6 +118,9 @@ final class RootViewController: UIViewController {
|
|||
// when user changes transmitter type or transmitter id, then new transmitter needs to be setup. That's why observer for these settings is required
|
||||
UserDefaults.standard.addObserver(self, forKeyPath: UserDefaults.Key.transmitterTypeAsString.rawValue, options: .new, context: nil)
|
||||
UserDefaults.standard.addObserver(self, forKeyPath: UserDefaults.Key.transmitterId.rawValue, options: .new, context: nil)
|
||||
// changing from follower to master or vice versa also requires transmitter setup
|
||||
UserDefaults.standard.addObserver(self, forKeyPath: UserDefaults.Key.isMaster.rawValue, options: .new
|
||||
, context: nil)
|
||||
|
||||
// create transmitter based on UserDefaults
|
||||
initializeCGMTransmitter()
|
||||
|
@ -296,17 +299,16 @@ final class RootViewController: UIViewController {
|
|||
|
||||
switch keyPathEnum {
|
||||
|
||||
case UserDefaults.Key.transmitterTypeAsString, UserDefaults.Key.transmitterId :
|
||||
// for these three settings, a forgetdevice can be done and reinitialize cgmTransmitter. In case of switching from master to follower, initializeCGMTransmitter will not initialize a cgmTransmitter, so it's ok to call that function
|
||||
case UserDefaults.Key.transmitterTypeAsString, UserDefaults.Key.transmitterId, UserDefaults.Key.isMaster :
|
||||
|
||||
// transmittertype change triggered by user, should not be done within 200 ms
|
||||
if (keyValueObserverTimeKeeper.verifyKey(forKey: keyPathEnum.rawValue, withMinimumDelayMilliSeconds: 200)) {
|
||||
UserDefaults.standard.bluetoothDeviceAddress = nil
|
||||
UserDefaults.standard.bluetoothDeviceName = nil
|
||||
|
||||
// there's no need to stop the sensor, maybe the user is just switching from xdrip a to xdrip b
|
||||
|
||||
// setting cgmTransmitter to nil, if currently cgmTransmitter is not nil, by assign to nil the deinit function of the currently used cgmTransmitter will be called, which will deconnect the device
|
||||
setCGMTransmitterToNil()
|
||||
// there's no need to stop the sensor here, maybe the user is just switching from xdrip a to xdrip b
|
||||
|
||||
// forget current device
|
||||
forgetDevice()
|
||||
|
||||
// set up na transmitter
|
||||
initializeCGMTransmitter()
|
||||
|
@ -366,26 +368,6 @@ final class RootViewController: UIViewController {
|
|||
ApplicationManager.shared.addClosureToRunWhenAppDidEnterBackground(key: applicationManagerKeyInvalidateUpdateLabelsTimer, closure: {invalidateUpdateLabelsTimer()})
|
||||
}
|
||||
|
||||
/// sets parameter cgmTransmitter to nil and also other settings
|
||||
///
|
||||
/// - cgmTransmitter to nil
|
||||
/// - UserDefaults.standard.transmitterBatteryInfo to nil
|
||||
/// - UserDefaults.standard.lastdisConnectTimestamp to nil
|
||||
/// - stops the active sensor
|
||||
private func setCGMTransmitterToNil() {
|
||||
|
||||
cgmTransmitter = nil // here don't use setCGMTransmitterToNil(), because it's not the goal tha transmitterBatteryInfo is set to nil at each app startup
|
||||
|
||||
// reset also UserDefaults.standard.transmitterBatteryInfo
|
||||
UserDefaults.standard.transmitterBatteryInfo = nil
|
||||
|
||||
// set lastdisconnecttimestamp to nil
|
||||
UserDefaults.standard.lastdisConnectTimestamp = nil
|
||||
|
||||
// stop active sensor
|
||||
stopSensor()
|
||||
}
|
||||
|
||||
/// opens an alert, that requests user to enter a calibration value, and calibrates
|
||||
/// - parameters:
|
||||
/// - userRequested : if true, it's a requestCalibration initiated by user clicking on the calibrate button in the homescreen
|
||||
|
@ -466,14 +448,17 @@ final class RootViewController: UIViewController {
|
|||
}
|
||||
|
||||
|
||||
/// will set first cgmTransmitter to nil, reads transmittertype from userdefaults, and if available creates the transmitter and start the scanning
|
||||
/// will set first cgmTransmitter to nil, reads transmittertype from userdefaults, if applicable also transmitterid and if available creates the property cgmTransmitter - if follower mode then cgmTransmitter is set to nil
|
||||
///
|
||||
/// depending on transmitter type, scanning will automatically start as soon as cgmTransmitter is created
|
||||
private func initializeCGMTransmitter() {
|
||||
|
||||
// setting cgmTransmitter to nil, if currently cgmTransmitter is not nil, by assign to nil the deinit function of the currently used cgmTransmitter will be called, which will deconnect the device
|
||||
// setting to nil is also done in other places, doing it again just to be 100% sure
|
||||
cgmTransmitter = nil
|
||||
|
||||
if let currentTransmitterTypeAsEnum = UserDefaults.standard.transmitterType {
|
||||
// if transmitter type is set and device is master
|
||||
if let currentTransmitterTypeAsEnum = UserDefaults.standard.transmitterType, UserDefaults.standard.isMaster {
|
||||
|
||||
// first create transmitter
|
||||
switch currentTransmitterTypeAsEnum {
|
||||
|
@ -658,7 +643,7 @@ final class RootViewController: UIViewController {
|
|||
|
||||
/// when user clicks transmitter button, this will create and present the actionsheet, contents depend on type of transmitter and sensor status
|
||||
private func createAndPresentTransmitterButtonActionSheet() {
|
||||
// intialize list of actions
|
||||
// initialize list of actions
|
||||
var listOfActions = [String : ((UIAlertAction) -> Void)]()
|
||||
|
||||
// first action is to show the status
|
||||
|
@ -675,7 +660,7 @@ final class RootViewController: UIViewController {
|
|||
if UserDefaults.standard.bluetoothDeviceAddress == nil {
|
||||
listOfActions[Texts_HomeView.scanBluetoothDeviceActionTitle] = {(UIAlertAction) in self.userInitiatesStartScanning()}
|
||||
} else {
|
||||
listOfActions[Texts_HomeView.forgetBluetoothDeviceActionTitle] = {(UIAlertAction) in self.userInitiatesForgetDevice()}
|
||||
listOfActions[Texts_HomeView.forgetBluetoothDeviceActionTitle] = {(UIAlertAction) in self.forgetDevice()}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -778,19 +763,32 @@ final class RootViewController: UIViewController {
|
|||
}
|
||||
}
|
||||
|
||||
/// user clicked forget device action, this function will forget the device
|
||||
private func userInitiatesForgetDevice() {
|
||||
/// - cgmTransmitter to nil, this disconnects also the existing transmitter
|
||||
/// - UserDefaults.standard.transmitterBatteryInfo to nil
|
||||
/// - UserDefaults.standard.lastdisConnectTimestamp to nil
|
||||
/// - UserDefaults.standard.bluetoothDeviceAddress to nil
|
||||
/// - UserDefaults.standard.bluetoothDeviceName to nil
|
||||
/// -
|
||||
/// - calls also initializeCGMTransmitter which recreated the cgmTransmitter property, depending on settings
|
||||
private func forgetDevice() {
|
||||
|
||||
// set device address and name to nil in userdefaults
|
||||
UserDefaults.standard.bluetoothDeviceAddress = nil
|
||||
UserDefaults.standard.bluetoothDeviceName = nil
|
||||
|
||||
// setting cgmTransmitter to nil, the deinit function of the currently used cgmTransmitter will be called, which will disconnect the device
|
||||
setCGMTransmitterToNil()
|
||||
// set cgmTransmitter to nil, this will call the deinit function which will disconnect first
|
||||
cgmTransmitter = nil
|
||||
|
||||
// by calling initializeCGMTransmitter, a new cgmTransmitter will be created - as it should be a device which does not automatically start scanning (otherwise we wouldn't be here). It will just create the transmitter but it will not scan, this needs to be initiated by the user
|
||||
// by calling initializeCGMTransmitter, a new cgmTransmitter will be created, assuming it's not follower mode, and transmittertype is selected and if applicable transmitter id is set
|
||||
initializeCGMTransmitter()
|
||||
|
||||
// reset also UserDefaults.standard.transmitterBatteryInfo
|
||||
UserDefaults.standard.transmitterBatteryInfo = nil
|
||||
|
||||
// set lastdisconnecttimestamp to nil
|
||||
UserDefaults.standard.lastdisConnectTimestamp = nil
|
||||
|
||||
}
|
||||
|
||||
// stop the active sensor
|
||||
|
|
|
@ -7,7 +7,8 @@ fileprivate enum Setting:Int, CaseIterable {
|
|||
case lowMarkValue = 1
|
||||
//high value
|
||||
case highMarkValue = 2
|
||||
// transmitter type
|
||||
// choose between master and follower
|
||||
case masterfolllower = 3
|
||||
}
|
||||
|
||||
/// conforms to SettingsViewModelProtocol for all general settings in the first sections screen
|
||||
|
@ -23,6 +24,8 @@ struct SettingsViewGeneralSettingsViewModel:SettingsViewModelProtocol {
|
|||
|
||||
case .highMarkValue:
|
||||
return SettingsSelectedRowAction.askText(title: Texts_SettingsView.labelHighValue, message: nil, keyboardType: UserDefaults.standard.bloodGlucoseUnitIsMgDl ? .numberPad:.decimalPad, text: UserDefaults.standard.highMarkValueInUserChosenUnitRounded, placeHolder: Constants.BGGraphBuilder.defaultHighMmarkInMgdl.description, actionTitle: nil, cancelTitle: nil, actionHandler: {(highMarkValue:String) in UserDefaults.standard.highMarkValueInUserChosenUnitRounded = highMarkValue}, cancelHandler: nil)
|
||||
case .masterfolllower:
|
||||
return SettingsSelectedRowAction.callFunction(function: {UserDefaults.standard.isMaster ? (UserDefaults.standard.isMaster) = false : (UserDefaults.standard.isMaster = true)})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +34,7 @@ struct SettingsViewGeneralSettingsViewModel:SettingsViewModelProtocol {
|
|||
}
|
||||
|
||||
func numberOfRows() -> Int {
|
||||
return Setting.allCases.count
|
||||
return 3//Setting.allCases.count
|
||||
}
|
||||
|
||||
func settingsRowText(index: Int) -> String {
|
||||
|
@ -44,6 +47,8 @@ struct SettingsViewGeneralSettingsViewModel:SettingsViewModelProtocol {
|
|||
return Texts_SettingsView.labelLowValue
|
||||
case .highMarkValue:
|
||||
return Texts_SettingsView.labelHighValue
|
||||
case .masterfolllower:
|
||||
return Texts_SettingsView.labelMasterOrFollower
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,6 +62,8 @@ struct SettingsViewGeneralSettingsViewModel:SettingsViewModelProtocol {
|
|||
return UITableViewCell.AccessoryType.disclosureIndicator
|
||||
case .highMarkValue:
|
||||
return UITableViewCell.AccessoryType.disclosureIndicator
|
||||
case .masterfolllower:
|
||||
return UITableViewCell.AccessoryType.none
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,15 +72,13 @@ struct SettingsViewGeneralSettingsViewModel:SettingsViewModelProtocol {
|
|||
|
||||
switch setting {
|
||||
case .bloodGlucoseUnit:
|
||||
if UserDefaults.standard.bloodGlucoseUnitIsMgDl {
|
||||
return Texts_Common.mgdl
|
||||
} else {
|
||||
return Texts_Common.mmol
|
||||
}
|
||||
return UserDefaults.standard.bloodGlucoseUnitIsMgDl ? Texts_Common.mgdl:Texts_Common.mmol
|
||||
case .lowMarkValue:
|
||||
return UserDefaults.standard.lowMarkValueInUserChosenUnit.bgValuetoString(mgdl: UserDefaults.standard.bloodGlucoseUnitIsMgDl)
|
||||
case .highMarkValue:
|
||||
return UserDefaults.standard.highMarkValueInUserChosenUnit.bgValuetoString(mgdl: UserDefaults.standard.bloodGlucoseUnitIsMgDl)
|
||||
case .masterfolllower:
|
||||
return UserDefaults.standard.isMaster ? Texts_SettingsView.master:Texts_SettingsView.follower
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,12 +17,16 @@ struct SettingsViewTransmitterSettingsViewModel:SettingsViewModelProtocol {
|
|||
|
||||
case .transmitterId:
|
||||
return SettingsSelectedRowAction.askText(title: Texts_SettingsView.labelTransmitterId, message: Texts_SettingsView.labelGiveTransmitterId, keyboardType: UIKeyboardType.alphabet, text: UserDefaults.standard.transmitterId, placeHolder: "00000", actionTitle: nil, cancelTitle: nil, actionHandler: {(transmitterId:String) in
|
||||
// convert to uppercase
|
||||
let transmitterIdUpper = transmitterId.uppercased()
|
||||
|
||||
// if changed then store new value
|
||||
if let currentTransmitterId = UserDefaults.standard.transmitterId {
|
||||
if currentTransmitterId != transmitterId {
|
||||
UserDefaults.standard.transmitterId = transmitterId
|
||||
if currentTransmitterId != transmitterIdUpper {
|
||||
UserDefaults.standard.transmitterId = transmitterIdUpper
|
||||
}
|
||||
} else {
|
||||
UserDefaults.standard.transmitterId = transmitterId
|
||||
UserDefaults.standard.transmitterId = transmitterIdUpper
|
||||
}
|
||||
|
||||
}, cancelHandler: nil)
|
||||
|
|
Loading…
Reference in New Issue