Skip to content

Commit c2ba503

Browse files
authored
Feat: live activities click events (#1593)
* Add request for Click Events This is the skeleton, we still need to finalize the path and parameters * Add widget extension methods for click tracking Add extension method `onesignalWidgetURL` to View and DynamicIsland that is modeled after the corresponding `widgetURL` methods in WidgetKit. * Add trackClickAndReturnOriginal method Developers call the `OneSignal.LiveActivities.trackClickAndReturnOriginal(url)` method to provide OneSignal the click tracking metadata. This method returns the intended original URL, with which they use to navigate their users. * Dev app updates to use new functionality * live activity: add notification ID to click event notification ID may be nullable if the live activity is started in-app * update click event request path and params * update example app to track clicks * Use OneSignal-aware activity in the demo app * Add onesignalWidgetURL to all OneSignal-aware activities in the demo app * Add tests for live activity click events * Add tests for live activity click events * Refactor generateTrackingDeepLink helper method to be testable, and move to enum namespace (internal by default) * Update the URL in the example app to be more complex
1 parent 7531828 commit c2ba503

File tree

15 files changed

+617
-11
lines changed

15 files changed

+617
-11
lines changed

iOS_SDK/OneSignalDevApp/OneSignalDevApp/AppDelegate.m

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ @implementation AppDelegate
4646

4747
OneSignalNotificationCenterDelegate *_notificationDelegate;
4848

49+
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
50+
// Log the full tracking URL and the original extracted URL
51+
// Also trigger trackClickAndReturnOriginal twice to confirm this click event is only sent once
52+
NSLog(@"Dev App: application openURL FULL URL is %@", url);
53+
NSURL *originalURL1 = [OneSignal.LiveActivities trackClickAndReturnOriginal:url];
54+
NSURL *originalURL2 = [OneSignal.LiveActivities trackClickAndReturnOriginal:url];
55+
NSLog(@"Dev App: application openURL processed, original URL is %@", originalURL1);
56+
return YES;
57+
}
58+
4959
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
5060

5161
// [FIRApp configure];

iOS_SDK/OneSignalDevApp/OneSignalDevApp/Info.plist

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,17 @@
2424
<string>APPL</string>
2525
<key>CFBundleShortVersionString</key>
2626
<string>$(MARKETING_VERSION)</string>
27+
<key>CFBundleURLTypes</key>
28+
<array>
29+
<dict>
30+
<key>CFBundleURLName</key>
31+
<string>com.onesignal.example</string>
32+
<key>CFBundleURLSchemes</key>
33+
<array>
34+
<string>myapp</string>
35+
</array>
36+
</dict>
37+
</array>
2738
<key>CFBundleVersion</key>
2839
<string>$(CURRENT_PROJECT_VERSION)</string>
2940
<key>LSRequiresIPhoneOS</key>

iOS_SDK/OneSignalDevApp/OneSignalDevApp/ViewController.m

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,12 @@ - (IBAction)startAndEnterLiveActivity:(id)sender {
242242
NSString *activityId = [self.activityId text];
243243
// Will not make a live activity if activityId is empty
244244
if (activityId && activityId.length) {
245-
// [LiveActivityController createDefaultActivityWithActivityId:activityId ];
246-
[LiveActivityController createActivityWithActivityId:activityId completionHandler:^(void) {} ];
245+
// 1. Create a Default activity
246+
// [LiveActivityController createDefaultActivityWithActivityId:activityId ];
247+
// 2. Create non-OneSignal-aware activity
248+
// [LiveActivityController createActivityWithActivityId:activityId completionHandler:^(void) {} ];
249+
// 3. Create OneSignal-aware activity
250+
[LiveActivityController createOneSignalAwareActivityWithActivityId:activityId];
247251
}
248252
} else {
249253
NSLog(@"Must use iOS 13 or later for swift concurrency which is required for [LiveActivityController createActivityWithCompletionHandler...");

iOS_SDK/OneSignalDevApp/OneSignalWidgetExtension/OneSignalWidgetExtensionLiveActivity.swift

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,11 @@ import OneSignalLiveActivities
5252
}
5353
Spacer()
5454
}
55+
.onesignalWidgetURL(URL(string: "https://example.com/page?param1=value1&param2=value2#section"), context: context)
56+
// .widgetURL(URL(string: "myapp://product/12345"))
5557
.activitySystemActionForegroundColor(.black)
5658
.activityBackgroundTint(.white)
57-
} dynamicIsland: { _ in
59+
} dynamicIsland: { context in
5860
DynamicIsland {
5961
// Expanded UI goes here. Compose the expanded UI through
6062
// various regions, like leading/trailing/center/bottom
@@ -75,7 +77,8 @@ import OneSignalLiveActivities
7577
} minimal: {
7678
Text("Min")
7779
}
78-
.widgetURL(URL(string: "http://www.apple.com"))
80+
.onesignalWidgetURL(URL(string: "https://example.com/page?param1=value1&param2=value2#section"), context: context)
81+
// .widgetURL(URL(string: "myapp://product/12345"))
7982
.keylineTint(Color.red)
8083
}
8184
}
@@ -118,7 +121,8 @@ import OneSignalLiveActivities
118121
.padding([.all], 20)
119122
.activitySystemActionForegroundColor(.black)
120123
.activityBackgroundTint(.white)
121-
} dynamicIsland: { _ in
124+
.onesignalWidgetURL(URL(string: "https://example.com/page?param1=value1&param2=value2#section"), context: context)
125+
} dynamicIsland: { context in
122126
DynamicIsland {
123127
// Expanded UI goes here. Compose the expanded UI through
124128
// various regions, like leading/trailing/center/bottom
@@ -140,6 +144,7 @@ import OneSignalLiveActivities
140144
Text("Min")
141145
}
142146
.keylineTint(Color.red)
147+
.onesignalWidgetURL(URL(string: "https://example.com/page?param1=value1&param2=value2#section"), context: context)
143148
}
144149
}
145150
}
@@ -233,7 +238,8 @@ struct DefaultOneSignalLiveActivityWidget: Widget {
233238
.padding([.all], 20)
234239
.activitySystemActionForegroundColor(.black)
235240
.activityBackgroundTint(.white)
236-
} dynamicIsland: { _ in
241+
.onesignalWidgetURL(URL(string: "https://example.com/page?param1=value1&param2=value2#section"), context: context)
242+
} dynamicIsland: { context in
237243
DynamicIsland {
238244
// Expanded UI goes here. Compose the expanded UI through
239245
// various regions, like leading/trailing/center/bottom
@@ -255,6 +261,7 @@ struct DefaultOneSignalLiveActivityWidget: Widget {
255261
Text("Min")
256262
}
257263
.keylineTint(Color.red)
264+
.onesignalWidgetURL(URL(string: "https://example.com/page?param1=value1&param2=value2#section"), context: context)
258265
}
259266
}
260267
}

iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,15 @@
6969
3C14E39F2AFAE39B006ED053 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 3C14E39E2AFAE39B006ED053 /* PrivacyInfo.xcprivacy */; };
7070
3C14E3A12AFAE461006ED053 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 3C14E3A02AFAE461006ED053 /* PrivacyInfo.xcprivacy */; };
7171
3C14E3A42AFAE54C006ED053 /* OneSignalSwiftInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEC08AFF2947D4E900C81DA3 /* OneSignalSwiftInterface.swift */; };
72+
3C19C6322E919F0C00D6731E /* OSRequestLiveActivityClicked.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C19C6312E919F0C00D6731E /* OSRequestLiveActivityClicked.swift */; };
7273
3C24B0EC2BD09D7A0052E771 /* OneSignalCoreObjCTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C24B0EB2BD09D7A0052E771 /* OneSignalCoreObjCTests.m */; };
7374
3C277D7E2BD76E0000857606 /* OSIdentityModelRepo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C277D7D2BD76E0000857606 /* OSIdentityModelRepo.swift */; };
7475
3C2C7DC8288F3C020020F9AE /* OSSubscriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C2C7DC7288F3C020020F9AE /* OSSubscriptionModel.swift */; };
7576
3C2D8A5928B4C4E300BE41F6 /* OSDelta.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C2D8A5828B4C4E300BE41F6 /* OSDelta.swift */; };
7677
3C2DB2F12DE6CB5E0006B905 /* OneSignalBadgeHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C2DB2EF2DE6CB5E0006B905 /* OneSignalBadgeHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; };
7778
3C2DB2F22DE6CB5E0006B905 /* OneSignalBadgeHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C2DB2F02DE6CB5E0006B905 /* OneSignalBadgeHelpers.m */; };
79+
3C3D34E92E95EAA5006A2924 /* LiveActivityConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C3D34E82E95EAA5006A2924 /* LiveActivityConstants.swift */; };
80+
3C3D8D782E92DB7500C3E977 /* OSLiveActivityViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C3D8D772E92DB7500C3E977 /* OSLiveActivityViewExtensions.swift */; };
7881
3C44673E296D099D0039A49E /* OneSignalMobileProvision.m in Sources */ = {isa = PBXBuildFile; fileRef = 912411FD1E73342200E41FD7 /* OneSignalMobileProvision.m */; };
7982
3C44673F296D09CC0039A49E /* OneSignalMobileProvision.h in Headers */ = {isa = PBXBuildFile; fileRef = 912411FC1E73342200E41FD7 /* OneSignalMobileProvision.h */; settings = {ATTRIBUTES = (Public, ); }; };
8083
3C448B9D2936ADFD002F96BC /* OSBackgroundTaskHandlerImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C448B9B2936ADFD002F96BC /* OSBackgroundTaskHandlerImpl.h */; };
@@ -97,6 +100,7 @@
97100
3C6299A72BEEA41900649187 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 3C6299A62BEEA40100649187 /* PrivacyInfo.xcprivacy */; };
98101
3C6299A92BEEA46C00649187 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 3C6299A82BEEA46C00649187 /* PrivacyInfo.xcprivacy */; };
99102
3C6299AB2BEEA4C000649187 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 3C6299AA2BEEA4C000649187 /* PrivacyInfo.xcprivacy */; };
103+
3C64C3322F1066D700693230 /* LiveActivitiesManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C64C3312F1066D700693230 /* LiveActivitiesManagerTests.swift */; };
100104
3C67F77A2BEB2B710085A0F0 /* SwitchUserIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C67F7792BEB2B710085A0F0 /* SwitchUserIntegrationTests.swift */; };
101105
3C7021E32ECF0821001768C6 /* OneSignalFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E2400381D4FFC31008BDE70 /* OneSignalFramework.framework */; };
102106
3C7021E42ECF0821001768C6 /* OneSignalFramework.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3E2400381D4FFC31008BDE70 /* OneSignalFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
@@ -1297,6 +1301,7 @@
12971301
3C11518C289AF5E800565C41 /* OSModelChangedHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSModelChangedHandler.swift; sourceTree = "<group>"; };
12981302
3C14E39E2AFAE39B006ED053 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
12991303
3C14E3A02AFAE461006ED053 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
1304+
3C19C6312E919F0C00D6731E /* OSRequestLiveActivityClicked.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSRequestLiveActivityClicked.swift; sourceTree = "<group>"; };
13001305
3C24B0EA2BD09D790052E771 /* OneSignalCoreTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OneSignalCoreTests-Bridging-Header.h"; sourceTree = "<group>"; };
13011306
3C24B0EB2BD09D7A0052E771 /* OneSignalCoreObjCTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OneSignalCoreObjCTests.m; sourceTree = "<group>"; };
13021307
3C277D7D2BD76E0000857606 /* OSIdentityModelRepo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSIdentityModelRepo.swift; sourceTree = "<group>"; };
@@ -1305,6 +1310,8 @@
13051310
3C2D8A5828B4C4E300BE41F6 /* OSDelta.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSDelta.swift; sourceTree = "<group>"; };
13061311
3C2DB2EF2DE6CB5E0006B905 /* OneSignalBadgeHelpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OneSignalBadgeHelpers.h; sourceTree = "<group>"; };
13071312
3C2DB2F02DE6CB5E0006B905 /* OneSignalBadgeHelpers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OneSignalBadgeHelpers.m; sourceTree = "<group>"; };
1313+
3C3D34E82E95EAA5006A2924 /* LiveActivityConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveActivityConstants.swift; sourceTree = "<group>"; };
1314+
3C3D8D772E92DB7500C3E977 /* OSLiveActivityViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSLiveActivityViewExtensions.swift; sourceTree = "<group>"; };
13081315
3C448B9B2936ADFD002F96BC /* OSBackgroundTaskHandlerImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSBackgroundTaskHandlerImpl.h; sourceTree = "<group>"; };
13091316
3C448B9C2936ADFD002F96BC /* OSBackgroundTaskHandlerImpl.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OSBackgroundTaskHandlerImpl.m; sourceTree = "<group>"; };
13101317
3C448BA12936B474002F96BC /* OSBackgroundTaskManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSBackgroundTaskManager.swift; sourceTree = "<group>"; };
@@ -1321,6 +1328,7 @@
13211328
3C6299A62BEEA40100649187 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
13221329
3C6299A82BEEA46C00649187 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
13231330
3C6299AA2BEEA4C000649187 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
1331+
3C64C3312F1066D700693230 /* LiveActivitiesManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveActivitiesManagerTests.swift; sourceTree = "<group>"; };
13241332
3C67F7792BEB2B710085A0F0 /* SwitchUserIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwitchUserIntegrationTests.swift; sourceTree = "<group>"; };
13251333
3C7021E72ECF0CF3001768C6 /* OneSignalInAppMessagesTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OneSignalInAppMessagesTests-Bridging-Header.h"; sourceTree = "<group>"; };
13261334
3C7021E82ECF0CF4001768C6 /* IAMIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IAMIntegrationTests.swift; sourceTree = "<group>"; };
@@ -2338,6 +2346,7 @@
23382346
3CFA8F472E9087DB00201FE5 /* OSRequestSetUpdateToken.swift */,
23392347
3CFA8F452E9087DB00201FE5 /* OSRequestRemoveUpdateToken.swift */,
23402348
3CFA8F5A2E9091A200201FE5 /* OSRequestLiveActivityReceiveReceipts.swift */,
2349+
3C19C6312E919F0C00D6731E /* OSRequestLiveActivityClicked.swift */,
23412350
);
23422351
path = Requests;
23432352
sourceTree = "<group>";
@@ -2349,8 +2358,10 @@
23492358
3CFA8F482E9087DB00201FE5 /* Requests */,
23502359
3CFA8F4B2E9087DB00201FE5 /* OneSignalLiveActivitiesManagerImpl.swift */,
23512360
3CFA8F4C2E9087DB00201FE5 /* OneSignalLiveActivityAttributes.swift */,
2361+
3C3D8D772E92DB7500C3E977 /* OSLiveActivityViewExtensions.swift */,
23522362
3CFA8F4D2E9087DB00201FE5 /* OSLiveActivitiesExtension.swift */,
23532363
3CFA8F492E9087DB00201FE5 /* AnyCodable.swift */,
2364+
3C3D34E82E95EAA5006A2924 /* LiveActivityConstants.swift */,
23542365
3CFA8F4A2E9087DB00201FE5 /* DefaultLiveActivityAttributes.swift */,
23552366
);
23562367
path = Source;
@@ -2428,6 +2439,7 @@
24282439
isa = PBXGroup;
24292440
children = (
24302441
4735424C2B8F93340016DB4C /* OSLiveActivitiesExecutorTests.swift */,
2442+
3C64C3312F1066D700693230 /* LiveActivitiesManagerTests.swift */,
24312443
47278E462BD92B4B00562820 /* DefaultLiveActivityAttributesTests.swift */,
24322444
);
24332445
path = OneSignalLiveActivitiesTests;
@@ -4431,6 +4443,7 @@
44314443
buildActionMask = 2147483647;
44324444
files = (
44334445
4735424D2B8F93340016DB4C /* OSLiveActivitiesExecutorTests.swift in Sources */,
4446+
3C64C3322F1066D700693230 /* LiveActivitiesManagerTests.swift in Sources */,
44344447
47278E472BD92B4B00562820 /* DefaultLiveActivityAttributesTests.swift in Sources */,
44354448
);
44364449
runOnlyForDeploymentPostprocessing = 0;
@@ -4440,13 +4453,16 @@
44404453
buildActionMask = 2147483647;
44414454
files = (
44424455
3CFA8F4F2E9087DB00201FE5 /* AnyCodable.swift in Sources */,
4456+
3C3D8D782E92DB7500C3E977 /* OSLiveActivityViewExtensions.swift in Sources */,
4457+
3C3D34E92E95EAA5006A2924 /* LiveActivityConstants.swift in Sources */,
44434458
3CFA8F502E9087DB00201FE5 /* OSLiveActivitiesExecutor.swift in Sources */,
44444459
3CFA8F512E9087DB00201FE5 /* DefaultLiveActivityAttributes.swift in Sources */,
44454460
3CFA8F522E9087DB00201FE5 /* OSRequestSetStartToken.swift in Sources */,
44464461
3CFA8F532E9087DB00201FE5 /* OSRequestRemoveStartToken.swift in Sources */,
44474462
3CFA8F542E9087DB00201FE5 /* OSLiveActivitiesExtension.swift in Sources */,
44484463
3CFA8F552E9087DB00201FE5 /* OneSignalLiveActivitiesManagerImpl.swift in Sources */,
44494464
3CFA8F562E9087DB00201FE5 /* OSRequestSetUpdateToken.swift in Sources */,
4465+
3C19C6322E919F0C00D6731E /* OSRequestLiveActivityClicked.swift in Sources */,
44504466
3CFA8F572E9087DB00201FE5 /* OSRequestRemoveUpdateToken.swift in Sources */,
44514467
3CFA8F582E9087DB00201FE5 /* OSLiveActivityRequest.swift in Sources */,
44524468
3CFA8F592E9087DB00201FE5 /* OneSignalLiveActivityAttributes.swift in Sources */,

iOS_SDK/OneSignalSDK/OneSignalCore/Source/OneSignalCommonDefines.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,5 +365,6 @@ typedef enum {GET, POST, HEAD, PUT, DELETE, OPTIONS, CONNECT, TRACE, PATCH} HTTP
365365
#define OS_LIVE_ACTIVITIES_EXECUTOR_UPDATE_TOKENS_KEY @"OS_LIVE_ACTIVITIES_EXECUTOR_UPDATE_TOKENS_KEY"
366366
#define OS_LIVE_ACTIVITIES_EXECUTOR_START_TOKENS_KEY @"OS_LIVE_ACTIVITIES_EXECUTOR_START_TOKENS_KEY"
367367
#define OS_LIVE_ACTIVITIES_EXECUTOR_RECEIVE_RECEIPTS_KEY @"OS_LIVE_ACTIVITIES_EXECUTOR_RECEIVE_RECEIPTS_KEY"
368+
#define OS_LIVE_ACTIVITIES_EXECUTOR_CLICKED_KEY @"OS_LIVE_ACTIVITIES_EXECUTOR_CLICKED_KEY"
368369

369370
#endif /* OneSignalCommonDefines_h */

iOS_SDK/OneSignalSDK/OneSignalLiveActivities/Source/Executors/OSLiveActivitiesExecutor.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,21 @@ class ReceiveReceiptsRequestCache: RequestCache {
123123
}
124124
}
125125

126+
class ClickedRequestCache: RequestCache {
127+
// Keep click event requests for up to 30 days.
128+
static let OneMonthInSeconds = TimeInterval(60 * 60 * 24 * 30)
129+
130+
init() {
131+
super.init(cacheKey: OS_LIVE_ACTIVITIES_EXECUTOR_CLICKED_KEY, ttl: ClickedRequestCache.OneMonthInSeconds)
132+
}
133+
}
134+
126135
class OSLiveActivitiesExecutor: OSPushSubscriptionObserver {
127136
// The currently tracked update and start tokens (key) and their associated request (value). THESE ARE NOT THREAD SAFE
128137
let updateTokens: UpdateRequestCache = UpdateRequestCache()
129138
let startTokens: StartRequestCache = StartRequestCache()
130139
let receiveReceipts: ReceiveReceiptsRequestCache = ReceiveReceiptsRequestCache()
140+
let clickEvents: ClickedRequestCache = ClickedRequestCache()
131141

132142
// The live activities request dispatch queue, serial. This synchronizes access to `updateTokens` and `startTokens`.
133143
private var requestDispatch: OSDispatchQueue
@@ -193,13 +203,16 @@ class OSLiveActivitiesExecutor: OSPushSubscriptionObserver {
193203
block(self.startTokens)
194204
block(self.updateTokens)
195205
block(self.receiveReceipts)
206+
block(self.clickEvents)
196207
}
197208

198209
private func getCache(_ request: OSLiveActivityRequest) -> RequestCache {
199210
if request is OSLiveActivityUpdateTokenRequest {
200211
return self.updateTokens
201212
} else if request is OSLiveActivityStartTokenRequest {
202213
return self.startTokens
214+
} else if request is OSRequestLiveActivityClicked {
215+
return self.clickEvents
203216
}
204217

205218
return self.receiveReceipts
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
Modified MIT License
3+
4+
Copyright 2025 OneSignal
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
1. The above copyright notice and this permission notice shall be included in
14+
all copies or substantial portions of the Software.
15+
16+
2. All copies of substantial portions of the Software may only be used in connection
17+
with services provided by OneSignal.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
THE SOFTWARE.
26+
*/
27+
28+
/// Constants used throughout the OneSignalLiveActivities module
29+
enum LiveActivityConstants {
30+
/// URL components for OneSignal click tracking
31+
enum Tracking {
32+
static let scheme = "onesignal-liveactivity"
33+
static let host = "track"
34+
static let clickPath = "/click"
35+
static let clickId = "clickId"
36+
static let activityId = "activityId"
37+
static let activityType = "activityType"
38+
static let notificationId = "notificationId"
39+
static let redirect = "redirect"
40+
}
41+
}

0 commit comments

Comments
 (0)