diff --git a/CHANGELOG.md b/CHANGELOG.md index c0673d32c..3fa81c938 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## Unreleased + +### Updates + +- Added `IterableConfig.eventThresholdLimit` (default `100`) to cap locally stored unknown-user events before identification (SDK-553). The value is forwarded to the native SDK; it has no runtime effect in React Native until `enableUnknownUserActivation` is exposed in a future release (that switch is not on the RN config surface yet). + ## 3.2.1 ### Fixes diff --git a/android/src/main/java/com/iterable/reactnative/Serialization.java b/android/src/main/java/com/iterable/reactnative/Serialization.java index 97aa52f49..51c5d3368 100644 --- a/android/src/main/java/com/iterable/reactnative/Serialization.java +++ b/android/src/main/java/com/iterable/reactnative/Serialization.java @@ -201,6 +201,11 @@ static IterableConfig.Builder getConfigFromReadableMap(ReadableMap iterableConte configBuilder.setExpiringAuthTokenRefreshPeriod(iterableContextJSON.optLong("expiringAuthTokenRefreshPeriod")); } + if (iterableContextJSON.has("eventThresholdLimit")) { + configBuilder.setEventThresholdLimit( + iterableContextJSON.optInt("eventThresholdLimit", 100)); + } + if (iterableContextJSON.has("useInMemoryStorageForInApps") || iterableContextJSON.has("androidSdkUseInMemoryStorageForInApps")) { configBuilder.setUseInMemoryStorageForInApps(iterableContextJSON.optBoolean("useInMemoryStorageForInApps")); } diff --git a/ios/RNIterableAPI/Serialization.swift b/ios/RNIterableAPI/Serialization.swift index fee4c49b6..b0b1bda2c 100644 --- a/ios/RNIterableAPI/Serialization.swift +++ b/ios/RNIterableAPI/Serialization.swift @@ -75,6 +75,10 @@ extension IterableConfig { config.expiringAuthTokenRefreshPeriod = expiringAuthTokenRefreshPeriod } + if let eventThresholdLimit = dict["eventThresholdLimit"] as? Int { + config.eventThresholdLimit = eventThresholdLimit + } + if let logLevelNumber = dict["logLevel"] as? NSNumber { config.logDelegate = createLogDelegate(logLevelNumber: logLevelNumber) } diff --git a/src/core/classes/Iterable.test.ts b/src/core/classes/Iterable.test.ts index baccc3e41..53e8dd69a 100644 --- a/src/core/classes/Iterable.test.ts +++ b/src/core/classes/Iterable.test.ts @@ -328,6 +328,7 @@ describe('Iterable', () => { expect(config.enableEmbeddedMessaging).toBe(false); expect(config.encryptionEnforced).toBe(false); expect(config.expiringAuthTokenRefreshPeriod).toBe(60.0); + expect(config.eventThresholdLimit).toBe(100); expect(config.inAppDisplayInterval).toBe(30.0); expect(config.inAppHandler).toBe(undefined); expect(config.logLevel).toBe(IterableLogLevel.debug); @@ -347,6 +348,7 @@ describe('Iterable', () => { expect(configDict.enableEmbeddedMessaging).toBe(false); expect(configDict.encryptionEnforced).toBe(false); expect(configDict.expiringAuthTokenRefreshPeriod).toBe(60.0); + expect(configDict.eventThresholdLimit).toBe(100); expect(configDict.inAppDisplayInterval).toBe(30.0); expect(configDict.inAppHandlerPresent).toBe(false); expect(configDict.logLevel).toBe(IterableLogLevel.debug); @@ -365,6 +367,13 @@ describe('Iterable', () => { expect(configDict.androidWakeDelayMs).toBe(1500); expect(configDict.authCallbackTimeoutMs).toBe(2500); }); + + it('should include eventThresholdLimit in toDict() when overridden', () => { + const config = new IterableConfig(); + config.eventThresholdLimit = 50; + const configDict = config.toDict(); + expect(configDict.eventThresholdLimit).toBe(50); + }); }); describe('urlHandler', () => { diff --git a/src/core/classes/IterableConfig.ts b/src/core/classes/IterableConfig.ts index b4de2fb41..e30639bbd 100644 --- a/src/core/classes/IterableConfig.ts +++ b/src/core/classes/IterableConfig.ts @@ -262,6 +262,18 @@ export class IterableConfig { */ expiringAuthTokenRefreshPeriod = 60.0; + /** + * Maximum number of unknown-user (anonymous) events stored locally before + * identification. The native SDK drops the oldest events when the count + * exceeds this limit. + * + * The value is sent to the native SDK at init. React Native does not expose + * `enableUnknownUserActivation` yet, so this limit has no observable effect + * until that option is added; when it is, the limit applies only while + * unknown-user activation is enabled. + */ + eventThresholdLimit = 100; + /** * Use this array to declare the specific URL protocols that the SDK can * expect to see on incoming links from Iterable, so it knows that it can @@ -476,6 +488,7 @@ export class IterableConfig { /** The log level for the SDK. */ logLevel: this.logLevel, expiringAuthTokenRefreshPeriod: this.expiringAuthTokenRefreshPeriod, + eventThresholdLimit: this.eventThresholdLimit, allowedProtocols: this.allowedProtocols, androidSdkUseInMemoryStorageForInApps: this.androidSdkUseInMemoryStorageForInApps,