when nightscout url or api secret are changed, then credentials test is done

This commit is contained in:
Johan Degraeve 2019-04-11 00:09:08 +02:00
parent 574a9aebbe
commit 579939302c
14 changed files with 166 additions and 15 deletions

View File

@ -66,6 +66,9 @@
F8AC426721ADEBD70078C348 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F8AC426621ADEBD70078C348 /* Assets.xcassets */; };
F8AC426A21ADEBD70078C348 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F8AC426821ADEBD70078C348 /* LaunchScreen.storyboard */; };
F8AC42A121B31F170078C348 /* xdrip.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = F8AC429F21B31F160078C348 /* xdrip.xcdatamodeld */; };
F8B3A783225D37F2004BA588 /* TextsNightScoutTestResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8B3A782225D37F2004BA588 /* TextsNightScoutTestResult.swift */; };
F8B3A786225D4473004BA588 /* NightScoutTestResult.strings in Resources */ = {isa = PBXBuildFile; fileRef = F8B3A788225D4473004BA588 /* NightScoutTestResult.strings */; };
F8B3A78B225D473D004BA588 /* UIAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8B3A78A225D473D004BA588 /* UIAlertController.swift */; };
F8BDD41722176B4A006EAB84 /* SettingsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8BDD41622176B4A006EAB84 /* SettingsTableViewCell.swift */; };
F8BDD41A2217FF42006EAB84 /* SettingsViewGeneralSettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8BDD4192217FF42006EAB84 /* SettingsViewGeneralSettingsViewModel.swift */; };
F8BDD41C2217FFB0006EAB84 /* SettingsViewTransmitterSettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8BDD41B2217FFB0006EAB84 /* SettingsViewTransmitterSettingsViewModel.swift */; };
@ -160,6 +163,10 @@
F8AC426921ADEBD70078C348 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
F8AC426B21ADEBD70078C348 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F8AC42A021B31F160078C348 /* xdrip.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = xdrip.xcdatamodel; sourceTree = "<group>"; };
F8B3A782225D37F2004BA588 /* TextsNightScoutTestResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextsNightScoutTestResult.swift; sourceTree = "<group>"; };
F8B3A787225D4473004BA588 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/NightScoutTestResult.strings; sourceTree = "<group>"; };
F8B3A789225D447A004BA588 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/NightScoutTestResult.strings; sourceTree = "<group>"; };
F8B3A78A225D473D004BA588 /* UIAlertController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIAlertController.swift; sourceTree = "<group>"; };
F8BDD41622176B4A006EAB84 /* SettingsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTableViewCell.swift; sourceTree = "<group>"; };
F8BDD4192217FF42006EAB84 /* SettingsViewGeneralSettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewGeneralSettingsViewModel.swift; sourceTree = "<group>"; };
F8BDD41B2217FFB0006EAB84 /* SettingsViewTransmitterSettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewTransmitterSettingsViewModel.swift; sourceTree = "<group>"; };
@ -246,6 +253,7 @@
F8E3C3AA21FE17B700907A04 /* StringProtocol.swift */,
F8025E6A21F7CD7600ECF0C0 /* UIStoryboard.swift */,
F8BDD4232218790E006EAB84 /* UserDefaults.swift */,
F8B3A78A225D473D004BA588 /* UIAlertController.swift */,
);
path = Extensions;
sourceTree = "<group>";
@ -341,6 +349,7 @@
F8BDD444221C9D0D006EAB84 /* Common.strings */,
F8BDD44A221C9D70006EAB84 /* ErrorMessages.strings */,
F8BDD457221DEF22006EAB84 /* SettingsViews.strings */,
F8B3A788225D4473004BA588 /* NightScoutTestResult.strings */,
);
path = Storyboards;
sourceTree = "<group>";
@ -531,6 +540,7 @@
F8BDD43E221B5BAF006EAB84 /* TextsErrorMessages.swift */,
F8BDD44F221CAA64006EAB84 /* TextsCommon.swift */,
F8BDD451221DEAB1006EAB84 /* TextsSettingsViews.swift */,
F8B3A782225D37F2004BA588 /* TextsNightScoutTestResult.swift */,
);
path = Texts;
sourceTree = "<group>";
@ -664,6 +674,7 @@
F8BDD442221C9D0D006EAB84 /* Common.strings in Resources */,
F8AC426A21ADEBD70078C348 /* LaunchScreen.storyboard in Resources */,
F8BDD438221A0349006EAB84 /* Localizable.strings in Resources */,
F8B3A786225D4473004BA588 /* NightScoutTestResult.strings in Resources */,
F8BDD448221C9D70006EAB84 /* ErrorMessages.strings in Resources */,
F8BDD455221DEF22006EAB84 /* SettingsViews.strings in Resources */,
F8AC426721ADEBD70078C348 /* Assets.xcassets in Resources */,
@ -772,6 +783,7 @@
F897AB1D22059EA000CDDD10 /* TransmitterMessage.swift in Sources */,
F8025E5721F4A60900ECF0C0 /* CGMTransmitter.swift in Sources */,
F897AB3D220A243300CDDD10 /* ResetMessage.swift in Sources */,
F8B3A783225D37F2004BA588 /* TextsNightScoutTestResult.swift in Sources */,
F85DC30121D3F5CC00B9F74A /* CGMG4xDripTransmitter.swift in Sources */,
F8025C0A21D94FD700ECF0C0 /* CBManagerState.swift in Sources */,
F897AB3B2208DCE100CDDD10 /* TransmitterBatteryInfo.swift in Sources */,
@ -783,6 +795,7 @@
F8025C0F21D95EC200ECF0C0 /* CGMTransmitterDelegate.swift in Sources */,
F8AC426021ADEBD60078C348 /* RootViewController.swift in Sources */,
F8BDD42022183CE9006EAB84 /* SettingsViewAlarmsSettingsViewModel.swift in Sources */,
F8B3A78B225D473D004BA588 /* UIAlertController.swift in Sources */,
F8BDD41722176B4A006EAB84 /* SettingsTableViewCell.swift in Sources */,
F897AB39220775B100CDDD10 /* BatteryStatusTxMessage.swift in Sources */,
F8025C1A21DBC1B700ECF0C0 /* SensorState.swift in Sources */,
@ -827,6 +840,15 @@
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
F8B3A788225D4473004BA588 /* NightScoutTestResult.strings */ = {
isa = PBXVariantGroup;
children = (
F8B3A787225D4473004BA588 /* en */,
F8B3A789225D447A004BA588 /* nl */,
);
name = NightScoutTestResult.strings;
sourceTree = "<group>";
};
F8BDD436221A0349006EAB84 /* Localizable.strings */ = {
isa = PBXVariantGroup;
children = (

View File

@ -0,0 +1,11 @@
import UIKit
extension UIAlertController {
func presentInOwnWindow(animated: Bool, completion: (() -> Void)?) {
let alertWindow = UIWindow(frame: UIScreen.main.bounds)
alertWindow.rootViewController = UIViewController()
alertWindow.windowLevel = UIWindow.Level.alert + 1;
alertWindow.makeKeyAndVisible()
alertWindow.rootViewController?.present(self, animated: animated, completion: completion)
}
}

View File

@ -1,7 +1,8 @@
import Foundation
import os
import UIKit
public class NightScoutUploader {
public class NightScoutUploader:NSObject {
// MARK: - properties
@ -23,10 +24,20 @@ public class NightScoutUploader {
/// BgReadings instance
private let bgReadings:BgReadings
// MARK: - initializer
init(bgReadings:BgReadings) {
self.bgReadings = bgReadings
super.init()
// add observers for nightscout settings which may require testing and/or start synchronize
UserDefaults.standard.addObserver(self, forKeyPath: UserDefaults.Key.nightScoutAPIKey.rawValue, options: .new, context: nil)
UserDefaults.standard.addObserver(self, forKeyPath: UserDefaults.Key.nightScoutUrl.rawValue, options: .new, context: nil)
}
// MARK: - public functions
/// synchronizes all NightScout related, if needed
public func synchronize() {
// check if NightScout upload is enabled
@ -35,6 +46,36 @@ public class NightScoutUploader {
}
}
// MARK: - overriden functions
// when one of the observed settings get changed, possible actions to take
override public func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if let keyPath = keyPath {
if let keyPathEnum = UserDefaults.Key(rawValue: keyPath) {
switch keyPathEnum {
case UserDefaults.Key.nightScoutUrl, UserDefaults.Key.nightScoutAPIKey :
if let apiKey = UserDefaults.standard.nightScoutAPIKey, let siteUrl = UserDefaults.standard.nightScoutUrl {
testNightScoutCredentials(apiKey: apiKey, siteURL: siteUrl, { (success, error) in
DispatchQueue.main.async {
self.presentNightScoutTestCredentialsResult(success: success, error: error)
if success {
self.synchronize()
} else {
os_log("in observeValue, NightScout credential check failed zzz", log: self.log, type: .info)
}
}
})
}
default:
break
}
}
}
}
// MARK: - private helper functions
private func uploadBgReadingsToNightScout(siteURL:String, apiKey:String) {
os_log("in uploadBgReadingsToNightScout", log: self.log, type: .info)
@ -117,4 +158,56 @@ public class NightScoutUploader {
}
}
private func testNightScoutCredentials(apiKey:String, siteURL:String, _ completion: @escaping (_ success: Bool, _ error: Error?) -> Void) {
if let url = URL(string: siteURL) {
let testURL = url.appendingPathComponent(nightScoutAuthTestPath)
var request = URLRequest(url: testURL)
request.setValue("application/json", forHTTPHeaderField:"Content-Type")
request.setValue("application/json", forHTTPHeaderField:"Accept")
request.setValue(apiKey.sha1(), forHTTPHeaderField:"api-secret")
let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
if let error = error {
completion(false, error)
return
}
if let httpResponse = response as? HTTPURLResponse ,
httpResponse.statusCode != 200, let data = data {
completion(false, NSError(domain: "", code: httpResponse.statusCode, userInfo: [NSLocalizedDescriptionKey: String(data: data, encoding: String.Encoding.utf8)!]))
} else {
completion(true, nil)
}
})
task.resume()
}
}
private func presentNightScoutTestCredentialsResult(success:Bool, error:Error?) {
// define the title text
var title = Texts_NightScoutTestResult.verificationSuccessFulAlertTitle
if !success {
title = Texts_NightScoutTestResult.verificationErrorAlertTitle
}
// define the message text
var message = Texts_NightScoutTestResult.verificationSuccessFulAlertBody
if !success {
if let error = error {
message = error.localizedDescription
} else {
message = "unknown error"// shouldn't happen
}
}
// define and present alertcontroller
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: Texts_Common.Ok, style: .default, handler: nil)
alertController.addAction(defaultAction)
alertController.presentInOwnWindow(animated: true, completion: {})
}
}

View File

@ -0,0 +1,3 @@
"nightscouttestresult_verificationsuccessfulalerttitle" = "Verification Successful";
"nightscouttestresult_verificationsuccessfulalertbody" = "Your Nightscout account was verified successfully";
"nightscouttestresult_verificationerroralerttitle" = "Verification Error";

View File

@ -0,0 +1,3 @@
"nightscouttestresult_verificationsuccessfulalerttitle" = "Verification Successful";
"nightscouttestresult_verificationsuccessfulalertbody" = "Your Nightscout account was verified successfully";
"nightscouttestresult_verificationerroralerttitle" = "Verification Error";

View File

@ -14,7 +14,6 @@ enum Texts_ErrorMessages {
static let TransmitterIDShouldHaveLength5:String = {
return NSLocalizedString("error_message_transmitter_id_should_have_length_5", tableName: errorMessagesFileName, bundle: Bundle.main, value: "Transmitter id should have length 5", comment: "error message for the case where Dexcom G5 transmitter id given by user doesn't have 5 characters")
}()
}

View File

@ -0,0 +1,18 @@
import Foundation
class Texts_NightScoutTestResult {
static private let filename = "NightScoutTestResult"
static let verificationSuccessFulAlertTitle: String = {
return NSLocalizedString("nightscouttestresult_verificationsuccessfulalerttitle", tableName: filename, bundle: Bundle.main, value: "Verification Successful", comment: "POP up after verifying nightscout credentials, to say that verification of url and api key were successful - this is the title")
}()
static let verificationSuccessFulAlertBody: String = {
return NSLocalizedString("nightscouttestresult_verificationsuccessfulalertbody", tableName: filename, bundle: Bundle.main, value: "Your nightscout account was verified successfully.", comment: "POP up after verifying nightscout credentials, to say that verification of url and api key were successful - this is the body")
}()
static let verificationErrorAlertTitle: String = {
return NSLocalizedString("nightscouttestresult_verificationerroralerttitle", tableName: filename, bundle: Bundle.main, value: "Verification Error", comment: "POP up after verifying nightscout credentials, to say that verification of url and api key was not successful - this is the title")
}()
}

View File

@ -222,12 +222,13 @@ extension SettingsViewController:UITableViewDataSource, UITableViewDelegate {
switch selectedRowAction {
case let .askText(title, message, keyboardType, placeHolder, actionTitle, cancelTitle, actionHandler, cancelHandler):
case let .askText(title, message, keyboardType, text, placeHolder, actionTitle, cancelTitle, actionHandler, cancelHandler):
//create uialertcontroller
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addTextField { (textField:UITextField) in
if let placeHolder = placeHolder { textField.placeholder = placeHolder }
textField.placeholder = placeHolder
textField.text = text
if let keyboardType = keyboardType { textField.keyboardType = keyboardType }
}
// add actions Ok and Cancel

View File

@ -24,15 +24,15 @@ class SettingsViewDexcomSettingsViewModel:SettingsViewModelProtocol {
case .dexcomShareAccountName:
var textAddon = ""
if let currentValue = UserDefaults.standard.dexcomShareAccountName {textAddon = "\n" + currentValue}
return SelectedRowAction.askText(title: Texts_SettingsViews.dexcomShareAccountName, message: Texts_SettingsViews.giveDexcomShareAccountName + textAddon, keyboardType: UIKeyboardType.alphabet, placeHolder: UserDefaults.standard.dexcomShareAccountName, actionTitle: nil, cancelTitle: nil, actionHandler: {(accountName:String) in UserDefaults.standard.dexcomShareAccountName = accountName}, cancelHandler: nil)
return SelectedRowAction.askText(title: Texts_SettingsViews.dexcomShareAccountName, message: Texts_SettingsViews.giveDexcomShareAccountName + textAddon, keyboardType: UIKeyboardType.alphabet, text: UserDefaults.standard.dexcomShareAccountName, placeHolder: nil, actionTitle: nil, cancelTitle: nil, actionHandler: {(accountName:String) in UserDefaults.standard.dexcomShareAccountName = accountName}, cancelHandler: nil)
case .dexcomSharePassword:
return SelectedRowAction.askText(title: Texts_Common.password, message: Texts_SettingsViews.giveDexcomSharePassword, keyboardType: UIKeyboardType.alphabet, placeHolder: "", actionTitle: nil, cancelTitle: nil, actionHandler: {(password:String) in UserDefaults.standard.dexcomSharePassword = password}, cancelHandler: nil)
return SelectedRowAction.askText(title: Texts_Common.password, message: Texts_SettingsViews.giveDexcomSharePassword, keyboardType: UIKeyboardType.alphabet, text: nil, placeHolder: nil, actionTitle: nil, cancelTitle: nil, actionHandler: {(password:String) in UserDefaults.standard.dexcomSharePassword = password}, cancelHandler: nil)
case .useUSDexcomShareurl:
return SelectedRowAction.nothing
case .dexcomShareSerialNumber:
var textAddon = ""
if let currentValue = UserDefaults.standard.dexcomShareSerialNumber {textAddon = "\n" + currentValue}
return SelectedRowAction.askText(title: Texts_SettingsViews.dexcomShareSerialNumber, message: Texts_SettingsViews.giveDexcomShareSerialNumber + textAddon, keyboardType: UIKeyboardType.alphabet, placeHolder: UserDefaults.standard.dexcomShareSerialNumber, actionTitle: nil, cancelTitle: nil, actionHandler: {(serialNumber:String) in UserDefaults.standard.dexcomShareSerialNumber = serialNumber}, cancelHandler: nil)
return SelectedRowAction.askText(title: Texts_SettingsViews.dexcomShareSerialNumber, message: Texts_SettingsViews.giveDexcomShareSerialNumber + textAddon, keyboardType: UIKeyboardType.alphabet, text: UserDefaults.standard.dexcomShareSerialNumber, placeHolder: nil, actionTitle: nil, cancelTitle: nil, actionHandler: {(serialNumber:String) in UserDefaults.standard.dexcomShareSerialNumber = serialNumber}, cancelHandler: nil)
}
}

View File

@ -18,10 +18,10 @@ struct SettingsViewGeneralSettingsViewModel:SettingsViewModelProtocol {
case .bloodGlucoseUnit:
return SelectedRowAction.callFunction(function: {UserDefaults.standard.bloodGlucoseUnitIsMgDl ? (UserDefaults.standard.bloodGlucoseUnitIsMgDl) = false : (UserDefaults.standard.bloodGlucoseUnitIsMgDl = true)})
case .lowMarkValue:
return SelectedRowAction.askText(title: Texts_SettingsViews.lowValue, message: nil, keyboardType: UserDefaults.standard.bloodGlucoseUnitIsMgDl ? .numberPad:.decimalPad, placeHolder: UserDefaults.standard.lowMarkValueInUserChosenUnitRounded, actionTitle: nil, cancelTitle: nil, actionHandler: {(lowMarkValue:String) in UserDefaults.standard.lowMarkValueInUserChosenUnitRounded = lowMarkValue}, cancelHandler: nil)
return SelectedRowAction.askText(title: Texts_SettingsViews.lowValue, message: nil, keyboardType: UserDefaults.standard.bloodGlucoseUnitIsMgDl ? .numberPad:.decimalPad, text: UserDefaults.standard.lowMarkValueInUserChosenUnitRounded, placeHolder: Constants.BGGraphBuilder.defaultLowMarkInMgdl.description, actionTitle: nil, cancelTitle: nil, actionHandler: {(lowMarkValue:String) in UserDefaults.standard.lowMarkValueInUserChosenUnitRounded = lowMarkValue}, cancelHandler: nil)
case .highMarkValue:
return SelectedRowAction.askText(title: Texts_SettingsViews.highValue, message: nil, keyboardType: UserDefaults.standard.bloodGlucoseUnitIsMgDl ? .numberPad:.decimalPad, placeHolder: UserDefaults.standard.highMarkValueInUserChosenUnitRounded, actionTitle: nil, cancelTitle: nil, actionHandler: {(highMarkValue:String) in UserDefaults.standard.highMarkValueInUserChosenUnitRounded = highMarkValue}, cancelHandler: nil)
return SelectedRowAction.askText(title: Texts_SettingsViews.highValue, 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)
}
}

View File

@ -59,13 +59,14 @@ enum SelectedRowAction {
/// - title: title that can be shown when asking for input
/// - message: message that can be shown when asking for input
/// - keyboardType: value can be used to define what kind of input is expected. In the end it's up to the viewcontroller or view to define what kind of keyboard will be used
/// - placeHolder to show in the textfield
/// - placeHolder to show in the textfield if text is nil
/// - text to show in the textfield
/// - actionTitle: text in the button that allows the user to confirm the input (Example 'Ok'), if nil then default value "Ok" will be used
/// - cancelTitle: text in the button that allows the user to cancel the input (Example 'Cancel'), if nil then default value "Cancel" will be used
/// - actionHandler: code to execute when user confirms input, with text that was entered by user, text is not optional here
/// - cancelHandler: code to execute when user cancels input
/// TODO: is it ok to define title, message optional ?
case askText (title:String?, message:String?, keyboardType:UIKeyboardType?, placeHolder:String?, actionTitle:String?, cancelTitle:String?, actionHandler: ((_ text: String) -> Void), cancelHandler: (() -> Void)?)
case askText (title:String?, message:String?, keyboardType:UIKeyboardType?, text:String?, placeHolder:String?, actionTitle:String?, cancelTitle:String?, actionHandler: ((_ text: String) -> Void), cancelHandler: (() -> Void)?)
/// when clicked, the function parameter needs to be called
///

View File

@ -18,10 +18,10 @@ class SettingsViewNightScoutSettingsViewModel:SettingsViewModelProtocol {
case .uploadReadingsToNightScout:
return SelectedRowAction.nothing
case .nightScoutUrl:
return SelectedRowAction.askText(title: Texts_SettingsViews.nightScoutUrl, message: UserDefaults.standard.nightScoutUrl, keyboardType: .URL, placeHolder: UserDefaults.standard.nightScoutUrl, actionTitle: nil, cancelTitle: nil, actionHandler: {(serialNumber:String) in UserDefaults.standard.nightScoutUrl = serialNumber}, cancelHandler: nil)
return SelectedRowAction.askText(title: Texts_SettingsViews.nightScoutUrl, message: UserDefaults.standard.nightScoutUrl, keyboardType: .URL, text: UserDefaults.standard.nightScoutUrl, placeHolder: "yoursitename", actionTitle: nil, cancelTitle: nil, actionHandler: {(serialNumber:String) in UserDefaults.standard.nightScoutUrl = serialNumber}, cancelHandler: nil)
case .nightScoutAPIKey:
return SelectedRowAction.askText(title: Texts_SettingsViews.nightScoutAPIKey, message: UserDefaults.standard.nightScoutAPIKey, keyboardType: .default, placeHolder: UserDefaults.standard.nightScoutAPIKey, actionTitle: nil, cancelTitle: nil, actionHandler: {(serialNumber:String) in UserDefaults.standard.nightScoutAPIKey = serialNumber}, cancelHandler: nil)
return SelectedRowAction.askText(title: Texts_SettingsViews.nightScoutAPIKey, message: UserDefaults.standard.nightScoutAPIKey, keyboardType: .default, text: UserDefaults.standard.nightScoutAPIKey, placeHolder: nil, actionTitle: nil, cancelTitle: nil, actionHandler: {(serialNumber:String) in UserDefaults.standard.nightScoutAPIKey = serialNumber}, cancelHandler: nil)
}
}

View File

@ -23,7 +23,7 @@ class SettingsViewSpeakSettingsViewModel:SettingsViewModelProtocol {
case .speakDelta:
return .nothing
case .speakInterval:
return SelectedRowAction.askText(title: Texts_SettingsViews.speakInterval, message: nil, keyboardType: .numberPad, placeHolder: UserDefaults.standard.speakInterval.description, actionTitle: nil, cancelTitle: nil, actionHandler: {(interval:String) in if let interval = Int(interval) {UserDefaults.standard.speakInterval = Int(interval)}}, cancelHandler: nil)
return SelectedRowAction.askText(title: Texts_SettingsViews.speakInterval, message: nil, keyboardType: .numberPad, text: UserDefaults.standard.speakInterval.description, placeHolder: "0", actionTitle: nil, cancelTitle: nil, actionHandler: {(interval:String) in if let interval = Int(interval) {UserDefaults.standard.speakInterval = Int(interval)}}, cancelHandler: nil)
}
}

View File

@ -15,7 +15,7 @@ struct SettingsViewTransmitterSettingsViewModel:SettingsViewModelProtocol {
switch setting {
case .transmitterId:
return SelectedRowAction.askText(title: Texts_SettingsViews.transmitterId, message: Texts_SettingsViews.giveTransmitterId, keyboardType: UIKeyboardType.alphabet, placeHolder: UserDefaults.standard.transmitterId, actionTitle: nil, cancelTitle: nil, actionHandler: {(serialNumber:String) in UserDefaults.standard.transmitterId = serialNumber}, cancelHandler: nil)
return SelectedRowAction.askText(title: Texts_SettingsViews.transmitterId, message: Texts_SettingsViews.giveTransmitterId, keyboardType: UIKeyboardType.alphabet, text: UserDefaults.standard.transmitterId, placeHolder: "00000", actionTitle: nil, cancelTitle: nil, actionHandler: {(serialNumber:String) in UserDefaults.standard.transmitterId = serialNumber}, cancelHandler: nil)
case .transmitterType:
var data = [String]()