Skip to content

Commit 5a94b8d

Browse files
docs: update mobile SDK integration guides to match current source (#787)
* docs: update mobile SDK integration guides to match current source Because * `globalUserParticipation` no longer exists in the SDK — it was split into `experimentParticipation` and `rolloutParticipation` * The `recordedContext` NimbusBuilder option for behavioral targeting and Glean recording is undocumented * `recordMalformedConfiguration()` for reporting invalid feature configs is undocumented * `HardcodedNimbusFeatures` testing helper is undocumented This commit * Replaces `globalUserParticipation` in mobile-ui.md with the two separate participation properties and explains their distinct behavior * Adds `recordedContext` section to both Android and iOS integration guides with cross-link to Recording Targeting Context docs * Adds `recordMalformedConfiguration()` section to Android guide * Adds `HardcodedNimbusFeatures` testing section with usage example and key test assertion methods * Updates complete NimbusBuilder examples in both guides to include `recordedContext` and `featureManifest` * Removes deprecated `customTargetingAttributes` from iOS example Fixes #786 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: address review feedback on HardcodedNimbusFeatures wording Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 93fdf4c commit 5a94b8d

3 files changed

Lines changed: 76 additions & 7 deletions

File tree

docs/platform-guides/android/integration.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,55 @@ Adding the `usePreviewCollection` flag allows the builder to configure a `Nimbus
220220
}.build(appInfo)
221221
```
222222

223+
### Connecting to the Recorded Targeting Context
224+
225+
The `recordedContext` builder option connects the Nimbus SDK to a `RecordedContext` implementation for behavioral targeting and Glean recording. This replaces the older `customTargetingAttributes` approach for providing targeting attributes.
226+
227+
```kotlin
228+
return NimbusBuilder(context).apply {
229+
//
230+
recordedContext = RecordedNimbusContext(isFirstRun = isAppFirstRun)
231+
//
232+
}.build(appInfo)
233+
```
234+
235+
See [Recording Targeting Context](/advanced/recording-targeting-context) for details on implementing the `RecordedContext` trait.
236+
237+
### Reporting malformed feature configuration
238+
239+
If your app detects that a feature configuration from an experiment is invalid or malformed, you can report it as telemetry using `recordMalformedConfiguration`:
240+
241+
```kotlin
242+
FxNimbus.features.myFeature.recordMalformedConfiguration(partId = "invalid-field")
243+
```
244+
245+
This sends a `malformedConfiguration` Glean event identifying the feature and the specific part that was invalid.
246+
247+
## Unit and UI testing with `HardcodedNimbusFeatures`
248+
249+
The `HardcodedNimbusFeatures` class lets you inject feature configurations directly for unit and UI testing, without needing to run the Nimbus SDK or connect to the network:
250+
251+
```kotlin
252+
val hardcodedNimbus = HardcodedNimbusFeatures(testContext,
253+
"my-feature" to JSONObject("""{"enabled": true, "title": "Hello"}""")
254+
)
255+
hardcodedNimbus.connectWith(FxNimbus)
256+
257+
// Access feature values as normal — it will use the hardcoded config.
258+
val config = FxNimbus.features.myFeature.value()
259+
260+
// Test assertions
261+
assertTrue(hardcodedNimbus.isExposed("my-feature"))
262+
assertEquals(1, hardcodedNimbus.getExposureCount("my-feature"))
263+
assertFalse(hardcodedNimbus.isMalformed("my-feature"))
264+
```
265+
266+
Key test methods:
267+
- `isExposed(featureId)` — whether `recordExposureEvent` was called
268+
- `getExposureCount(featureId)` — number of exposure events recorded
269+
- `isMalformed(featureId)` — whether `recordMalformedConfiguration` was called
270+
- `hasFeature(featureId)` — whether the feature was provided to the constructor
271+
223272
## A complete `NimbusBuilder` example
224273

225274
```kotlin
@@ -232,6 +281,8 @@ Adding the `usePreviewCollection` flag allows the builder to configure a `Nimbus
232281
usePreviewCollection = context.settings().nimbusUsePreview
233282
isFirstRun = isAppFirstRun
234283
sharedPreferences = context.settings().preferences
284+
recordedContext = RecordedNimbusContext(isFirstRun = isAppFirstRun)
285+
featureManifest = FxNimbus
235286
// Optional callbacks.
236287
onCreateCallback = { nimbus ->
237288
// called when nimbus is set up

docs/platform-guides/android/mobile-ui.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,24 @@ Required user interface components for apps integrating with the Nimbus SDK.
1010

1111
Currently Nimbus provides no user-interface components of its own, though provides API to connect to existing settings screens.
1212

13-
## Global Opt-Out/Opt-In for Experiments
13+
## Opt-Out/Opt-In Controls
1414

1515
The settings page should include a `Studies` toggle, which allows users to opt-in or opt-out of experiments. The example from Firefox for iOS is shown:
1616

1717
<img src="/img/firefox-ios/studies-toggle.png" width="300px" />
1818

19-
Toggling the `Studies` flag should set the `Nimbus` value for `globalUserParticipation`:
19+
Experiment participation and rollout participation are controlled separately:
2020

2121
```kotlin
22-
nimbus.globalUserParticipation = flag
22+
// Controls opt-in/out for experiments (not rollouts)
23+
nimbus.experimentParticipation = flag
24+
25+
// Controls opt-in/out for rollouts (not experiments)
26+
nimbus.rolloutParticipation = flag
2327
```
2428

29+
When set to `false`, the user will be opted out of all active enrollments of that type and will not be enrolled in new ones. Toggling the `Studies` flag should set `experimentParticipation`.
30+
2531
## Resetting Telemetry Identifiers
2632

2733
During experiment enrollment, telemetry is generated which can connect the user to the experiment enrollment.

docs/platform-guides/ios/integration.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,20 @@ To connect the `NimbusInterface` object to the command line, we need to feed the
184184
.build(appInfo: appInfo)
185185
```
186186

187+
### Connecting to the Recorded Targeting Context
188+
189+
The `recordedContext` builder option connects the Nimbus SDK to a `RecordedContext` implementation for behavioral targeting and Glean recording. This replaces the older `customTargetingAttributes` approach for providing targeting attributes.
190+
191+
```swift
192+
return NimbusBuilder(dbPath: dbPath)
193+
//
194+
.with(recordedContext: RecordedNimbusContext(isFirstRun: isFirstRun))
195+
//
196+
.build(appInfo: appSettings)
197+
```
198+
199+
See [Recording Targeting Context](/advanced/recording-targeting-context) for details on implementing the `RecordedContext` protocol.
200+
187201
## A complete `NimbusBuilder` example
188202

189203
```swift
@@ -203,10 +217,7 @@ public static var nimbus: NimbusInterface = {
203217
// thinks it is.
204218
let appSettings = NimbusAppSettings(
205219
appName: "example-app",
206-
channel: "release",
207-
customTargetingAttributes: [
208-
"is_first_run": isFirstRun,
209-
]
220+
channel: "release"
210221
)
211222

212223
let errorReporter: NimbusErrorReporter = { err in
@@ -229,6 +240,7 @@ public static var nimbus: NimbusInterface = {
229240
.with(errorReporter: errorReporter)
230241
.with(initialExperiments: Bundle.main.url(forResource: "initial_experiments", withExtension: "json"))
231242
.isFirstRun(isFirstRun)
243+
.with(recordedContext: RecordedNimbusContext(isFirstRun: isFirstRun))
232244
.with(bundles: bundles)
233245
.with(userDefaults: UserDefaults.standard)
234246
.with(featureManifest: AppConfig.shared)

0 commit comments

Comments
 (0)