Skip to main content

Using prefs to override feature variables

This page details adding pref-key to a feature definition. This cause the FML generated code to check the user preferences (UserDefaults or SharedPrefences) before checking the Nimbus configuration store or the default.

Setting up

The app's preferences object needs to be added to the NimbusBuilder call:

NimbusBuilder()
.with(userDefaults: UserDefaults.standard) // or alternative
.build()

Without this line, the default value used is UserDefaults.standard.

These should be readable by Nimbus, but writeable by the rest of the app. For best effect, these should be the same preferences that drive the Settings screens.

Once the preference object is available to nimbus, you can add pref-keys to feature variables.

Adding a pref-key to a feature variable definitions

The pref-key can be specified by top level feature variables:

features:
sample-feature:
variables:
is-enabled:
type: Boolean
default: false
pref-key: sample-feature.isEnabled

The generated API is used in the same way as without the pref-key:

let feature = FxNimbus.shared.features.sampleFeature.value()
if feature.isEnabled {
// Do something because the feature has been enabled.
}

However, now, the call to feature.isEnabled is overridden by the preference held at sample-feature.isEnabled.

This is available for types that are supported by preferences: Boolean, Int, String and Text.

Generated code sketch

The generated code looks approximately like:

let isEnabled: Boolean {
return prefs.getBoolean("sample-feature.isEnabled") ??
json.getBoolean("is-enabled") ??
defaults.isEnabled
}

Without the pref-key:

let isEnabled: Boolean {
return json.getBoolean("is-enabled") ??
defaults.isEnabled
}

Limitations

This is available for feature variables (not nested Objects fields), and only for scalar types.

It is not available for structural types (i.e. Option<T>, List<T> or Map<String, T>).

Feedback welcome

If there is demand for it, then support for these types and places will be considered.

Similarly, we're looking for feedback on how to make this API or generated code better.

Additional effects of experiment events

If the user sets any of the named preferences for the feature, then the feature is said to be user-modified.

This is exposed in the isModified() method of the feature.

User-modified features will not emit exposure events.

experimental

Question: Should user-modification be allowed for the general population? i.e. can we add these toggles to a public facing settings screen?

Answer: Currently, it is recommended that user-modification should be exposed only in Secret Settings screens.

This is not suitable as building an opt out of all experiments involving the feature.