Skip to content

Commit 5a0b8dd

Browse files
authored
Merge pull request #863 from Iterable/evan/MOB-10615-improve-criteria-update-frequency
[MOB-10615] improve criteria update frequency
2 parents 12f0cc4 + 4ac4a81 commit 5a0b8dd

File tree

5 files changed

+280
-12
lines changed

5 files changed

+280
-12
lines changed

iterableapi/src/main/java/com/iterable/iterableapi/AnonymousUserManager.java

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import androidx.annotation.NonNull;
99
import androidx.annotation.Nullable;
10+
import androidx.annotation.VisibleForTesting;
1011
import androidx.core.app.NotificationManagerCompat;
1112

1213
import com.google.gson.Gson;
@@ -25,10 +26,25 @@
2526
import java.util.List;
2627
import java.util.UUID;
2728

28-
public class AnonymousUserManager {
29+
public class AnonymousUserManager implements IterableActivityMonitor.AppStateCallback {
2930

3031
private static final String TAG = "AnonymousUserManager";
31-
private final IterableApi iterableApi = IterableApi.sharedInstance;
32+
private IterableApi iterableApi = IterableApi.sharedInstance;
33+
private final IterableActivityMonitor activityMonitor;
34+
long lastCriteriaFetch = 0;
35+
36+
AnonymousUserManager(IterableApi iterableApi) {
37+
this(iterableApi,
38+
IterableActivityMonitor.getInstance());
39+
}
40+
41+
@VisibleForTesting
42+
AnonymousUserManager(IterableApi iterableApi,
43+
IterableActivityMonitor activityMonitor) {
44+
this.iterableApi = iterableApi;
45+
this.activityMonitor = activityMonitor;
46+
this.activityMonitor.addCallback(this);
47+
}
3248

3349
void updateAnonSession() {
3450
IterableLogger.v(TAG, "updateAnonSession");
@@ -157,6 +173,8 @@ void trackAnonUpdateCart(@NonNull List<CommerceItem> items) {
157173
}
158174

159175
void getCriteria() {
176+
lastCriteriaFetch = System.currentTimeMillis();
177+
160178
iterableApi.apiClient.getCriteriaList(data -> {
161179
if (data != null) {
162180
try {
@@ -465,4 +483,27 @@ private String getPushStatus() {
465483
return "";
466484
}
467485
}
486+
487+
@Override
488+
public void onSwitchToForeground() {
489+
long currentTime = System.currentTimeMillis();
490+
491+
// fetching anonymous user criteria on foregrounding
492+
if (!iterableApi.checkSDKInitialization()
493+
&& iterableApi._userIdAnon == null
494+
&& iterableApi.config.enableAnonActivation
495+
&& iterableApi.getVisitorUsageTracked()
496+
&& iterableApi.config.enableForegroundCriteriaFetch
497+
&& currentTime - lastCriteriaFetch >= IterableConstants.CRITERIA_FETCHING_COOLDOWN) {
498+
499+
lastCriteriaFetch = currentTime;
500+
this.getCriteria();
501+
IterableLogger.d(TAG, "Fetching anonymous user criteria - Foreground");
502+
}
503+
}
504+
505+
@Override
506+
public void onSwitchToBackground() {
507+
508+
}
468509
}

iterableapi/src/main/java/com/iterable/iterableapi/IterableApi.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public class IterableApi {
3636
private String _apiKey;
3737
private String _email;
3838
private String _userId;
39-
private String _userIdAnon;
39+
String _userIdAnon;
4040
private String _authToken;
4141
private boolean _debugMode;
4242
private Bundle _payloadData;
@@ -47,8 +47,8 @@ public class IterableApi {
4747
private IterableHelper.FailureHandler _setUserFailureCallbackHandler;
4848

4949
IterableApiClient apiClient = new IterableApiClient(new IterableApiAuthProvider());
50-
private static final AnonymousUserManager anonymousUserManager = new AnonymousUserManager();
5150
private static final AnonymousUserMerge anonymousUserMerge = new AnonymousUserMerge();
51+
private @Nullable AnonymousUserManager anonymousUserManager;
5252
private @Nullable IterableInAppManager inAppManager;
5353
private @Nullable IterableEmbeddedManager embeddedManager;
5454
private String inboxSessionId;
@@ -441,7 +441,7 @@ private boolean isInitialized() {
441441
return _apiKey != null && (_email != null || _userId != null);
442442
}
443443

444-
private boolean checkSDKInitialization() {
444+
boolean checkSDKInitialization() {
445445
if (!isInitialized()) {
446446
IterableLogger.w(TAG, "Iterable SDK must be initialized with an API key and user email/userId before calling SDK methods");
447447
return false;
@@ -666,12 +666,21 @@ public static void initialize(@NonNull Context context, @NonNull String apiKey,
666666
);
667667
}
668668

669+
if (sharedInstance.anonymousUserManager == null) {
670+
sharedInstance.anonymousUserManager = new AnonymousUserManager(
671+
sharedInstance
672+
);
673+
}
674+
669675
loadLastSavedConfiguration(context);
670676
IterablePushNotificationUtil.processPendingAction(context);
671677

672-
if (!sharedInstance.checkSDKInitialization() && sharedInstance._userIdAnon == null && sharedInstance.config.enableAnonActivation && sharedInstance.getVisitorUsageTracked()) {
673-
anonymousUserManager.updateAnonSession();
674-
anonymousUserManager.getCriteria();
678+
if (!sharedInstance.checkSDKInitialization()
679+
&& sharedInstance._userIdAnon == null
680+
&& sharedInstance.config.enableAnonActivation
681+
&& sharedInstance.getVisitorUsageTracked()) {
682+
sharedInstance.anonymousUserManager.updateAnonSession();
683+
sharedInstance.anonymousUserManager.getCriteria();
675684
}
676685

677686
if (DeviceInfoUtils.isFireTV(context.getPackageManager())) {

iterableapi/src/main/java/com/iterable/iterableapi/IterableConfig.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ public class IterableConfig {
6060
*/
6161
final IterableAuthHandler authHandler;
6262

63-
63+
/**
64+
* Handler that can be used to retrieve the anonymous user id
65+
*/
6466
final IterableAnonUserHandler iterableAnonUserHandler;
6567

6668
/**
@@ -92,8 +94,20 @@ public class IterableConfig {
9294

9395
final boolean encryptionEnforced;
9496

97+
/**
98+
* Enables anonymous user activation
99+
*/
95100
final boolean enableAnonActivation;
96101

102+
/**
103+
* Toggles fetching of anonymous user criteria on foregrounding when set to true
104+
* By default, the SDK will fetch anonymous user criteria on foregrounding.
105+
*/
106+
final boolean enableForegroundCriteriaFetch;
107+
108+
/**
109+
* The number of anonymous events stored in local storage
110+
*/
97111
final int eventThresholdLimit;
98112

99113
/**
@@ -130,6 +144,7 @@ private IterableConfig(Builder builder) {
130144
useInMemoryStorageForInApps = builder.useInMemoryStorageForInApps;
131145
encryptionEnforced = builder.encryptionEnforced;
132146
enableAnonActivation = builder.enableAnonActivation;
147+
enableForegroundCriteriaFetch = builder.enableForegroundCriteriaFetch;
133148
enableEmbeddedMessaging = builder.enableEmbeddedMessaging;
134149
eventThresholdLimit = builder.eventThresholdLimit;
135150
identityResolution = builder.identityResolution;
@@ -155,6 +170,7 @@ public static class Builder {
155170
private IterableDecryptionFailureHandler decryptionFailureHandler;
156171
private boolean encryptionEnforced = false;
157172
private boolean enableAnonActivation = false;
173+
private boolean enableForegroundCriteriaFetch = true;
158174
private boolean enableEmbeddedMessaging = false;
159175
private int eventThresholdLimit = 100;
160176
private IterableIdentityResolution identityResolution = new IterableIdentityResolution();
@@ -310,7 +326,6 @@ public Builder setDataRegion(@NonNull IterableDataRegion dataRegion) {
310326
* Set whether the SDK should store in-apps only in memory, or in file storage
311327
* @param useInMemoryStorageForInApps `true` will have in-apps be only in memory
312328
*/
313-
314329
@NonNull
315330
public Builder setUseInMemoryStorageForInApps(boolean useInMemoryStorageForInApps) {
316331
this.useInMemoryStorageForInApps = useInMemoryStorageForInApps;
@@ -327,6 +342,16 @@ public Builder setEnableAnonActivation(boolean enableAnonActivation) {
327342
return this;
328343
}
329344

345+
/**
346+
* Set whether the SDK should disable criteria fetching on foregrounding. Set this to `false`
347+
* if you want criteria to only be fetched on app launch.
348+
* @param enableForegroundCriteriaFetch `true` will fetch criteria only on app launch.
349+
*/
350+
public Builder setEnableForegroundCriteriaFetch(boolean enableForegroundCriteriaFetch) {
351+
this.enableForegroundCriteriaFetch = enableForegroundCriteriaFetch;
352+
return this;
353+
}
354+
330355
public Builder setEventThresholdLimit(int eventThresholdLimit) {
331356
this.eventThresholdLimit = eventThresholdLimit;
332357
return this;
@@ -348,7 +373,6 @@ public Builder setEnableEmbeddedMessaging(boolean enableEmbeddedMessaging) {
348373
* @param identityResolution
349374
* @return
350375
*/
351-
352376
public Builder setIdentityResolution(IterableIdentityResolution identityResolution) {
353377
this.identityResolution = identityResolution;
354378
return this;

iterableapi/src/main/java/com/iterable/iterableapi/IterableConstants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ public final class IterableConstants {
336336
public static final String PURCHASE_ITEM = "shoppingCartItems";
337337
public static final String PURCHASE_ITEM_PREFIX = PURCHASE_ITEM + ".";
338338
public static final String MIN_MATCH = "minMatch";
339-
339+
public static final Integer CRITERIA_FETCHING_COOLDOWN = 120000;
340340

341341
//Tracking types
342342
public static final String TRACK_EVENT = "customEvent";

0 commit comments

Comments
 (0)