@onesignal/capacitor-plugin 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/OneSignalCapacitorPlugin.podspec +5 -1
- package/Package.swift +12 -1
- package/README.md +50 -16
- package/android/src/main/kotlin/com/onesignal/capacitor/OneSignalCapacitorPlugin.kt +146 -77
- package/dist/index.d.ts +17 -7
- package/dist/index.js +59 -28
- package/ios/Sources/OSCapacitorLaunchOptions/OSCapacitorLaunchOptions.m +89 -0
- package/ios/Sources/OSCapacitorLaunchOptions/include/OSCapacitorLaunchOptions.h +35 -0
- package/ios/Sources/OneSignalCapacitorPlugin/OneSignalCapacitorPlugin.swift +158 -40
- package/package.json +3 -3
|
@@ -10,7 +10,11 @@ Pod::Spec.new do |s|
|
|
|
10
10
|
s.homepage = package['homepage']
|
|
11
11
|
s.author = 'OneSignal'
|
|
12
12
|
s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
|
|
13
|
-
s.source_files =
|
|
13
|
+
s.source_files = [
|
|
14
|
+
'ios/Sources/OneSignalCapacitorPlugin/**/*.swift',
|
|
15
|
+
'ios/Sources/OSCapacitorLaunchOptions/**/*.{h,m}'
|
|
16
|
+
]
|
|
17
|
+
s.public_header_files = 'ios/Sources/OSCapacitorLaunchOptions/include/*.h'
|
|
14
18
|
|
|
15
19
|
s.ios.deployment_target = '14.0'
|
|
16
20
|
s.swift_version = '5.9'
|
package/Package.swift
CHANGED
|
@@ -16,6 +16,16 @@ let package = Package(
|
|
|
16
16
|
.package(url: "https://github.com/OneSignal/OneSignal-XCFramework", from: "5.0.0")
|
|
17
17
|
],
|
|
18
18
|
targets: [
|
|
19
|
+
// Obj-C helper that captures the iOS launchOptions dictionary at
|
|
20
|
+
// process start (via +load + UIApplicationDidFinishLaunchingNotification)
|
|
21
|
+
// so cold-start notification taps are still available when the JS
|
|
22
|
+
// layer initializes the plugin later. SPM cannot mix Swift and Obj-C
|
|
23
|
+
// in the same target, so this lives as its own target.
|
|
24
|
+
.target(
|
|
25
|
+
name: "OSCapacitorLaunchOptions",
|
|
26
|
+
path: "ios/Sources/OSCapacitorLaunchOptions",
|
|
27
|
+
publicHeadersPath: "include"
|
|
28
|
+
),
|
|
19
29
|
.target(
|
|
20
30
|
name: "OnesignalCapacitorPlugin",
|
|
21
31
|
dependencies: [
|
|
@@ -28,7 +38,8 @@ let package = Package(
|
|
|
28
38
|
.product(name: "OneSignalFramework", package: "OneSignal-XCFramework"),
|
|
29
39
|
.product(name: "OneSignalInAppMessages", package: "OneSignal-XCFramework"),
|
|
30
40
|
.product(name: "OneSignalLocation", package: "OneSignal-XCFramework"),
|
|
31
|
-
.product(name: "OneSignalExtension", package: "OneSignal-XCFramework")
|
|
41
|
+
.product(name: "OneSignalExtension", package: "OneSignal-XCFramework"),
|
|
42
|
+
"OSCapacitorLaunchOptions"
|
|
32
43
|
],
|
|
33
44
|
path: "ios/Sources/OneSignalCapacitorPlugin"
|
|
34
45
|
)
|
package/README.md
CHANGED
|
@@ -24,13 +24,13 @@ See the `examples/demo` directory for a full working example.
|
|
|
24
24
|
|
|
25
25
|
<docgen-index>
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
* [`initialize(...)`](#initialize)
|
|
28
|
+
* [`login(...)`](#login)
|
|
29
|
+
* [`logout()`](#logout)
|
|
30
|
+
* [`setConsentRequired(...)`](#setconsentrequired)
|
|
31
|
+
* [`setConsentGiven(...)`](#setconsentgiven)
|
|
32
|
+
* [Interfaces](#interfaces)
|
|
33
|
+
* [Type Aliases](#type-aliases)
|
|
34
34
|
|
|
35
35
|
</docgen-index>
|
|
36
36
|
|
|
@@ -51,7 +51,8 @@ Initialize the SDK with your OneSignal app ID. Call during app startup.
|
|
|
51
51
|
| ----------- | ------------------- |
|
|
52
52
|
| **`appId`** | <code>string</code> |
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
--------------------
|
|
55
|
+
|
|
55
56
|
|
|
56
57
|
### login(...)
|
|
57
58
|
|
|
@@ -65,7 +66,8 @@ Log in to OneSignal as the user identified by `externalId`, switching the user c
|
|
|
65
66
|
| ---------------- | ------------------- |
|
|
66
67
|
| **`externalId`** | <code>string</code> |
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
--------------------
|
|
70
|
+
|
|
69
71
|
|
|
70
72
|
### logout()
|
|
71
73
|
|
|
@@ -75,7 +77,8 @@ logout() => Promise<void>
|
|
|
75
77
|
|
|
76
78
|
Log out the current user. The SDK will reference a new device-scoped user.
|
|
77
79
|
|
|
78
|
-
|
|
80
|
+
--------------------
|
|
81
|
+
|
|
79
82
|
|
|
80
83
|
### setConsentRequired(...)
|
|
81
84
|
|
|
@@ -89,7 +92,8 @@ Set whether user privacy consent is required before sending data to OneSignal. C
|
|
|
89
92
|
| -------------- | -------------------- |
|
|
90
93
|
| **`required`** | <code>boolean</code> |
|
|
91
94
|
|
|
92
|
-
|
|
95
|
+
--------------------
|
|
96
|
+
|
|
93
97
|
|
|
94
98
|
### setConsentGiven(...)
|
|
95
99
|
|
|
@@ -103,10 +107,12 @@ Indicate whether the user has granted privacy consent.
|
|
|
103
107
|
| ------------- | -------------------- |
|
|
104
108
|
| **`granted`** | <code>boolean</code> |
|
|
105
109
|
|
|
106
|
-
|
|
110
|
+
--------------------
|
|
111
|
+
|
|
107
112
|
|
|
108
113
|
### Interfaces
|
|
109
114
|
|
|
115
|
+
|
|
110
116
|
#### OneSignalDebugAPI
|
|
111
117
|
|
|
112
118
|
Debug helpers exposed via `OneSignal.Debug`.
|
|
@@ -116,6 +122,7 @@ Debug helpers exposed via `OneSignal.Debug`.
|
|
|
116
122
|
| **setLogLevel** | (logLevel: <a href="#loglevel">LogLevel</a>) => void | Set the log level printed to LogCat (Android) or the Xcode console (iOS). |
|
|
117
123
|
| **setAlertLevel** | (visualLogLevel: <a href="#loglevel">LogLevel</a>) => void | Set the log level shown to the user as alert dialogs. |
|
|
118
124
|
|
|
125
|
+
|
|
119
126
|
#### OneSignalUserAPI
|
|
120
127
|
|
|
121
128
|
Current-user operations exposed via `OneSignal.User`.
|
|
@@ -146,12 +153,14 @@ Current-user operations exposed via `OneSignal.User`.
|
|
|
146
153
|
| **getExternalId** | () => Promise<string \| null> | Get the external ID set via `login`, or null if the user is anonymous. |
|
|
147
154
|
| **trackEvent** | (name: string, properties?: object \| undefined) => Promise<void> | Track a custom event with an optional set of JSON-serializable properties. |
|
|
148
155
|
|
|
156
|
+
|
|
149
157
|
#### UserChangedState
|
|
150
158
|
|
|
151
159
|
| Prop | Type |
|
|
152
160
|
| ------------- | ----------------------------------------------- |
|
|
153
161
|
| **`current`** | <code><a href="#userstate">UserState</a></code> |
|
|
154
162
|
|
|
163
|
+
|
|
155
164
|
#### UserState
|
|
156
165
|
|
|
157
166
|
| Prop | Type |
|
|
@@ -159,6 +168,7 @@ Current-user operations exposed via `OneSignal.User`.
|
|
|
159
168
|
| **`onesignalId`** | <code>string</code> |
|
|
160
169
|
| **`externalId`** | <code>string</code> |
|
|
161
170
|
|
|
171
|
+
|
|
162
172
|
#### OneSignalPushSubscriptionAPI
|
|
163
173
|
|
|
164
174
|
Push subscription state and controls exposed via `OneSignal.User.pushSubscription`.
|
|
@@ -173,6 +183,7 @@ Push subscription state and controls exposed via `OneSignal.User.pushSubscriptio
|
|
|
173
183
|
| **optIn** | () => Promise<void> | Opt the user in to push notifications. Prompts for permission if needed. |
|
|
174
184
|
| **optOut** | () => Promise<void> | Opt the user out of push notifications on this device. |
|
|
175
185
|
|
|
186
|
+
|
|
176
187
|
#### PushSubscriptionChangedState
|
|
177
188
|
|
|
178
189
|
| Prop | Type |
|
|
@@ -180,6 +191,7 @@ Push subscription state and controls exposed via `OneSignal.User.pushSubscriptio
|
|
|
180
191
|
| **`previous`** | <code><a href="#pushsubscriptionstate">PushSubscriptionState</a></code> |
|
|
181
192
|
| **`current`** | <code><a href="#pushsubscriptionstate">PushSubscriptionState</a></code> |
|
|
182
193
|
|
|
194
|
+
|
|
183
195
|
#### PushSubscriptionState
|
|
184
196
|
|
|
185
197
|
| Prop | Type |
|
|
@@ -188,6 +200,7 @@ Push subscription state and controls exposed via `OneSignal.User.pushSubscriptio
|
|
|
188
200
|
| **`token`** | <code>string</code> |
|
|
189
201
|
| **`optedIn`** | <code>boolean</code> |
|
|
190
202
|
|
|
203
|
+
|
|
191
204
|
#### OneSignalNotificationsAPI
|
|
192
205
|
|
|
193
206
|
Notification permission and event handling exposed via `OneSignal.Notifications`.
|
|
@@ -205,6 +218,7 @@ Notification permission and event handling exposed via `OneSignal.Notifications`
|
|
|
205
218
|
| **removeNotification** | (id: number) => Promise<void> | Android only. Cancel a single notification by its Android notification ID. |
|
|
206
219
|
| **removeGroupedNotifications** | (id: string) => Promise<void> | Android only. Cancel a group of notifications by group key. |
|
|
207
220
|
|
|
221
|
+
|
|
208
222
|
#### NotificationClickEvent
|
|
209
223
|
|
|
210
224
|
| Prop | Type |
|
|
@@ -212,6 +226,7 @@ Notification permission and event handling exposed via `OneSignal.Notifications`
|
|
|
212
226
|
| **`result`** | <code><a href="#notificationclickresult">NotificationClickResult</a></code> |
|
|
213
227
|
| **`notification`** | <code>OSNotification</code> |
|
|
214
228
|
|
|
229
|
+
|
|
215
230
|
#### NotificationClickResult
|
|
216
231
|
|
|
217
232
|
| Prop | Type |
|
|
@@ -219,6 +234,7 @@ Notification permission and event handling exposed via `OneSignal.Notifications`
|
|
|
219
234
|
| **`actionId`** | <code>string</code> |
|
|
220
235
|
| **`url`** | <code>string</code> |
|
|
221
236
|
|
|
237
|
+
|
|
222
238
|
#### OneSignalInAppMessagesAPI
|
|
223
239
|
|
|
224
240
|
In-app message triggers and event handling exposed via `OneSignal.InAppMessages`.
|
|
@@ -235,6 +251,7 @@ In-app message triggers and event handling exposed via `OneSignal.InAppMessages`
|
|
|
235
251
|
| **setPaused** | (pause: boolean) => void | Pause or resume the display of in-app messages. |
|
|
236
252
|
| **getPaused** | () => Promise<boolean> | Whether in-app messaging is currently paused. |
|
|
237
253
|
|
|
254
|
+
|
|
238
255
|
#### InAppMessageClickEvent
|
|
239
256
|
|
|
240
257
|
| Prop | Type |
|
|
@@ -242,12 +259,14 @@ In-app message triggers and event handling exposed via `OneSignal.InAppMessages`
|
|
|
242
259
|
| **`message`** | <code><a href="#osinappmessage">OSInAppMessage</a></code> |
|
|
243
260
|
| **`result`** | <code><a href="#inappmessageclickresult">InAppMessageClickResult</a></code> |
|
|
244
261
|
|
|
262
|
+
|
|
245
263
|
#### OSInAppMessage
|
|
246
264
|
|
|
247
265
|
| Prop | Type |
|
|
248
266
|
| --------------- | ------------------- |
|
|
249
267
|
| **`messageId`** | <code>string</code> |
|
|
250
268
|
|
|
269
|
+
|
|
251
270
|
#### InAppMessageClickResult
|
|
252
271
|
|
|
253
272
|
| Prop | Type |
|
|
@@ -257,30 +276,35 @@ In-app message triggers and event handling exposed via `OneSignal.InAppMessages`
|
|
|
257
276
|
| **`url`** | <code>string</code> |
|
|
258
277
|
| **`urlTarget`** | <code><a href="#inappmessageactionurltype">InAppMessageActionUrlType</a></code> |
|
|
259
278
|
|
|
279
|
+
|
|
260
280
|
#### InAppMessageWillDisplayEvent
|
|
261
281
|
|
|
262
282
|
| Prop | Type |
|
|
263
283
|
| ------------- | --------------------------------------------------------- |
|
|
264
284
|
| **`message`** | <code><a href="#osinappmessage">OSInAppMessage</a></code> |
|
|
265
285
|
|
|
286
|
+
|
|
266
287
|
#### InAppMessageDidDisplayEvent
|
|
267
288
|
|
|
268
289
|
| Prop | Type |
|
|
269
290
|
| ------------- | --------------------------------------------------------- |
|
|
270
291
|
| **`message`** | <code><a href="#osinappmessage">OSInAppMessage</a></code> |
|
|
271
292
|
|
|
293
|
+
|
|
272
294
|
#### InAppMessageWillDismissEvent
|
|
273
295
|
|
|
274
296
|
| Prop | Type |
|
|
275
297
|
| ------------- | --------------------------------------------------------- |
|
|
276
298
|
| **`message`** | <code><a href="#osinappmessage">OSInAppMessage</a></code> |
|
|
277
299
|
|
|
300
|
+
|
|
278
301
|
#### InAppMessageDidDismissEvent
|
|
279
302
|
|
|
280
303
|
| Prop | Type |
|
|
281
304
|
| ------------- | --------------------------------------------------------- |
|
|
282
305
|
| **`message`** | <code><a href="#osinappmessage">OSInAppMessage</a></code> |
|
|
283
306
|
|
|
307
|
+
|
|
284
308
|
#### OneSignalSessionAPI
|
|
285
309
|
|
|
286
310
|
Outcome reporting exposed via `OneSignal.Session`.
|
|
@@ -291,6 +315,7 @@ Outcome reporting exposed via `OneSignal.Session`.
|
|
|
291
315
|
| **addUniqueOutcome** | (name: string) => Promise<void> | <a href="#record">Record</a> a unique outcome with the given name against the current session. |
|
|
292
316
|
| **addOutcomeWithValue** | (name: string, value: number) => Promise<void> | <a href="#record">Record</a> an outcome with the given name and value against the current session. |
|
|
293
317
|
|
|
318
|
+
|
|
294
319
|
#### OneSignalLocationAPI
|
|
295
320
|
|
|
296
321
|
Location permission and sharing exposed via `OneSignal.Location`.
|
|
@@ -301,6 +326,7 @@ Location permission and sharing exposed via `OneSignal.Location`.
|
|
|
301
326
|
| **setShared** | (shared: boolean) => void | Enable or disable sharing the device location with OneSignal. |
|
|
302
327
|
| **isShared** | () => Promise<boolean> | Whether the device location is currently shared with OneSignal. |
|
|
303
328
|
|
|
329
|
+
|
|
304
330
|
#### OneSignalLiveActivitiesAPI
|
|
305
331
|
|
|
306
332
|
Live activity controls exposed via `OneSignal.LiveActivities`. iOS only unless noted.
|
|
@@ -314,48 +340,56 @@ Live activity controls exposed via `OneSignal.LiveActivities`. iOS only unless n
|
|
|
314
340
|
| **setupDefault** | (options?: <a href="#liveactivitysetupoptions">LiveActivitySetupOptions</a> \| undefined) => Promise<void> | Set up the OneSignal default live activity, optionally enabling pushToStart/pushToUpdate. |
|
|
315
341
|
| **startDefault** | (activityId: string, attributes: <a href="#record">Record</a><string, unknown>, content: <a href="#record">Record</a><string, unknown>) => Promise<void> | Start a live activity backed by the OneSignal default attributes type. |
|
|
316
342
|
|
|
343
|
+
|
|
317
344
|
### Type Aliases
|
|
318
345
|
|
|
346
|
+
|
|
319
347
|
#### LogLevel
|
|
320
348
|
|
|
321
349
|
<code>(typeof <a href="#loglevel">LogLevel</a>)[keyof typeof LogLevel]</code>
|
|
322
350
|
|
|
351
|
+
|
|
323
352
|
#### Record
|
|
324
353
|
|
|
325
354
|
Construct a type with a set of properties K of type T
|
|
326
355
|
|
|
327
|
-
<code>{
|
|
328
|
-
[P in K]: T;
|
|
329
|
-
}</code>
|
|
356
|
+
<code>{
|
|
330
357
|
[P in K]: T;
|
|
331
358
|
}</code>
|
|
359
|
+
|
|
332
360
|
|
|
333
361
|
#### OSNotificationPermission
|
|
334
362
|
|
|
335
363
|
<code>(typeof <a href="#osnotificationpermission">OSNotificationPermission</a>)[keyof typeof OSNotificationPermission]</code>
|
|
336
364
|
|
|
365
|
+
|
|
337
366
|
#### NotificationEventName
|
|
338
367
|
|
|
339
368
|
<code>'click' | 'foregroundWillDisplay' | 'permissionChange'</code>
|
|
340
369
|
|
|
370
|
+
|
|
341
371
|
#### NotificationEventTypeMap
|
|
342
372
|
|
|
343
373
|
<code>{ click: <a href="#notificationclickevent">NotificationClickEvent</a>; foregroundWillDisplay: NotificationWillDisplayEvent; permissionChange: boolean; }</code>
|
|
344
374
|
|
|
375
|
+
|
|
345
376
|
#### InAppMessageEventName
|
|
346
377
|
|
|
347
378
|
<code>'click' | 'willDisplay' | 'didDisplay' | 'willDismiss' | 'didDismiss'</code>
|
|
348
379
|
|
|
380
|
+
|
|
349
381
|
#### InAppMessageEventTypeMap
|
|
350
382
|
|
|
351
383
|
<code>{ click: <a href="#inappmessageclickevent">InAppMessageClickEvent</a>; willDisplay: <a href="#inappmessagewilldisplayevent">InAppMessageWillDisplayEvent</a>; didDisplay: <a href="#inappmessagediddisplayevent">InAppMessageDidDisplayEvent</a>; willDismiss: <a href="#inappmessagewilldismissevent">InAppMessageWillDismissEvent</a>; didDismiss: <a href="#inappmessagediddismissevent">InAppMessageDidDismissEvent</a>; }</code>
|
|
352
384
|
|
|
385
|
+
|
|
353
386
|
#### InAppMessageActionUrlType
|
|
354
387
|
|
|
355
388
|
<code>'browser' | 'webview' | 'replacement'</code>
|
|
356
389
|
|
|
390
|
+
|
|
357
391
|
#### LiveActivitySetupOptions
|
|
358
392
|
|
|
359
393
|
The setup options for `OneSignal.LiveActivities.setupDefault`.
|
|
360
394
|
|
|
361
|
-
<code>{ /**
|
|
395
|
+
<code>{ /** * When true, OneSignal will listen for pushToStart tokens for the `OneSignalLiveActivityAttributes` structure. */ enablePushToStart: boolean; /** * When true, OneSignal will listen for pushToUpdate tokens for each start live activity that uses the * `OneSignalLiveActivityAttributes` structure. */ enablePushToUpdate: boolean; }</code>
|
|
362
396
|
|
|
363
397
|
</docgen-api>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package com.onesignal.capacitor
|
|
2
2
|
|
|
3
|
+
import android.app.Application
|
|
3
4
|
import com.getcapacitor.JSObject
|
|
4
5
|
import com.getcapacitor.Plugin
|
|
5
6
|
import com.getcapacitor.PluginCall
|
|
@@ -7,6 +8,7 @@ import com.getcapacitor.PluginMethod
|
|
|
7
8
|
import com.getcapacitor.annotation.CapacitorPlugin
|
|
8
9
|
import com.onesignal.OneSignal
|
|
9
10
|
import com.onesignal.common.OneSignalWrapper
|
|
11
|
+
import com.onesignal.core.internal.application.IApplicationService
|
|
10
12
|
import com.onesignal.inAppMessages.IInAppMessageClickEvent
|
|
11
13
|
import com.onesignal.inAppMessages.IInAppMessageClickListener
|
|
12
14
|
import com.onesignal.inAppMessages.IInAppMessageDidDismissEvent
|
|
@@ -24,8 +26,8 @@ import com.onesignal.user.state.IUserStateObserver
|
|
|
24
26
|
import com.onesignal.user.state.UserChangedState
|
|
25
27
|
import com.onesignal.user.subscriptions.IPushSubscriptionObserver
|
|
26
28
|
import com.onesignal.user.subscriptions.PushSubscriptionChangedState
|
|
27
|
-
import kotlinx.coroutines.
|
|
28
|
-
import kotlinx.coroutines.
|
|
29
|
+
import kotlinx.coroutines.MainScope
|
|
30
|
+
import kotlinx.coroutines.cancel
|
|
29
31
|
import kotlinx.coroutines.launch
|
|
30
32
|
import org.json.JSONArray
|
|
31
33
|
import org.json.JSONObject
|
|
@@ -37,11 +39,82 @@ class OneSignalCapacitorPlugin : Plugin(),
|
|
|
37
39
|
IInAppMessageLifecycleListener,
|
|
38
40
|
IInAppMessageClickListener {
|
|
39
41
|
|
|
42
|
+
companion object {
|
|
43
|
+
// Mirror of iOS UNAuthorizationStatus values so the JS layer can use a
|
|
44
|
+
// single permissionNative() return shape across platforms. Android only
|
|
45
|
+
// distinguishes denied/authorized; the iOS-specific notDetermined (0),
|
|
46
|
+
// provisional (3), and ephemeral (4) states do not apply here.
|
|
47
|
+
private const val PERMISSION_DENIED = 1
|
|
48
|
+
private const val PERMISSION_AUTHORIZED = 2
|
|
49
|
+
}
|
|
50
|
+
|
|
40
51
|
private val notificationWillDisplayCache = mutableMapOf<String, INotificationWillDisplayEvent>()
|
|
41
52
|
private val preventDefaultCache = mutableSetOf<String>()
|
|
42
|
-
private var
|
|
53
|
+
private var initialized = false
|
|
54
|
+
|
|
55
|
+
// Class-scoped scope so launched permission/location coroutines are tied
|
|
56
|
+
// to the plugin instance lifetime. Cancelled in handleOnDestroy so a
|
|
57
|
+
// pending permission dialog that resolves after the activity dies cannot
|
|
58
|
+
// call into the dead Capacitor bridge.
|
|
59
|
+
private val pluginScope = MainScope()
|
|
60
|
+
|
|
61
|
+
private val permissionObserver = object : IPermissionObserver {
|
|
62
|
+
override fun onNotificationPermissionChange(permission: Boolean) {
|
|
63
|
+
val ret = JSObject()
|
|
64
|
+
ret.put("permission", permission)
|
|
65
|
+
notifyListeners("permissionChange", ret)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private val pushSubscriptionObserver = object : IPushSubscriptionObserver {
|
|
70
|
+
override fun onPushSubscriptionChange(state: PushSubscriptionChangedState) {
|
|
71
|
+
val ret = JSObject()
|
|
72
|
+
val prev = JSObject()
|
|
73
|
+
prev.put("id", state.previous.id.ifEmpty { JSONObject.NULL })
|
|
74
|
+
prev.put("token", state.previous.token.ifEmpty { JSONObject.NULL })
|
|
75
|
+
prev.put("optedIn", state.previous.optedIn)
|
|
76
|
+
ret.put("previous", prev)
|
|
77
|
+
|
|
78
|
+
val curr = JSObject()
|
|
79
|
+
curr.put("id", state.current.id.ifEmpty { JSONObject.NULL })
|
|
80
|
+
curr.put("token", state.current.token.ifEmpty { JSONObject.NULL })
|
|
81
|
+
curr.put("optedIn", state.current.optedIn)
|
|
82
|
+
ret.put("current", curr)
|
|
83
|
+
|
|
84
|
+
notifyListeners("pushSubscriptionChange", ret)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private val userStateObserver = object : IUserStateObserver {
|
|
89
|
+
override fun onUserStateChange(state: UserChangedState) {
|
|
90
|
+
val ret = JSObject()
|
|
91
|
+
val curr = JSObject()
|
|
92
|
+
curr.put("onesignalId", state.current.onesignalId.ifEmpty { JSONObject.NULL })
|
|
93
|
+
curr.put("externalId", state.current.externalId.ifEmpty { JSONObject.NULL })
|
|
94
|
+
ret.put("current", curr)
|
|
95
|
+
notifyListeners("userStateChange", ret)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
43
98
|
|
|
44
|
-
|
|
99
|
+
override fun handleOnDestroy() {
|
|
100
|
+
// Detach this dead plugin instance so the next plugin instance can
|
|
101
|
+
// receive events; otherwise the SDK keeps firing on this stale
|
|
102
|
+
// instance and skips its unprocessed-click replay queue.
|
|
103
|
+
runCatching {
|
|
104
|
+
OneSignal.Notifications.removePermissionObserver(permissionObserver)
|
|
105
|
+
OneSignal.Notifications.removeForegroundLifecycleListener(this)
|
|
106
|
+
OneSignal.Notifications.removeClickListener(this)
|
|
107
|
+
OneSignal.User.pushSubscription.removeObserver(pushSubscriptionObserver)
|
|
108
|
+
OneSignal.User.removeObserver(userStateObserver)
|
|
109
|
+
OneSignal.InAppMessages.removeLifecycleListener(this)
|
|
110
|
+
OneSignal.InAppMessages.removeClickListener(this)
|
|
111
|
+
}
|
|
112
|
+
pluginScope.cancel()
|
|
113
|
+
// Caches aren't explicitly cleared: GC reclaims them with this
|
|
114
|
+
// instance once the listener removals above run, and runtime size is
|
|
115
|
+
// bounded by consume-on-read in proceedWithWillDisplay/displayNotification.
|
|
116
|
+
super.handleOnDestroy()
|
|
117
|
+
}
|
|
45
118
|
|
|
46
119
|
@PluginMethod
|
|
47
120
|
fun initialize(call: PluginCall) {
|
|
@@ -51,68 +124,56 @@ class OneSignalCapacitorPlugin : Plugin(),
|
|
|
51
124
|
return
|
|
52
125
|
}
|
|
53
126
|
|
|
127
|
+
// initialize() is idempotent: JS may call it multiple times per
|
|
128
|
+
// activity (effect re-runs, hot reload). Listeners are detached in
|
|
129
|
+
// handleOnDestroy and the next plugin instance starts fresh.
|
|
130
|
+
if (initialized) {
|
|
131
|
+
call.resolve()
|
|
132
|
+
return
|
|
133
|
+
}
|
|
134
|
+
initialized = true
|
|
135
|
+
|
|
54
136
|
OneSignalWrapper.sdkType = "capacitor"
|
|
55
|
-
OneSignalWrapper.sdkVersion = "
|
|
137
|
+
OneSignalWrapper.sdkVersion = "010002"
|
|
56
138
|
OneSignal.initWithContext(context, appId)
|
|
57
139
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
notifyListeners("permissionChange", ret)
|
|
63
|
-
}
|
|
64
|
-
})
|
|
140
|
+
// If the SDK was initialized from a non-Activity context (FCM/work
|
|
141
|
+
// managers) before this call, its ALC missed MainActivity.onResume
|
|
142
|
+
// and isInForeground stays false. Forward the missed events now.
|
|
143
|
+
nudgeApplicationServiceForeground()
|
|
65
144
|
|
|
145
|
+
OneSignal.Notifications.addPermissionObserver(permissionObserver)
|
|
66
146
|
OneSignal.Notifications.addForegroundLifecycleListener(this)
|
|
67
147
|
OneSignal.Notifications.addClickListener(this)
|
|
68
|
-
|
|
69
|
-
OneSignal.User.
|
|
70
|
-
override fun onPushSubscriptionChange(state: PushSubscriptionChangedState) {
|
|
71
|
-
val ret = JSObject()
|
|
72
|
-
val prev = JSObject()
|
|
73
|
-
prev.put("id", state.previous.id.ifEmpty { JSONObject.NULL })
|
|
74
|
-
prev.put("token", state.previous.token.ifEmpty { JSONObject.NULL })
|
|
75
|
-
prev.put("optedIn", state.previous.optedIn)
|
|
76
|
-
ret.put("previous", prev)
|
|
77
|
-
|
|
78
|
-
val curr = JSObject()
|
|
79
|
-
curr.put("id", state.current.id.ifEmpty { JSONObject.NULL })
|
|
80
|
-
curr.put("token", state.current.token.ifEmpty { JSONObject.NULL })
|
|
81
|
-
curr.put("optedIn", state.current.optedIn)
|
|
82
|
-
ret.put("current", curr)
|
|
83
|
-
|
|
84
|
-
notifyListeners("pushSubscriptionChange", ret)
|
|
85
|
-
}
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
OneSignal.User.addObserver(object : IUserStateObserver {
|
|
89
|
-
override fun onUserStateChange(state: UserChangedState) {
|
|
90
|
-
val ret = JSObject()
|
|
91
|
-
val curr = JSObject()
|
|
92
|
-
curr.put("onesignalId", state.current.onesignalId.ifEmpty { JSONObject.NULL })
|
|
93
|
-
curr.put("externalId", state.current.externalId.ifEmpty { JSONObject.NULL })
|
|
94
|
-
ret.put("current", curr)
|
|
95
|
-
notifyListeners("userStateChange", ret)
|
|
96
|
-
}
|
|
97
|
-
})
|
|
98
|
-
|
|
148
|
+
OneSignal.User.pushSubscription.addObserver(pushSubscriptionObserver)
|
|
149
|
+
OneSignal.User.addObserver(userStateObserver)
|
|
99
150
|
OneSignal.InAppMessages.addLifecycleListener(this)
|
|
100
151
|
OneSignal.InAppMessages.addClickListener(this)
|
|
101
152
|
|
|
102
|
-
pendingClickEvent?.let { event ->
|
|
103
|
-
val ret = JSObject()
|
|
104
|
-
val clickResult = JSObject()
|
|
105
|
-
clickResult.put("actionId", event.result.actionId)
|
|
106
|
-
clickResult.put("url", event.result.url)
|
|
107
|
-
ret.put("result", clickResult)
|
|
108
|
-
ret.put("notification", JSObject(event.notification.rawPayload))
|
|
109
|
-
notifyListeners("notificationClick", ret)
|
|
110
|
-
pendingClickEvent = null
|
|
111
|
-
}
|
|
112
|
-
|
|
113
153
|
call.resolve()
|
|
114
154
|
}
|
|
115
155
|
|
|
156
|
+
/** Forward the missed activity-resume to the SDK so isInForeground is
|
|
157
|
+
* correct on cold start. No-op if the SDK already saw the resume. */
|
|
158
|
+
private fun nudgeApplicationServiceForeground() {
|
|
159
|
+
val activity = activity ?: return
|
|
160
|
+
val appSvc = runCatching { OneSignal.getServiceOrNull<IApplicationService>() }.getOrNull() ?: return
|
|
161
|
+
if (appSvc.isInForeground && appSvc.current === activity) return
|
|
162
|
+
val callbacks = appSvc as? Application.ActivityLifecycleCallbacks ?: return
|
|
163
|
+
callbacks.onActivityStarted(activity)
|
|
164
|
+
callbacks.onActivityResumed(activity)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
private fun buildClickEventJson(event: INotificationClickEvent): JSObject {
|
|
168
|
+
val ret = JSObject()
|
|
169
|
+
val clickResult = JSObject()
|
|
170
|
+
clickResult.put("actionId", event.result.actionId)
|
|
171
|
+
clickResult.put("url", event.result.url)
|
|
172
|
+
ret.put("result", clickResult)
|
|
173
|
+
ret.put("notification", serializeNotification(event.notification))
|
|
174
|
+
return ret
|
|
175
|
+
}
|
|
176
|
+
|
|
116
177
|
@PluginMethod
|
|
117
178
|
fun login(call: PluginCall) {
|
|
118
179
|
val externalId = call.getString("externalId")
|
|
@@ -144,8 +205,6 @@ class OneSignalCapacitorPlugin : Plugin(),
|
|
|
144
205
|
call.resolve()
|
|
145
206
|
}
|
|
146
207
|
|
|
147
|
-
// endregion
|
|
148
|
-
|
|
149
208
|
// region Debug
|
|
150
209
|
|
|
151
210
|
@PluginMethod
|
|
@@ -387,14 +446,15 @@ class OneSignalCapacitorPlugin : Plugin(),
|
|
|
387
446
|
@PluginMethod
|
|
388
447
|
fun permissionNative(call: PluginCall) {
|
|
389
448
|
val ret = JSObject()
|
|
390
|
-
|
|
449
|
+
val status = if (OneSignal.Notifications.permission) PERMISSION_AUTHORIZED else PERMISSION_DENIED
|
|
450
|
+
ret.put("permission", status)
|
|
391
451
|
call.resolve(ret)
|
|
392
452
|
}
|
|
393
453
|
|
|
394
454
|
@PluginMethod
|
|
395
455
|
fun requestPermission(call: PluginCall) {
|
|
396
456
|
val fallback = call.getBoolean("fallbackToSettings") ?: false
|
|
397
|
-
|
|
457
|
+
pluginScope.launch {
|
|
398
458
|
val accepted = OneSignal.Notifications.requestPermission(fallback)
|
|
399
459
|
val ret = JSObject()
|
|
400
460
|
ret.put("permission", accepted)
|
|
@@ -411,8 +471,12 @@ class OneSignalCapacitorPlugin : Plugin(),
|
|
|
411
471
|
|
|
412
472
|
@PluginMethod
|
|
413
473
|
fun registerForProvisionalAuthorization(call: PluginCall) {
|
|
474
|
+
// Provisional authorization is an iOS-only concept (UNUserNotification
|
|
475
|
+
// .provisional). Android has no equivalent quiet-delivery permission
|
|
476
|
+
// tier, so report `accepted = false` rather than misleading the JS
|
|
477
|
+
// layer into thinking a quiet permission was granted.
|
|
414
478
|
val ret = JSObject()
|
|
415
|
-
ret.put("accepted",
|
|
479
|
+
ret.put("accepted", false)
|
|
416
480
|
call.resolve(ret)
|
|
417
481
|
}
|
|
418
482
|
|
|
@@ -467,12 +531,15 @@ class OneSignalCapacitorPlugin : Plugin(),
|
|
|
467
531
|
call.reject("notificationId is required")
|
|
468
532
|
return
|
|
469
533
|
}
|
|
470
|
-
|
|
534
|
+
// JS always dispatches this after the listener loop, even when a
|
|
535
|
+
// listener already called display(). Missing entry = already handled.
|
|
536
|
+
val event = notificationWillDisplayCache.remove(notificationId)
|
|
471
537
|
if (event == null) {
|
|
472
|
-
|
|
538
|
+
preventDefaultCache.remove(notificationId)
|
|
539
|
+
call.resolve()
|
|
473
540
|
return
|
|
474
541
|
}
|
|
475
|
-
if (!preventDefaultCache.
|
|
542
|
+
if (!preventDefaultCache.remove(notificationId)) {
|
|
476
543
|
event.notification.display()
|
|
477
544
|
}
|
|
478
545
|
call.resolve()
|
|
@@ -485,11 +552,13 @@ class OneSignalCapacitorPlugin : Plugin(),
|
|
|
485
552
|
call.reject("notificationId is required")
|
|
486
553
|
return
|
|
487
554
|
}
|
|
488
|
-
val event = notificationWillDisplayCache
|
|
555
|
+
val event = notificationWillDisplayCache.remove(notificationId)
|
|
489
556
|
if (event == null) {
|
|
490
|
-
|
|
557
|
+
preventDefaultCache.remove(notificationId)
|
|
558
|
+
call.resolve()
|
|
491
559
|
return
|
|
492
560
|
}
|
|
561
|
+
preventDefaultCache.remove(notificationId)
|
|
493
562
|
event.notification.display()
|
|
494
563
|
call.resolve()
|
|
495
564
|
}
|
|
@@ -588,7 +657,7 @@ class OneSignalCapacitorPlugin : Plugin(),
|
|
|
588
657
|
|
|
589
658
|
@PluginMethod
|
|
590
659
|
fun requestLocationPermission(call: PluginCall) {
|
|
591
|
-
|
|
660
|
+
pluginScope.launch {
|
|
592
661
|
OneSignal.Location.requestPermission()
|
|
593
662
|
call.resolve()
|
|
594
663
|
}
|
|
@@ -610,7 +679,9 @@ class OneSignalCapacitorPlugin : Plugin(),
|
|
|
610
679
|
|
|
611
680
|
// endregion
|
|
612
681
|
|
|
613
|
-
// region Live Activities
|
|
682
|
+
// region Live Activities
|
|
683
|
+
// iOS-only feature; methods below are no-ops on Android so cross-platform
|
|
684
|
+
// JS code can call them unconditionally. No warnings — silent success.
|
|
614
685
|
|
|
615
686
|
@PluginMethod
|
|
616
687
|
fun enterLiveActivity(call: PluginCall) {
|
|
@@ -647,6 +718,10 @@ class OneSignalCapacitorPlugin : Plugin(),
|
|
|
647
718
|
// region Observer Callbacks
|
|
648
719
|
|
|
649
720
|
override fun onWillDisplay(event: INotificationWillDisplayEvent) {
|
|
721
|
+
// No retainUntilConsumed needed: foreground will-display only fires
|
|
722
|
+
// while the app is foregrounded, so the JS layer's listener is
|
|
723
|
+
// already attached. Contrast with onClick() below, which can fire
|
|
724
|
+
// before the WebView finishes booting on a cold-start tap.
|
|
650
725
|
val notificationId = event.notification.notificationId ?: return
|
|
651
726
|
notificationWillDisplayCache[notificationId] = event
|
|
652
727
|
event.preventDefault()
|
|
@@ -654,17 +729,11 @@ class OneSignalCapacitorPlugin : Plugin(),
|
|
|
654
729
|
}
|
|
655
730
|
|
|
656
731
|
override fun onClick(event: INotificationClickEvent) {
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
ret.put("result", clickResult)
|
|
663
|
-
ret.put("notification", serializeNotification(event.notification))
|
|
664
|
-
notifyListeners("notificationClick", ret)
|
|
665
|
-
} else {
|
|
666
|
-
pendingClickEvent = event
|
|
667
|
-
}
|
|
732
|
+
// retainUntilConsumed lets Capacitor hold this event until the JS-side
|
|
733
|
+
// click listener attaches. On Android the OneSignal SDK can deliver a
|
|
734
|
+
// cold-start click before the WebView has finished booting and the JS
|
|
735
|
+
// layer has called addEventListener('click', ...).
|
|
736
|
+
notifyListeners("notificationClick", buildClickEventJson(event), true)
|
|
668
737
|
}
|
|
669
738
|
|
|
670
739
|
private fun serializeNotification(notification: INotification): JSObject {
|
package/dist/index.d.ts
CHANGED
|
@@ -366,6 +366,7 @@ interface PushSubscriptionChangedState {
|
|
|
366
366
|
declare class PushSubscription implements OneSignalPushSubscriptionAPI {
|
|
367
367
|
private _plugin;
|
|
368
368
|
private _subscriptionObserverList;
|
|
369
|
+
private _hasRegisteredChangeListener;
|
|
369
370
|
constructor(plugin: OneSignalCapacitorPlugin);
|
|
370
371
|
private _processFunctionList;
|
|
371
372
|
/**
|
|
@@ -388,8 +389,9 @@ declare class PushSubscription implements OneSignalPushSubscriptionAPI {
|
|
|
388
389
|
getOptedInAsync(): Promise<boolean>;
|
|
389
390
|
/**
|
|
390
391
|
* Add a callback that fires when the OneSignal push subscription state changes.
|
|
391
|
-
*
|
|
392
|
-
*
|
|
392
|
+
* The bridge subscription is registered once per namespace instance; subsequent
|
|
393
|
+
* subscribers append to the local list to avoid orphaned bridge handlers
|
|
394
|
+
* across hot-reload cycles.
|
|
393
395
|
*/
|
|
394
396
|
addEventListener(_event: 'change', listener: (event: PushSubscriptionChangedState) => void): void;
|
|
395
397
|
/**
|
|
@@ -474,6 +476,7 @@ declare class User implements OneSignalUserAPI {
|
|
|
474
476
|
pushSubscription: PushSubscription;
|
|
475
477
|
private _plugin;
|
|
476
478
|
private _userStateObserverList;
|
|
479
|
+
private _hasRegisteredChangeListener;
|
|
477
480
|
constructor(plugin: OneSignalCapacitorPlugin);
|
|
478
481
|
private _processFunctionList;
|
|
479
482
|
/**
|
|
@@ -565,8 +568,9 @@ declare class User implements OneSignalUserAPI {
|
|
|
565
568
|
}>;
|
|
566
569
|
/**
|
|
567
570
|
* Add a callback that fires when the OneSignal User state changes.
|
|
568
|
-
*
|
|
569
|
-
*
|
|
571
|
+
* The bridge subscription is registered once per namespace instance; subsequent
|
|
572
|
+
* subscribers append to the local list to avoid orphaned bridge handlers
|
|
573
|
+
* across hot-reload cycles.
|
|
570
574
|
*/
|
|
571
575
|
addEventListener(_event: 'change', listener: (event: UserChangedState) => void): void;
|
|
572
576
|
/**
|
|
@@ -804,13 +808,19 @@ declare class InAppMessages implements OneSignalInAppMessagesAPI {
|
|
|
804
808
|
private _didDisplayInAppMessageListeners;
|
|
805
809
|
private _willDismissInAppMessageListeners;
|
|
806
810
|
private _didDismissInAppMessageListeners;
|
|
811
|
+
private _hasRegisteredClickListener;
|
|
812
|
+
private _hasRegisteredWillDisplayListener;
|
|
813
|
+
private _hasRegisteredDidDisplayListener;
|
|
814
|
+
private _hasRegisteredWillDismissListener;
|
|
815
|
+
private _hasRegisteredDidDismissListener;
|
|
807
816
|
constructor(plugin: OneSignalCapacitorPlugin);
|
|
808
817
|
private _processFunctionList;
|
|
809
818
|
/**
|
|
810
819
|
* Add event listeners for In-App Message click and/or lifecycle events.
|
|
811
|
-
*
|
|
812
|
-
*
|
|
813
|
-
*
|
|
820
|
+
* Each native event channel is bridged once per namespace instance; subsequent
|
|
821
|
+
* subscribers are appended to the local list. Without this guard, hot-reload
|
|
822
|
+
* cycles and effect re-runs leak orphaned bridge subscriptions that fan a
|
|
823
|
+
* single native event into N JS callbacks.
|
|
814
824
|
*/
|
|
815
825
|
addEventListener<K extends InAppMessageEventName>(event: K, listener: (event: InAppMessageEventTypeMap[K]) => void): void;
|
|
816
826
|
/**
|
package/dist/index.js
CHANGED
|
@@ -62,6 +62,11 @@ var InAppMessages = class {
|
|
|
62
62
|
this._didDisplayInAppMessageListeners = [];
|
|
63
63
|
this._willDismissInAppMessageListeners = [];
|
|
64
64
|
this._didDismissInAppMessageListeners = [];
|
|
65
|
+
this._hasRegisteredClickListener = false;
|
|
66
|
+
this._hasRegisteredWillDisplayListener = false;
|
|
67
|
+
this._hasRegisteredDidDisplayListener = false;
|
|
68
|
+
this._hasRegisteredWillDismissListener = false;
|
|
69
|
+
this._hasRegisteredDidDismissListener = false;
|
|
65
70
|
this._plugin = plugin;
|
|
66
71
|
}
|
|
67
72
|
_processFunctionList(array, param) {
|
|
@@ -69,36 +74,52 @@ var InAppMessages = class {
|
|
|
69
74
|
}
|
|
70
75
|
/**
|
|
71
76
|
* Add event listeners for In-App Message click and/or lifecycle events.
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
77
|
+
* Each native event channel is bridged once per namespace instance; subsequent
|
|
78
|
+
* subscribers are appended to the local list. Without this guard, hot-reload
|
|
79
|
+
* cycles and effect re-runs leak orphaned bridge subscriptions that fan a
|
|
80
|
+
* single native event into N JS callbacks.
|
|
75
81
|
*/
|
|
76
82
|
addEventListener(event, listener) {
|
|
77
83
|
if (event === "click") {
|
|
78
84
|
this._inAppMessageClickListeners.push(listener);
|
|
79
|
-
this.
|
|
80
|
-
this.
|
|
81
|
-
|
|
85
|
+
if (!this._hasRegisteredClickListener) {
|
|
86
|
+
this._hasRegisteredClickListener = true;
|
|
87
|
+
this._plugin.addListener("inAppMessageClick", (json) => {
|
|
88
|
+
this._processFunctionList(this._inAppMessageClickListeners, json);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
82
91
|
} else if (event === "willDisplay") {
|
|
83
92
|
this._willDisplayInAppMessageListeners.push(listener);
|
|
84
|
-
this.
|
|
85
|
-
this.
|
|
86
|
-
|
|
93
|
+
if (!this._hasRegisteredWillDisplayListener) {
|
|
94
|
+
this._hasRegisteredWillDisplayListener = true;
|
|
95
|
+
this._plugin.addListener("inAppMessageWillDisplay", (event) => {
|
|
96
|
+
this._processFunctionList(this._willDisplayInAppMessageListeners, event);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
87
99
|
} else if (event === "didDisplay") {
|
|
88
100
|
this._didDisplayInAppMessageListeners.push(listener);
|
|
89
|
-
this.
|
|
90
|
-
this.
|
|
91
|
-
|
|
101
|
+
if (!this._hasRegisteredDidDisplayListener) {
|
|
102
|
+
this._hasRegisteredDidDisplayListener = true;
|
|
103
|
+
this._plugin.addListener("inAppMessageDidDisplay", (event) => {
|
|
104
|
+
this._processFunctionList(this._didDisplayInAppMessageListeners, event);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
92
107
|
} else if (event === "willDismiss") {
|
|
93
108
|
this._willDismissInAppMessageListeners.push(listener);
|
|
94
|
-
this.
|
|
95
|
-
this.
|
|
96
|
-
|
|
109
|
+
if (!this._hasRegisteredWillDismissListener) {
|
|
110
|
+
this._hasRegisteredWillDismissListener = true;
|
|
111
|
+
this._plugin.addListener("inAppMessageWillDismiss", (event) => {
|
|
112
|
+
this._processFunctionList(this._willDismissInAppMessageListeners, event);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
97
115
|
} else if (event === "didDismiss") {
|
|
98
116
|
this._didDismissInAppMessageListeners.push(listener);
|
|
99
|
-
this.
|
|
100
|
-
this.
|
|
101
|
-
|
|
117
|
+
if (!this._hasRegisteredDidDismissListener) {
|
|
118
|
+
this._hasRegisteredDidDismissListener = true;
|
|
119
|
+
this._plugin.addListener("inAppMessageDidDismiss", (event) => {
|
|
120
|
+
this._processFunctionList(this._didDismissInAppMessageListeners, event);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
102
123
|
}
|
|
103
124
|
}
|
|
104
125
|
/**
|
|
@@ -544,6 +565,7 @@ var Session = class {
|
|
|
544
565
|
var PushSubscription = class {
|
|
545
566
|
constructor(plugin) {
|
|
546
567
|
this._subscriptionObserverList = [];
|
|
568
|
+
this._hasRegisteredChangeListener = false;
|
|
547
569
|
this._plugin = plugin;
|
|
548
570
|
}
|
|
549
571
|
_processFunctionList(array, param) {
|
|
@@ -575,14 +597,18 @@ var PushSubscription = class {
|
|
|
575
597
|
}
|
|
576
598
|
/**
|
|
577
599
|
* Add a callback that fires when the OneSignal push subscription state changes.
|
|
578
|
-
*
|
|
579
|
-
*
|
|
600
|
+
* The bridge subscription is registered once per namespace instance; subsequent
|
|
601
|
+
* subscribers append to the local list to avoid orphaned bridge handlers
|
|
602
|
+
* across hot-reload cycles.
|
|
580
603
|
*/
|
|
581
604
|
addEventListener(_event, listener) {
|
|
582
605
|
this._subscriptionObserverList.push(listener);
|
|
583
|
-
this.
|
|
584
|
-
this.
|
|
585
|
-
|
|
606
|
+
if (!this._hasRegisteredChangeListener) {
|
|
607
|
+
this._hasRegisteredChangeListener = true;
|
|
608
|
+
this._plugin.addListener("pushSubscriptionChange", (state) => {
|
|
609
|
+
this._processFunctionList(this._subscriptionObserverList, state);
|
|
610
|
+
});
|
|
611
|
+
}
|
|
586
612
|
}
|
|
587
613
|
/**
|
|
588
614
|
* Remove a push subscription observer that has been previously added.
|
|
@@ -612,6 +638,7 @@ var PushSubscription = class {
|
|
|
612
638
|
var User = class {
|
|
613
639
|
constructor(plugin) {
|
|
614
640
|
this._userStateObserverList = [];
|
|
641
|
+
this._hasRegisteredChangeListener = false;
|
|
615
642
|
this._plugin = plugin;
|
|
616
643
|
this.pushSubscription = new PushSubscription(plugin);
|
|
617
644
|
}
|
|
@@ -737,14 +764,18 @@ var User = class {
|
|
|
737
764
|
}
|
|
738
765
|
/**
|
|
739
766
|
* Add a callback that fires when the OneSignal User state changes.
|
|
740
|
-
*
|
|
741
|
-
*
|
|
767
|
+
* The bridge subscription is registered once per namespace instance; subsequent
|
|
768
|
+
* subscribers append to the local list to avoid orphaned bridge handlers
|
|
769
|
+
* across hot-reload cycles.
|
|
742
770
|
*/
|
|
743
771
|
addEventListener(_event, listener) {
|
|
744
772
|
this._userStateObserverList.push(listener);
|
|
745
|
-
this.
|
|
746
|
-
this.
|
|
747
|
-
|
|
773
|
+
if (!this._hasRegisteredChangeListener) {
|
|
774
|
+
this._hasRegisteredChangeListener = true;
|
|
775
|
+
this._plugin.addListener("userStateChange", (state) => {
|
|
776
|
+
this._processFunctionList(this._userStateObserverList, state);
|
|
777
|
+
});
|
|
778
|
+
}
|
|
748
779
|
}
|
|
749
780
|
/**
|
|
750
781
|
* Remove a User State observer that has been previously added.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#import "OSCapacitorLaunchOptions.h"
|
|
2
|
+
#import <UIKit/UIKit.h>
|
|
3
|
+
#import <UserNotifications/UserNotifications.h>
|
|
4
|
+
#import <objc/runtime.h>
|
|
5
|
+
|
|
6
|
+
@implementation OSCapacitorLaunchOptions
|
|
7
|
+
|
|
8
|
+
static NSDictionary *_capturedLaunchOptions = nil;
|
|
9
|
+
static NSMutableArray<UNNotificationResponse *> *_capturedColdStartResponses = nil;
|
|
10
|
+
// Flips to YES the first time consumeColdStartResponses runs (i.e. after the JS
|
|
11
|
+
// layer has called OneSignal.initialize and drained whatever was queued). The
|
|
12
|
+
// swizzle stays installed for the process lifetime, so without this flag every
|
|
13
|
+
// subsequent warm/background tap would be retained in the array forever and
|
|
14
|
+
// _capturedColdStartResponses would grow monotonically. Once consumed, new
|
|
15
|
+
// taps fall through to the host delegate without being captured.
|
|
16
|
+
static BOOL _coldStartResponsesConsumed = NO;
|
|
17
|
+
|
|
18
|
+
+ (void)load {
|
|
19
|
+
_capturedColdStartResponses = [NSMutableArray array];
|
|
20
|
+
[[NSNotificationCenter defaultCenter]
|
|
21
|
+
addObserver:self
|
|
22
|
+
selector:@selector(applicationDidFinishLaunching:)
|
|
23
|
+
name:UIApplicationDidFinishLaunchingNotification
|
|
24
|
+
object:nil];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
+ (void)applicationDidFinishLaunching:(NSNotification *)notification {
|
|
28
|
+
_capturedLaunchOptions = notification.userInfo;
|
|
29
|
+
|
|
30
|
+
[[NSNotificationCenter defaultCenter]
|
|
31
|
+
removeObserver:self
|
|
32
|
+
name:UIApplicationDidFinishLaunchingNotification
|
|
33
|
+
object:nil];
|
|
34
|
+
|
|
35
|
+
// Wrap the UN delegate's didReceiveNotificationResponse so we can hold on
|
|
36
|
+
// to the UNNotificationResponse iOS hands us on cold start. The OneSignal
|
|
37
|
+
// iOS SDK drops cold-start responses inside processNotificationResponse:
|
|
38
|
+
// when no appId is set yet, which is always true on cold start because the
|
|
39
|
+
// JS layer has not called OneSignal.initialize yet. The plugin replays the
|
|
40
|
+
// captured response after initialize() so the SDK can fire its click
|
|
41
|
+
// listeners normally.
|
|
42
|
+
id unDelegate = [UNUserNotificationCenter currentNotificationCenter].delegate;
|
|
43
|
+
if (!unDelegate) return;
|
|
44
|
+
|
|
45
|
+
SEL didReceiveSel = NSSelectorFromString(@"userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:");
|
|
46
|
+
Class delegateClass = [unDelegate class];
|
|
47
|
+
Method original = class_getInstanceMethod(delegateClass, didReceiveSel);
|
|
48
|
+
if (!original) return;
|
|
49
|
+
|
|
50
|
+
__block IMP originalIMP = method_getImplementation(original);
|
|
51
|
+
IMP newIMP = imp_implementationWithBlock(^(id self_, UNUserNotificationCenter *center, UNNotificationResponse *response, void (^completionHandler)(void)) {
|
|
52
|
+
// Queue every response that arrives before the JS layer drains us.
|
|
53
|
+
// The JS bundle can take multiple seconds to load on cold start (worse
|
|
54
|
+
// in dev builds), and the user can tap a second notification from the
|
|
55
|
+
// shade in that window. Overwriting would silently lose the earlier
|
|
56
|
+
// tap. consumeColdStartResponses clears the queue and flips the
|
|
57
|
+
// _coldStartResponsesConsumed flag once initialize() has handed every
|
|
58
|
+
// response to OSNotificationsManager; from that point on, taps fall
|
|
59
|
+
// straight through to the host delegate so the array can't grow.
|
|
60
|
+
if (!_coldStartResponsesConsumed) {
|
|
61
|
+
[_capturedColdStartResponses addObject:response];
|
|
62
|
+
}
|
|
63
|
+
((void(*)(id, SEL, UNUserNotificationCenter*, UNNotificationResponse*, void(^)(void)))originalIMP)(self_, didReceiveSel, center, response, completionHandler);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Try to add the method to the delegate's exact class first. If it succeeds,
|
|
67
|
+
// the IMP came from a parent class (inherited) and we've safely shadowed it
|
|
68
|
+
// on this subclass only, leaving sibling subclasses untouched. If it fails,
|
|
69
|
+
// the method is owned by this exact class and method_setImplementation is
|
|
70
|
+
// safe — it won't leak the wrap up the inheritance chain.
|
|
71
|
+
if (!class_addMethod(delegateClass, didReceiveSel, newIMP, method_getTypeEncoding(original))) {
|
|
72
|
+
method_setImplementation(original, newIMP);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
+ (NSDictionary *)launchOptions {
|
|
77
|
+
return _capturedLaunchOptions;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
+ (NSArray<UNNotificationResponse *> *)pendingColdStartResponses {
|
|
81
|
+
return [_capturedColdStartResponses copy];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
+ (void)consumeColdStartResponses {
|
|
85
|
+
_coldStartResponsesConsumed = YES;
|
|
86
|
+
[_capturedColdStartResponses removeAllObjects];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
#import <UserNotifications/UserNotifications.h>
|
|
3
|
+
|
|
4
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
5
|
+
|
|
6
|
+
/// Captures cold-start state from iOS that the OneSignal SDK would otherwise
|
|
7
|
+
/// drop because its JS-driven initialize() runs too late.
|
|
8
|
+
///
|
|
9
|
+
/// This class subscribes to UIApplicationDidFinishLaunchingNotification from
|
|
10
|
+
/// +load (executed by dyld at process start, before main()) so:
|
|
11
|
+
/// * launchOptions are captured before any other code can lose them, and
|
|
12
|
+
/// * the UNUserNotificationCenter delegate's
|
|
13
|
+
/// didReceiveNotificationResponse: is wrapped so we can hold on to the
|
|
14
|
+
/// UNNotificationResponse for a cold-start tap. The OneSignal iOS SDK
|
|
15
|
+
/// drops it inside processNotificationResponse: when no appId is set
|
|
16
|
+
/// yet (OSNotificationsManager.m). We replay it after the JS layer
|
|
17
|
+
/// finishes calling OneSignal.initialize.
|
|
18
|
+
@interface OSCapacitorLaunchOptions : NSObject
|
|
19
|
+
|
|
20
|
+
@property (class, readonly, nullable) NSDictionary *launchOptions;
|
|
21
|
+
|
|
22
|
+
/// UNNotificationResponses delivered by iOS while the JS layer was still
|
|
23
|
+
/// booting (i.e. before OneSignal.initialize ran and we drained the queue).
|
|
24
|
+
/// Empty for warm starts and after consumeColdStartResponses has been called.
|
|
25
|
+
/// Multiple entries are possible: the user can tap a second notification from
|
|
26
|
+
/// the shade while the JS bundle is still loading, especially in dev builds.
|
|
27
|
+
@property (class, readonly, nonnull) NSArray<UNNotificationResponse *> *pendingColdStartResponses;
|
|
28
|
+
|
|
29
|
+
/// Mark the captured cold-start responses as consumed so they are not replayed
|
|
30
|
+
/// twice. Call after handing each response off to the OneSignal iOS SDK.
|
|
31
|
+
+ (void)consumeColdStartResponses;
|
|
32
|
+
|
|
33
|
+
@end
|
|
34
|
+
|
|
35
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -2,16 +2,12 @@ import Foundation
|
|
|
2
2
|
import Capacitor
|
|
3
3
|
import OneSignalFramework
|
|
4
4
|
import OneSignalLiveActivities
|
|
5
|
+
#if SWIFT_PACKAGE
|
|
6
|
+
import OSCapacitorLaunchOptions
|
|
7
|
+
#endif
|
|
5
8
|
|
|
6
9
|
@objc(OneSignalCapacitorPlugin)
|
|
7
|
-
public class OneSignalCapacitorPlugin: CAPPlugin, CAPBridgedPlugin
|
|
8
|
-
OSNotificationPermissionObserver,
|
|
9
|
-
OSNotificationLifecycleListener,
|
|
10
|
-
OSNotificationClickListener,
|
|
11
|
-
OSPushSubscriptionObserver,
|
|
12
|
-
OSInAppMessageLifecycleListener,
|
|
13
|
-
OSInAppMessageClickListener,
|
|
14
|
-
OSUserStateObserver {
|
|
10
|
+
public class OneSignalCapacitorPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
15
11
|
|
|
16
12
|
public let identifier = "OneSignalCapacitorPlugin"
|
|
17
13
|
public let jsName = "OneSignalCapacitor"
|
|
@@ -72,8 +68,28 @@ public class OneSignalCapacitorPlugin: CAPPlugin, CAPBridgedPlugin,
|
|
|
72
68
|
]
|
|
73
69
|
|
|
74
70
|
private var notificationWillDisplayCache = [String: OSNotificationWillDisplayEvent]()
|
|
75
|
-
private var preventDefaultCache =
|
|
76
|
-
private var
|
|
71
|
+
private var preventDefaultCache = Set<String>()
|
|
72
|
+
private var initialized = false
|
|
73
|
+
|
|
74
|
+
// Observer/listener forwarder. The iOS SDK strong-retains conformers of
|
|
75
|
+
// the lifecycle/click protocols (NSMutableArray-backed), so registering
|
|
76
|
+
// self directly creates a retain cycle that makes deinit unreachable.
|
|
77
|
+
// The proxy holds a weak ref back to us, so dropping the last external
|
|
78
|
+
// ref to the plugin lets deinit run and clean up the proxy registration.
|
|
79
|
+
private var listenerProxy: OneSignalListenerProxy?
|
|
80
|
+
|
|
81
|
+
deinit {
|
|
82
|
+
// Only present after initialize() ran. Removes are idempotent on the
|
|
83
|
+
// SDK side; we still gate to avoid touching an uninitialized SDK.
|
|
84
|
+
guard let listenerProxy = listenerProxy else { return }
|
|
85
|
+
OneSignal.Notifications.removePermissionObserver(listenerProxy)
|
|
86
|
+
OneSignal.Notifications.removeForegroundLifecycleListener(listenerProxy)
|
|
87
|
+
OneSignal.Notifications.removeClickListener(listenerProxy)
|
|
88
|
+
OneSignal.User.pushSubscription.removeObserver(listenerProxy)
|
|
89
|
+
OneSignal.User.removeObserver(listenerProxy)
|
|
90
|
+
OneSignal.InAppMessages.removeLifecycleListener(listenerProxy)
|
|
91
|
+
OneSignal.InAppMessages.removeClickListener(listenerProxy)
|
|
92
|
+
}
|
|
77
93
|
|
|
78
94
|
// MARK: - Core
|
|
79
95
|
|
|
@@ -82,21 +98,56 @@ public class OneSignalCapacitorPlugin: CAPPlugin, CAPBridgedPlugin,
|
|
|
82
98
|
call.reject("appId is required")
|
|
83
99
|
return
|
|
84
100
|
}
|
|
85
|
-
OneSignalWrapper.sdkType = "capacitor"
|
|
86
|
-
OneSignalWrapper.sdkVersion = "010000"
|
|
87
|
-
OneSignal.initialize(appId, withLaunchOptions: nil)
|
|
88
|
-
OneSignal.Notifications.addPermissionObserver(self)
|
|
89
|
-
OneSignal.Notifications.addForegroundLifecycleListener(self)
|
|
90
|
-
OneSignal.Notifications.addClickListener(self)
|
|
91
|
-
OneSignal.User.pushSubscription.addObserver(self)
|
|
92
|
-
OneSignal.User.addObserver(self)
|
|
93
|
-
OneSignal.InAppMessages.addLifecycleListener(self)
|
|
94
|
-
OneSignal.InAppMessages.addClickListener(self)
|
|
95
101
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
102
|
+
// initialize() is idempotent: JS may call it multiple times per
|
|
103
|
+
// plugin instance (effect re-runs, hot reload). The iOS SDK's
|
|
104
|
+
// listener arrays don't dedupe, so unguarded re-entry would
|
|
105
|
+
// double-fire foreground/click events.
|
|
106
|
+
if initialized {
|
|
107
|
+
call.resolve()
|
|
108
|
+
return
|
|
99
109
|
}
|
|
110
|
+
initialized = true
|
|
111
|
+
|
|
112
|
+
OneSignalWrapper.sdkType = "capacitor"
|
|
113
|
+
OneSignalWrapper.sdkVersion = "010002"
|
|
114
|
+
// OSCapacitorLaunchOptions's +load captures the dictionary from
|
|
115
|
+
// UIApplicationDidFinishLaunchingNotification at process start (before
|
|
116
|
+
// main()), so cold-start notification taps that arrive via launchOptions
|
|
117
|
+
// are still available to the OneSignal iOS SDK when the JS layer
|
|
118
|
+
// initializes us.
|
|
119
|
+
OneSignal.initialize(appId, withLaunchOptions: OSCapacitorLaunchOptions.launchOptions)
|
|
120
|
+
|
|
121
|
+
// The OneSignal iOS SDK drops cold-start UNNotificationResponse objects
|
|
122
|
+
// inside processNotificationResponse: when no appId is set yet, which
|
|
123
|
+
// is always true on cold start because iOS delivers the response before
|
|
124
|
+
// OneSignal.initialize() runs from JS. OSCapacitorLaunchOptions's
|
|
125
|
+
// delegate wrap queues every response that arrives in that window so we
|
|
126
|
+
// can replay them here, in arrival order, after initialize has set the
|
|
127
|
+
// appId. The queue can hold more than one entry if the user tapped a
|
|
128
|
+
// second notification from the shade while the JS bundle was loading.
|
|
129
|
+
for response in OSCapacitorLaunchOptions.pendingColdStartResponses {
|
|
130
|
+
OSNotificationsManager.processNotificationResponse(response)
|
|
131
|
+
}
|
|
132
|
+
// Always consume, even if the queue was empty. consumeColdStartResponses
|
|
133
|
+
// also flips a one-way flag that tells the swizzle to stop capturing
|
|
134
|
+
// future taps; without this unconditional call, sessions that cold-start
|
|
135
|
+
// without a notification tap would never flip the flag and any later
|
|
136
|
+
// warm/background taps would accumulate in the static array forever.
|
|
137
|
+
OSCapacitorLaunchOptions.consumeColdStartResponses()
|
|
138
|
+
|
|
139
|
+
let proxy = OneSignalListenerProxy()
|
|
140
|
+
proxy.owner = self
|
|
141
|
+
listenerProxy = proxy
|
|
142
|
+
|
|
143
|
+
OneSignal.Notifications.addPermissionObserver(proxy)
|
|
144
|
+
OneSignal.Notifications.addForegroundLifecycleListener(proxy)
|
|
145
|
+
OneSignal.Notifications.addClickListener(proxy)
|
|
146
|
+
OneSignal.User.pushSubscription.addObserver(proxy)
|
|
147
|
+
OneSignal.User.addObserver(proxy)
|
|
148
|
+
OneSignal.InAppMessages.addLifecycleListener(proxy)
|
|
149
|
+
OneSignal.InAppMessages.addClickListener(proxy)
|
|
150
|
+
|
|
100
151
|
call.resolve()
|
|
101
152
|
}
|
|
102
153
|
|
|
@@ -320,7 +371,7 @@ public class OneSignalCapacitorPlugin: CAPPlugin, CAPBridgedPlugin,
|
|
|
320
371
|
return
|
|
321
372
|
}
|
|
322
373
|
event.preventDefault()
|
|
323
|
-
preventDefaultCache
|
|
374
|
+
preventDefaultCache.insert(notificationId)
|
|
324
375
|
call.resolve()
|
|
325
376
|
}
|
|
326
377
|
|
|
@@ -329,11 +380,15 @@ public class OneSignalCapacitorPlugin: CAPPlugin, CAPBridgedPlugin,
|
|
|
329
380
|
call.reject("notificationId is required")
|
|
330
381
|
return
|
|
331
382
|
}
|
|
332
|
-
|
|
333
|
-
|
|
383
|
+
// JS always dispatches this after the listener loop, even when a
|
|
384
|
+
// listener already called display(). Missing entry = already handled.
|
|
385
|
+
guard let event = notificationWillDisplayCache.removeValue(forKey: notificationId) else {
|
|
386
|
+
preventDefaultCache.remove(notificationId)
|
|
387
|
+
call.resolve()
|
|
334
388
|
return
|
|
335
389
|
}
|
|
336
|
-
|
|
390
|
+
let wasPrevented = preventDefaultCache.remove(notificationId) != nil
|
|
391
|
+
if !wasPrevented {
|
|
337
392
|
event.notification.display()
|
|
338
393
|
}
|
|
339
394
|
call.resolve()
|
|
@@ -344,10 +399,12 @@ public class OneSignalCapacitorPlugin: CAPPlugin, CAPBridgedPlugin,
|
|
|
344
399
|
call.reject("notificationId is required")
|
|
345
400
|
return
|
|
346
401
|
}
|
|
347
|
-
guard let event = notificationWillDisplayCache
|
|
348
|
-
|
|
402
|
+
guard let event = notificationWillDisplayCache.removeValue(forKey: notificationId) else {
|
|
403
|
+
preventDefaultCache.remove(notificationId)
|
|
404
|
+
call.resolve()
|
|
349
405
|
return
|
|
350
406
|
}
|
|
407
|
+
preventDefaultCache.remove(notificationId)
|
|
351
408
|
event.notification.display()
|
|
352
409
|
call.resolve()
|
|
353
410
|
}
|
|
@@ -569,18 +626,16 @@ public class OneSignalCapacitorPlugin: CAPPlugin, CAPBridgedPlugin,
|
|
|
569
626
|
}
|
|
570
627
|
|
|
571
628
|
public func onClick(event: OSNotificationClickEvent) {
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
if let data = event.stringify().data(using: .utf8),
|
|
581
|
-
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {
|
|
582
|
-
notifyListeners("notificationClick", data: json)
|
|
629
|
+
// retainUntilConsumed lets Capacitor hold this event until a JS click
|
|
630
|
+
// listener attaches. On cold start the plugin's initialize() replays
|
|
631
|
+
// the OneSignal click before JS has had a chance to call
|
|
632
|
+
// addEventListener('click', ...), so without this a cold-start tap
|
|
633
|
+
// would fire before any JS listener exists and be lost.
|
|
634
|
+
guard let data = event.stringify().data(using: .utf8),
|
|
635
|
+
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
|
|
636
|
+
return
|
|
583
637
|
}
|
|
638
|
+
notifyListeners("notificationClick", data: json, retainUntilConsumed: true)
|
|
584
639
|
}
|
|
585
640
|
|
|
586
641
|
@objc(onWillDisplayInAppMessage:)
|
|
@@ -637,3 +692,66 @@ public class OneSignalCapacitorPlugin: CAPPlugin, CAPBridgedPlugin,
|
|
|
637
692
|
])
|
|
638
693
|
}
|
|
639
694
|
}
|
|
695
|
+
|
|
696
|
+
// Forwarding proxy for the OneSignal iOS SDK observer/listener APIs.
|
|
697
|
+
// Registered with the SDK in place of the plugin so the SDK's strong
|
|
698
|
+
// retention of click/lifecycle listeners (NSMutableArray-backed) does not
|
|
699
|
+
// pin the plugin and make its deinit unreachable. The proxy holds a weak
|
|
700
|
+
// ref back to the plugin; once external holders drop the plugin its
|
|
701
|
+
// deinit runs, removes the proxy from the SDK, and the proxy is then
|
|
702
|
+
// released too.
|
|
703
|
+
final class OneSignalListenerProxy: NSObject,
|
|
704
|
+
OSNotificationPermissionObserver,
|
|
705
|
+
OSNotificationLifecycleListener,
|
|
706
|
+
OSNotificationClickListener,
|
|
707
|
+
OSPushSubscriptionObserver,
|
|
708
|
+
OSInAppMessageLifecycleListener,
|
|
709
|
+
OSInAppMessageClickListener,
|
|
710
|
+
OSUserStateObserver {
|
|
711
|
+
|
|
712
|
+
weak var owner: OneSignalCapacitorPlugin?
|
|
713
|
+
|
|
714
|
+
public func onNotificationPermissionDidChange(_ permission: Bool) {
|
|
715
|
+
owner?.onNotificationPermissionDidChange(permission)
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
public func onPushSubscriptionDidChange(state: OSPushSubscriptionChangedState) {
|
|
719
|
+
owner?.onPushSubscriptionDidChange(state: state)
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
public func onUserStateDidChange(state: OSUserChangedState) {
|
|
723
|
+
owner?.onUserStateDidChange(state: state)
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
public func onWillDisplay(event: OSNotificationWillDisplayEvent) {
|
|
727
|
+
owner?.onWillDisplay(event: event)
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
public func onClick(event: OSNotificationClickEvent) {
|
|
731
|
+
owner?.onClick(event: event)
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
@objc(onWillDisplayInAppMessage:)
|
|
735
|
+
public func onWillDisplay(event: OSInAppMessageWillDisplayEvent) {
|
|
736
|
+
owner?.onWillDisplay(event: event)
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
@objc(onDidDisplayInAppMessage:)
|
|
740
|
+
public func onDidDisplay(event: OSInAppMessageDidDisplayEvent) {
|
|
741
|
+
owner?.onDidDisplay(event: event)
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
@objc(onWillDismissInAppMessage:)
|
|
745
|
+
public func onWillDismiss(event: OSInAppMessageWillDismissEvent) {
|
|
746
|
+
owner?.onWillDismiss(event: event)
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
@objc(onDidDismissInAppMessage:)
|
|
750
|
+
public func onDidDismiss(event: OSInAppMessageDidDismissEvent) {
|
|
751
|
+
owner?.onDidDismiss(event: event)
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
public func onClick(event: OSInAppMessageClickEvent) {
|
|
755
|
+
owner?.onClick(event: event)
|
|
756
|
+
}
|
|
757
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onesignal/capacitor-plugin",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "OneSignal is a high volume Push Notification service for mobile apps. This is the pure Capacitor plugin for OneSignal, providing push notifications, in-app messaging, and more.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"apns",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"verify": "vp pack && vp test run && vp lint"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@capacitor/core": "
|
|
59
|
+
"@capacitor/core": "7.0.0",
|
|
60
60
|
"@capacitor/docgen": "^0.2.2",
|
|
61
61
|
"@types/bun": "latest",
|
|
62
62
|
"@vitest/coverage-v8": "^4.1.2",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"vite-plus": "0.1.20"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
|
-
"@capacitor/core": "
|
|
69
|
+
"@capacitor/core": ">=7.0.0"
|
|
70
70
|
},
|
|
71
71
|
"overrides": {
|
|
72
72
|
"vite": "npm:@voidzero-dev/vite-plus-core@latest",
|