Skip to content

Commit 67d7d9d

Browse files
committed
Add request for Click Events
This is the skeleton, we still need to finalize the path and parameters
1 parent 2a2d695 commit 67d7d9d

File tree

4 files changed

+122
-0
lines changed

4 files changed

+122
-0
lines changed

iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
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 */; };
@@ -1251,6 +1252,7 @@
12511252
3C11518C289AF5E800565C41 /* OSModelChangedHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSModelChangedHandler.swift; sourceTree = "<group>"; };
12521253
3C14E39E2AFAE39B006ED053 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
12531254
3C14E3A02AFAE461006ED053 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
1255+
3C19C6312E919F0C00D6731E /* OSRequestLiveActivityClicked.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSRequestLiveActivityClicked.swift; sourceTree = "<group>"; };
12541256
3C24B0EA2BD09D790052E771 /* OneSignalCoreTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OneSignalCoreTests-Bridging-Header.h"; sourceTree = "<group>"; };
12551257
3C24B0EB2BD09D7A0052E771 /* OneSignalCoreObjCTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OneSignalCoreObjCTests.m; sourceTree = "<group>"; };
12561258
3C277D7D2BD76E0000857606 /* OSIdentityModelRepo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSIdentityModelRepo.swift; sourceTree = "<group>"; };
@@ -2258,6 +2260,7 @@
22582260
3CFA8F472E9087DB00201FE5 /* OSRequestSetUpdateToken.swift */,
22592261
3CFA8F452E9087DB00201FE5 /* OSRequestRemoveUpdateToken.swift */,
22602262
3CFA8F5A2E9091A200201FE5 /* OSRequestLiveActivityReceiveReceipts.swift */,
2263+
3C19C6312E919F0C00D6731E /* OSRequestLiveActivityClicked.swift */,
22612264
);
22622265
path = Requests;
22632266
sourceTree = "<group>";
@@ -4311,6 +4314,7 @@
43114314
3CFA8F542E9087DB00201FE5 /* OSLiveActivitiesExtension.swift in Sources */,
43124315
3CFA8F552E9087DB00201FE5 /* OneSignalLiveActivitiesManagerImpl.swift in Sources */,
43134316
3CFA8F562E9087DB00201FE5 /* OSRequestSetUpdateToken.swift in Sources */,
4317+
3C19C6322E919F0C00D6731E /* OSRequestLiveActivityClicked.swift in Sources */,
43144318
3CFA8F572E9087DB00201FE5 /* OSRequestRemoveUpdateToken.swift in Sources */,
43154319
3CFA8F582E9087DB00201FE5 /* OSLiveActivityRequest.swift in Sources */,
43164320
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: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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+
import OneSignalCore
29+
import OneSignalUser
30+
31+
class OSRequestLiveActivityClicked: OneSignalRequest, OSLiveActivityRequest {
32+
override var description: String { return "(OSRequestLiveActivityClicked) key:\(key) requestSuccessful:\(requestSuccessful) activityType:\(activityType) activityId:\(activityId)" }
33+
34+
var key: String // UUID representing this unique click
35+
var activityType: String
36+
var activityId: String
37+
var requestSuccessful: Bool
38+
var shouldForgetWhenSuccessful: Bool = true
39+
40+
func prepareForExecution() -> Bool {
41+
guard let appId = OneSignalConfigManager.getAppId() else {
42+
OneSignalLog.onesignalLog(.LL_DEBUG, message: "Cannot generate the OSRequestLiveActivityClicked due to null app ID.")
43+
return false
44+
}
45+
46+
guard let subscriptionId = OneSignalUserManagerImpl.sharedInstance.pushSubscriptionId else {
47+
OneSignalLog.onesignalLog(.LL_DEBUG, message: "Cannot generate the OSRequestLiveActivityClicked due to null subscription ID.")
48+
return false
49+
}
50+
51+
// TODO: ⚠️ What is the path, method, and parameters
52+
// TODO: ⚠️ Need to guard for encoding activity strings if in path
53+
// TODO: ⚠️ Timestamp since we are caching? Same for received event.
54+
self.path = "foo/bar/\(activityId)/click"
55+
self.parameters = [
56+
"app_id": appId,
57+
"player_id": subscriptionId,
58+
"device_type": 0,
59+
"live_activity_id": activityId,
60+
"live_activity_type": activityType,
61+
"click_id": key
62+
]
63+
self.method = POST
64+
65+
return true
66+
}
67+
68+
func supersedes(_ existing: any OSLiveActivityRequest) -> Bool {
69+
return false
70+
}
71+
72+
init(key: String, activityType: String, activityId: String) {
73+
self.key = key
74+
self.activityType = activityType
75+
self.activityId = activityId
76+
self.requestSuccessful = false
77+
super.init()
78+
}
79+
80+
func encode(with coder: NSCoder) {
81+
coder.encode(key, forKey: "key")
82+
coder.encode(activityType, forKey: "activityType")
83+
coder.encode(activityId, forKey: "activityId")
84+
coder.encode(requestSuccessful, forKey: "requestSuccessful")
85+
coder.encode(timestamp, forKey: "timestamp")
86+
}
87+
88+
required init?(coder: NSCoder) {
89+
guard
90+
let key = coder.decodeObject(forKey: "key") as? String,
91+
let activityType = coder.decodeObject(forKey: "activityType") as? String,
92+
let activityId = coder.decodeObject(forKey: "activityId") as? String,
93+
let timestamp = coder.decodeObject(forKey: "timestamp") as? Date
94+
else {
95+
return nil
96+
}
97+
self.key = key
98+
self.activityType = activityType
99+
self.activityId = activityId
100+
self.requestSuccessful = coder.decodeBool(forKey: "requestSuccessful")
101+
super.init()
102+
self.timestamp = timestamp
103+
}
104+
}

0 commit comments

Comments
 (0)