Skip to content

Settings

Johan Degraeve edited this page Nov 10, 2019 · 11 revisions

Summary

Settings are stored in UserDefaults, see xdrip/View Controllers/SettingsViewController/View Models/UserDefaults.swift Charts userdefaults are in a seperate file UserDefaults+charts.swift

Settings are updated by the user through several classes :

  • SettingsViewController : this is the main page for the settings.

  • PickerViewController : is used whenever user needs to pick a value froma list (eg transmitter type)

  • In the View Models folder, there's a class per section in the settings. Example SettingsViewNightScoutSettingsViewModel . This class fetches and updates the data in the UserDefaults, it also gives info to the view controller about what type of data is expected from the user.

Add a setting

Update UserDefaults

Update file xdrip/Extensions/UserDefaults.swift

add a value to the enum Key

add a computed property to get and set the value with the expected type - if the type of a property is enum, then you may need to add an additional property example of type String. Because it's not possible to add observers to type enum. See for Example transmitterTypeAsString and transmitterType

Add new setting to Settings View, existing Section in Settings Page

To add a setting to an existing Section in the Settings Page.

In the folder xdrip/View Controllers/SettingsViewController/View Models there's a ViewModel per section that can appear in a settings page. That file needs to be updated (example for NightScout settings, the file is xdrip/View Controllers/SettingsViewController/View Models/SettingsViewNightScoutSettingsViewModel.swift)

Extend the enum Setting

The class in the file needs to be updated to support the new case.

func onRowSelect(index: Int) -> SelectedRowAction

Defines what should happen if the user clicks a specific row.

This is defined by returning an instance of SelectedRowAction

There are different cases :

nothing

Do nothing when user clicks a row.

This is the case for example when the row has a UISwitch. Clicking the switch will trigger a change of the setting.
There's no need to do anything additional

askText

This is for when a text input is required. Example url for Nightscout.

The parameters are

title:String? can be used as title field when asking text
message:String? an additional message giving more info about what type of input is required
keyboardType:UIKeyboardType?, eg numeric, .. see https://developer.apple.com/documentation/uikit/uikeyboardtype
placeHolder:String?, default value that can be shown
actionTitle:String?, eg "Ok" or "Add". Default value will be read from Text files
cancelTitle:String?, eg "Cancel". Default value will be read from Text files
actionHandler: ((_ text: String) -> Void), what to do when user confirms the text, usually this will be to store the value in the setting. Also a value check can be done, eg check the length of a transmitter id
cancelHandler: (() -> Void)?, What to do when user cancels the change, usually it will be nil value

callFunction

A function will be called. Example, in the Settings file SettingsViewGeneralSettingsViewModel.swift, there's a setting mgdl or mmol.
By clicking that row, the setting will swap from one to another, by calling a function.

selectFromList

A list must be shown to user form which user needs to pick one.

performSegue

performSegue to be done with specified identifier

showInfoText

To show information to the user

func accessoryType(index: Int) -> UITableViewCell.AccessoryType

Defines what kind of accessoryType to show when user clicks a row

Appears in the right side of the row, see https://developer.apple.com/documentation/uikit/uitableviewcell/accessorytype

The type disclosureIndicator is used whenever clicking will open a popup, example to enter the NightScout url

func detailedText(index: Int) -> String?

Defines text to be shown on right of the row. Example for row with NightScout url, this is the url that is currently stored in the settings.

func uiView(index: Int) -> (view: UIView?, reloadSection: Bool)

If a UIView is to be added in the row. It will appear on the right.

For the moment ony used for UISwitch, see https://developer.apple.com/documentation/uikit/views_and_controls

The returned view must include action to take when value of the UISwitch changes. This will usually be to change the value of the setting from on to off or vice versa.

To see an xxample have a look at SettingsViewNightScoutSettingsViewModel.swift

func completeSettingsViewRefreshNeeded(index: Int) -> Bool

In some cases, when changing a specific setting, other settings need to be enabled/disabled ...

For example, when changing from master to follower or vice versa, some settings in other sections needs to be disabled. In that case the function should return true for the index that represents the master/follower setting

func isEnabled(index: Int) -> Bool

Is the setting enabled or not. For instance, dexcom share settings, if transmitter type is G5, then the user can't set the serial, so it will be disabled, ie return false

func settingsRowText(index:Int) -> String

the text to be shown for a specific row in the Section

func numberOfRows() -> Int

the number of rows in the section

func sectionTitle() -> String?

the title of the section

To add a Section to the Settings Page

Create a new file in the View Models folder, example SettingsViewNewSectionViewModel

Define an enum Setting, which defines the settings in the new Section

Define a class that implements SettingsViewModelProtocol, name the class SettingsViewNewSectionViewModel

In the file SettingsViewController, search for the enum Section and add a case for the new Section

On top of the file add a new instance of the new View Model
Example fileprivate var newSectionViewModel = SettingsViewNewSectionViewModel()

Now in file SettingsViewController, update all the functions defined in protocols UITableViewDataSource and UITableViewDelegate to support the new Section, the new code is similar to existing cases.

In the new View Model, implement all the functions as defined in Add new setting to Settings View, existing Section in Settings Page