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:
Johan Degraeve 2019-05-28 23:41:21 +02:00
parent d71b386e7f
commit 10d916c384
13 changed files with 201 additions and 68 deletions

View File

@ -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;

View File

@ -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
}
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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
}
}

View File

@ -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";

View File

@ -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>

View File

@ -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 = {

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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
}
}

View File

@ -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)