Skip to content

Commit 81f797c

Browse files
committed
Fix IAM redisplay multiple times
* When IAM only has dynamic triggers it can end redisplaying multiple times on the same session * Limit IAM with only dynamic trigger to display once per session * Add test for escenario
1 parent fe0d439 commit 81f797c

File tree

4 files changed

+42
-4
lines changed

4 files changed

+42
-4
lines changed

iOS_SDK/OneSignalSDK/Source/OSMessagingController.m

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ - (void)setDataForRedisplay:(OSInAppMessage *)message {
361361
message.displayStats.lastDisplayTime = redisplayMessageSavedData.displayStats.lastDisplayTime;
362362

363363
// Message that don't have triggers should display only once per session
364-
BOOL triggerHasChanged = message.isTriggerChanged || (!redisplayMessageSavedData.isDisplayedInSession && [message.triggers count] == 0);
364+
BOOL triggerHasChanged = [self hasMessageTriggerChanged:message];
365365

366366
[OneSignal onesignal_Log:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"setDataForRedisplay with message: %@ \ntriggerHasChanged: %@ \nno triggers: %@ \ndisplayed in session saved: %@", message, message.isTriggerChanged ? @"YES" : @"NO", [message.triggers count] == 0 ? @"YES" : @"NO", redisplayMessageSavedData.isDisplayedInSession ? @"YES" : @"NO"]];
367367
// Check if conditions are correct for redisplay
@@ -378,6 +378,18 @@ - (void)setDataForRedisplay:(OSInAppMessage *)message {
378378
}
379379
}
380380

381+
- (BOOL)hasMessageTriggerChanged:(OSInAppMessage *)message {
382+
// Message that only have dynamic trigger should display only once per session
383+
BOOL messageHasOnlyDynamicTrigger = [self.triggerController messageHasOnlyDynamicTriggers:message];
384+
if (messageHasOnlyDynamicTrigger)
385+
return !message.isDisplayedInSession;
386+
387+
// Message that don't have triggers should display only once per session
388+
BOOL shouldMessageDisplayInSession = !message.isDisplayedInSession && [message.triggers count] == 0;
389+
390+
return message.isTriggerChanged || shouldMessageDisplayInSession;
391+
}
392+
381393
/*
382394
Method to check whether or not to show an IAM
383395
Checks if the IAM matches any triggers or if it exists in cached seenInAppMessages set
@@ -498,7 +510,6 @@ - (void)persistInAppMessageForRedisplay:(OSInAppMessage *)message {
498510
return;
499511
}
500512

501-
502513
let displayTimeSeconds = self.dateGenerator();
503514
message.displayStats.lastDisplayTime = displayTimeSeconds;
504515
[message.displayStats incrementDisplayQuantity];

iOS_SDK/OneSignalSDK/Source/OSTriggerController.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ NS_ASSUME_NONNULL_BEGIN
4848

4949
- (BOOL)messageMatchesTriggers:(OSInAppMessage *)message;
5050
- (BOOL)hasSharedTriggers:(OSInAppMessage *)message newTriggersKeys:(NSArray<NSString *> *)newTriggersKeys;
51+
- (BOOL)messageHasOnlyDynamicTriggers:(OSInAppMessage *)message;
5152
- (void)addTriggers:(NSDictionary<NSString *, id> *)triggers;
5253
- (void)removeTriggersForKeys:(NSArray<NSString *> *)keys;
5354
- (NSDictionary<NSString *, id> *)getTriggers;

iOS_SDK/OneSignalSDK/Source/OSTriggerController.m

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,26 @@ - (BOOL)hasSharedTriggers:(OSInAppMessage *)message newTriggersKeys:(NSArray<NSS
9797
return NO;
9898
}
9999

100+
/*
101+
* Part of redisplay logic
102+
*
103+
* If message has only dynamic trigger return true, otherwise false
104+
*/
105+
- (BOOL)messageHasOnlyDynamicTriggers:(OSInAppMessage *)message {
106+
if (message.triggers == nil || message.triggers.count == 0)
107+
return false;
108+
109+
for (NSArray <OSTrigger *> *andConditions in message.triggers) {
110+
for (OSTrigger *trigger in andConditions) {
111+
if ([trigger.kind isEqualToString:OS_DYNAMIC_TRIGGER_KIND_CUSTOM])
112+
// At least one trigger is not dynamic
113+
return false;
114+
}
115+
}
116+
117+
return true;
118+
}
119+
100120
#pragma mark Private Methods
101121

102122
- (void)timeSinceLastMessage:(NSDate *)date {

iOS_SDK/OneSignalSDK/UnitTests/InAppMessagingIntegrationTests.m

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,15 +267,21 @@ - (void)testIAMIsScheduled {
267267
(all the triggers for the message evaluate to true), the SDK should display the message. This
268268
test verifies that the message actually gets displayed.
269269
*/
270-
- (void)testIAMIsDisplayed {
270+
- (void)testIAMIsDisplayedOncePerSession {
271+
[OneSignal pauseInAppMessages:false];
272+
271273
let trigger = [OSTrigger dynamicTriggerWithKind:OS_DYNAMIC_TRIGGER_KIND_SESSION_TIME withOperator:OSTriggerOperatorTypeLessThan withValue:@10.0];
272274

273-
let message = [OSInAppMessageTestHelper testMessageWithTriggers:@[@[trigger]]];
275+
let message = [OSInAppMessageTestHelper testMessageWithTriggers:@[@[trigger]] withRedisplayLimit:@10 delay:@0];
274276

275277
[self initOneSignalWithInAppMessage:message];
276278

277279
XCTAssertFalse(NSTimerOverrider.hasScheduledTimer);
278280
XCTAssertEqual(OSMessagingControllerOverrider.messageDisplayQueue.count, 1);
281+
282+
[OSMessagingControllerOverrider dismissCurrentMessage];
283+
284+
XCTAssertEqual(OSMessagingControllerOverrider.messageDisplayQueue.count, 0);
279285
}
280286

281287
// if we have two messages that are both valid to displayed add them to the queue (triggers are all true),

0 commit comments

Comments
 (0)