Skip to content

Commit 05c95b5

Browse files
authored
feat: IAMs now display when triggers added before first fetch (#1635)
* feat: IAMs now display when triggers added before first fetch - Addresses issue where in-app messages wouldn't display on cold starts if their triggers were added very early (before IAM fetch completed). - Tracks triggers added before first fetch completes, then applies the isTriggerChanged flag to matching messages when they are received from the server, ensuring redisplay logic works correctly. * test: add tests for early trigger tracking feature Add comprehensive test coverage for the early trigger tracking feature that enables IAMs to display when triggers are added before the first fetch completes on cold start.
1 parent 6be4cf7 commit 05c95b5

5 files changed

Lines changed: 498 additions & 1 deletion

File tree

iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
3C2D8A5928B4C4E300BE41F6 /* OSDelta.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C2D8A5828B4C4E300BE41F6 /* OSDelta.swift */; };
7777
3C2DB2F12DE6CB5E0006B905 /* OneSignalBadgeHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C2DB2EF2DE6CB5E0006B905 /* OneSignalBadgeHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; };
7878
3C2DB2F22DE6CB5E0006B905 /* OneSignalBadgeHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C2DB2F02DE6CB5E0006B905 /* OneSignalBadgeHelpers.m */; };
79+
3C30FE362F21FBE1001B9C25 /* EarlyTriggerTrackingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C30FE352F21FBE1001B9C25 /* EarlyTriggerTrackingTests.swift */; };
7980
3C3D34E92E95EAA5006A2924 /* LiveActivityConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C3D34E82E95EAA5006A2924 /* LiveActivityConstants.swift */; };
8081
3C3D8D782E92DB7500C3E977 /* OSLiveActivityViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C3D8D772E92DB7500C3E977 /* OSLiveActivityViewExtensions.swift */; };
8182
3C44673E296D099D0039A49E /* OneSignalMobileProvision.m in Sources */ = {isa = PBXBuildFile; fileRef = 912411FD1E73342200E41FD7 /* OneSignalMobileProvision.m */; };
@@ -1310,6 +1311,7 @@
13101311
3C2D8A5828B4C4E300BE41F6 /* OSDelta.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSDelta.swift; sourceTree = "<group>"; };
13111312
3C2DB2EF2DE6CB5E0006B905 /* OneSignalBadgeHelpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OneSignalBadgeHelpers.h; sourceTree = "<group>"; };
13121313
3C2DB2F02DE6CB5E0006B905 /* OneSignalBadgeHelpers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OneSignalBadgeHelpers.m; sourceTree = "<group>"; };
1314+
3C30FE352F21FBE1001B9C25 /* EarlyTriggerTrackingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EarlyTriggerTrackingTests.swift; sourceTree = "<group>"; };
13131315
3C3D34E82E95EAA5006A2924 /* LiveActivityConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveActivityConstants.swift; sourceTree = "<group>"; };
13141316
3C3D8D772E92DB7500C3E977 /* OSLiveActivityViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSLiveActivityViewExtensions.swift; sourceTree = "<group>"; };
13151317
3C448B9B2936ADFD002F96BC /* OSBackgroundTaskHandlerImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSBackgroundTaskHandlerImpl.h; sourceTree = "<group>"; };
@@ -2168,6 +2170,7 @@
21682170
3C01519B2C2E29F90079E076 /* IAMRequestTests.m */,
21692171
3C7021E82ECF0CF4001768C6 /* IAMIntegrationTests.swift */,
21702172
3CAA4BB62F0BAFBA00A16682 /* TriggerTests.swift */,
2173+
3C30FE352F21FBE1001B9C25 /* EarlyTriggerTrackingTests.swift */,
21712174
3CB35FCA2F0FA20B000E6E0F /* OSMessagingControllerUserStateTests.swift */,
21722175
3C7021E72ECF0CF3001768C6 /* OneSignalInAppMessagesTests-Bridging-Header.h */,
21732176
);
@@ -4313,6 +4316,7 @@
43134316
isa = PBXSourcesBuildPhase;
43144317
buildActionMask = 2147483647;
43154318
files = (
4319+
3C30FE362F21FBE1001B9C25 /* EarlyTriggerTrackingTests.swift in Sources */,
43164320
3CAA4BB72F0BAFBA00A16682 /* TriggerTests.swift in Sources */,
43174321
3C7021E92ECF0CF4001768C6 /* IAMIntegrationTests.swift in Sources */,
43184322
3C01519C2C2E29F90079E076 /* IAMRequestTests.m in Sources */,

iOS_SDK/OneSignalSDK/OneSignalInAppMessages/Controller/OSMessagingController.m

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ @interface OSMessagingController ()
149149
/// set when we attempt getInAppMessagesFromServer and no onesignal ID is available yet
150150
@property (strong, nonatomic, nullable) NSString *shouldFetchOnUserChangeWithSubscriptionID;
151151

152+
/// Tracks whether the first IAM fetch has completed since this cold start
153+
@property (nonatomic) BOOL hasCompletedFirstFetch;
154+
155+
/// Tracks trigger keys added early on cold start (before first fetch completes), for redisplay logic
156+
@property (strong, nonatomic, nonnull) NSMutableSet<NSString *> *earlySessionTriggers;
157+
152158
@end
153159

154160
@implementation OSMessagingController
@@ -218,6 +224,8 @@ - (instancetype)init {
218224
self.messageDisplayQueue = [NSMutableArray new];
219225
self.clickListeners = [NSMutableArray new];
220226
self.lifecycleListeners = [NSMutableArray new];
227+
self.hasCompletedFirstFetch = NO;
228+
self.earlySessionTriggers = [NSMutableSet new];
221229

222230
let standardUserDefaults = OneSignalUserDefaults.initStandard;
223231

@@ -404,6 +412,23 @@ - (void)updateInAppMessagesFromServer:(NSArray<OSInAppMessageInternal *> *)newMe
404412
self.messages = newMessages;
405413
self.calledLoadTags = NO;
406414
[self resetRedisplayMessagesBySession];
415+
416+
// Apply isTriggerChanged for messages that match triggers added too early on cold start
417+
if (self.earlySessionTriggers.count > 0) {
418+
[OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"Processing triggers added early on cold start: %@", self.earlySessionTriggers]];
419+
for (OSInAppMessageInternal *message in self.messages) {
420+
if ([self.redisplayedInAppMessages objectForKey:message.messageId] &&
421+
[self.triggerController hasSharedTriggers:message newTriggersKeys:self.earlySessionTriggers.allObjects]) {
422+
[OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"Setting isTriggerChanged=YES for message %@", message]];
423+
message.isTriggerChanged = YES;
424+
}
425+
}
426+
[self.earlySessionTriggers removeAllObjects];
427+
}
428+
429+
// Mark that first fetch has completed
430+
self.hasCompletedFirstFetch = YES;
431+
407432
[self evaluateMessages];
408433
[self deleteOldRedisplayedInAppMessages];
409434
}
@@ -806,6 +831,13 @@ - (void)evaluateRedisplayedInAppMessages:(NSArray<NSString *> *)newTriggersKeys
806831
#pragma mark Trigger Methods
807832
- (void)addTriggers:(NSDictionary<NSString *, id> *)triggers {
808833
[self evaluateRedisplayedInAppMessages:triggers.allKeys];
834+
835+
// Track triggers added early on cold start (before first fetch completes) for redisplay logic
836+
if (!self.hasCompletedFirstFetch) {
837+
[OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:[NSString stringWithFormat:@"Tracking triggers added early on cold start: %@", triggers]];
838+
[self.earlySessionTriggers addObjectsFromArray:triggers.allKeys];
839+
}
840+
809841
[self.triggerController addTriggers:triggers];
810842
}
811843

0 commit comments

Comments
 (0)