react-native-push-signal 0.1.0

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.
Files changed (91) hide show
  1. package/LICENSE +20 -0
  2. package/PushSignal.podspec +31 -0
  3. package/README.md +125 -0
  4. package/README.ru.md +125 -0
  5. package/android/CMakeLists.txt +24 -0
  6. package/android/build.gradle +115 -0
  7. package/android/src/main/AndroidManifest.xml +18 -0
  8. package/android/src/main/cpp/cpp-adapter.cpp +11 -0
  9. package/android/src/main/java/com/margelo/nitro/pushsignal/PushSignal.kt +44 -0
  10. package/android/src/main/java/com/margelo/nitro/pushsignal/PushSignalCenter.kt +353 -0
  11. package/android/src/main/java/com/margelo/nitro/pushsignal/PushSignalInitProvider.kt +34 -0
  12. package/android/src/main/java/com/margelo/nitro/pushsignal/PushSignalMessagingService.kt +15 -0
  13. package/android/src/main/java/com/margelo/nitro/pushsignal/PushSignalPackage.kt +22 -0
  14. package/ios/PushSignal.swift +38 -0
  15. package/ios/PushSignalCenter.swift +430 -0
  16. package/ios/PushSignalLaunchStore.h +21 -0
  17. package/ios/PushSignalLaunchStore.m +26 -0
  18. package/lib/module/PushSignal.nitro.js +4 -0
  19. package/lib/module/PushSignal.nitro.js.map +1 -0
  20. package/lib/module/index.js +4 -0
  21. package/lib/module/index.js.map +1 -0
  22. package/lib/module/package.json +1 -0
  23. package/lib/module/pushSignal.js +19 -0
  24. package/lib/module/pushSignal.js.map +1 -0
  25. package/lib/module/pushSignal.native.js +46 -0
  26. package/lib/module/pushSignal.native.js.map +1 -0
  27. package/lib/typescript/package.json +1 -0
  28. package/lib/typescript/src/PushSignal.nitro.d.ts +33 -0
  29. package/lib/typescript/src/PushSignal.nitro.d.ts.map +1 -0
  30. package/lib/typescript/src/index.d.ts +3 -0
  31. package/lib/typescript/src/index.d.ts.map +1 -0
  32. package/lib/typescript/src/pushSignal.d.ts +8 -0
  33. package/lib/typescript/src/pushSignal.d.ts.map +1 -0
  34. package/lib/typescript/src/pushSignal.native.d.ts +8 -0
  35. package/lib/typescript/src/pushSignal.native.d.ts.map +1 -0
  36. package/nitro.json +23 -0
  37. package/nitrogen/generated/android/c++/JAndroidFirebaseConfig.hpp +70 -0
  38. package/nitrogen/generated/android/c++/JFunc_void_PushMessage.hpp +80 -0
  39. package/nitrogen/generated/android/c++/JHybridPushSignalSpec.cpp +138 -0
  40. package/nitrogen/generated/android/c++/JHybridPushSignalSpec.hpp +68 -0
  41. package/nitrogen/generated/android/c++/JPermissionStatus.hpp +61 -0
  42. package/nitrogen/generated/android/c++/JPushCredentials.hpp +70 -0
  43. package/nitrogen/generated/android/c++/JPushEnvironment.hpp +58 -0
  44. package/nitrogen/generated/android/c++/JPushMessage.hpp +84 -0
  45. package/nitrogen/generated/android/c++/JPushPlatform.hpp +58 -0
  46. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pushsignal/AndroidFirebaseConfig.kt +66 -0
  47. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pushsignal/Func_void_PushMessage.kt +78 -0
  48. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pushsignal/HybridPushSignalSpec.kt +87 -0
  49. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pushsignal/PermissionStatus.kt +24 -0
  50. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pushsignal/PushCredentials.kt +61 -0
  51. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pushsignal/PushEnvironment.kt +23 -0
  52. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pushsignal/PushMessage.kt +66 -0
  53. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pushsignal/PushPlatform.kt +23 -0
  54. package/nitrogen/generated/android/kotlin/com/margelo/nitro/pushsignal/pushsignalOnLoad.kt +35 -0
  55. package/nitrogen/generated/android/pushsignal+autolinking.cmake +81 -0
  56. package/nitrogen/generated/android/pushsignal+autolinking.gradle +27 -0
  57. package/nitrogen/generated/android/pushsignalOnLoad.cpp +56 -0
  58. package/nitrogen/generated/android/pushsignalOnLoad.hpp +34 -0
  59. package/nitrogen/generated/ios/PushSignal+autolinking.rb +62 -0
  60. package/nitrogen/generated/ios/PushSignal-Swift-Cxx-Bridge.cpp +65 -0
  61. package/nitrogen/generated/ios/PushSignal-Swift-Cxx-Bridge.hpp +257 -0
  62. package/nitrogen/generated/ios/PushSignal-Swift-Cxx-Umbrella.hpp +66 -0
  63. package/nitrogen/generated/ios/PushSignalAutolinking.mm +33 -0
  64. package/nitrogen/generated/ios/PushSignalAutolinking.swift +26 -0
  65. package/nitrogen/generated/ios/c++/HybridPushSignalSpecSwift.cpp +11 -0
  66. package/nitrogen/generated/ios/c++/HybridPushSignalSpecSwift.hpp +137 -0
  67. package/nitrogen/generated/ios/swift/AndroidFirebaseConfig.swift +96 -0
  68. package/nitrogen/generated/ios/swift/Func_void_PermissionStatus.swift +46 -0
  69. package/nitrogen/generated/ios/swift/Func_void_PushCredentials.swift +46 -0
  70. package/nitrogen/generated/ios/swift/Func_void_PushMessage.swift +46 -0
  71. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +46 -0
  72. package/nitrogen/generated/ios/swift/HybridPushSignalSpec.swift +60 -0
  73. package/nitrogen/generated/ios/swift/HybridPushSignalSpec_cxx.swift +226 -0
  74. package/nitrogen/generated/ios/swift/PermissionStatus.swift +44 -0
  75. package/nitrogen/generated/ios/swift/PushCredentials.swift +45 -0
  76. package/nitrogen/generated/ios/swift/PushEnvironment.swift +40 -0
  77. package/nitrogen/generated/ios/swift/PushMessage.swift +97 -0
  78. package/nitrogen/generated/ios/swift/PushPlatform.swift +40 -0
  79. package/nitrogen/generated/shared/c++/AndroidFirebaseConfig.hpp +96 -0
  80. package/nitrogen/generated/shared/c++/HybridPushSignalSpec.cpp +26 -0
  81. package/nitrogen/generated/shared/c++/HybridPushSignalSpec.hpp +79 -0
  82. package/nitrogen/generated/shared/c++/PermissionStatus.hpp +80 -0
  83. package/nitrogen/generated/shared/c++/PushCredentials.hpp +97 -0
  84. package/nitrogen/generated/shared/c++/PushEnvironment.hpp +76 -0
  85. package/nitrogen/generated/shared/c++/PushMessage.hpp +97 -0
  86. package/nitrogen/generated/shared/c++/PushPlatform.hpp +76 -0
  87. package/package.json +187 -0
  88. package/src/PushSignal.nitro.ts +37 -0
  89. package/src/index.tsx +16 -0
  90. package/src/pushSignal.native.tsx +67 -0
  91. package/src/pushSignal.tsx +32 -0
@@ -0,0 +1,353 @@
1
+ package com.margelo.nitro.pushsignal
2
+
3
+ import android.Manifest
4
+ import android.app.Activity
5
+ import android.app.Application
6
+ import android.content.Context
7
+ import android.content.Intent
8
+ import android.content.pm.PackageManager
9
+ import android.os.Build
10
+ import android.os.Bundle
11
+ import androidx.activity.ComponentActivity
12
+ import androidx.activity.result.ActivityResultLauncher
13
+ import androidx.activity.result.contract.ActivityResultContracts
14
+ import androidx.core.app.NotificationManagerCompat
15
+ import androidx.core.content.ContextCompat
16
+ import com.google.firebase.FirebaseApp
17
+ import com.google.firebase.FirebaseOptions
18
+ import com.google.firebase.messaging.FirebaseMessaging
19
+ import com.google.android.gms.tasks.Tasks
20
+ import com.google.firebase.messaging.RemoteMessage
21
+ import java.util.Collections
22
+ import java.util.WeakHashMap
23
+ import java.util.concurrent.CopyOnWriteArrayList
24
+
25
+ internal object PushSignalCenter : Application.ActivityLifecycleCallbacks {
26
+ private const val PREFS_NAME = "pushsignal"
27
+ private const val PREF_ASKED_PERMISSION = "asked_notifications"
28
+ private const val EXTRA_HANDLED = "pushsignal.handled"
29
+ private const val PERMISSION_LAUNCHER_KEY = "com.margelo.nitro.pushsignal.permission"
30
+
31
+ private val lock = Any()
32
+ @Volatile private var application: Application? = null
33
+ @Volatile private var currentActivity: Activity? = null
34
+ @Volatile private var permissionLauncher: ActivityResultLauncher<String>? = null
35
+ @Volatile private var onMessage: ((PushMessage) -> Unit)? = null
36
+ @Volatile private var onNotificationPress: ((PushMessage) -> Unit)? = null
37
+ @Volatile private var pendingPress: PushMessage? = null
38
+ private val permissionWaiters = CopyOnWriteArrayList<(PermissionStatus) -> Unit>()
39
+ private val registeredActivities = Collections.newSetFromMap(WeakHashMap<Activity, Boolean>())
40
+ @Volatile private var pendingFirebaseConfig: AndroidFirebaseConfig? = null
41
+
42
+ fun attach(context: Context) {
43
+ val app = context.applicationContext as? Application ?: return
44
+ if (application === app) {
45
+ return
46
+ }
47
+ application?.unregisterActivityLifecycleCallbacks(this)
48
+ application = app
49
+ app.registerActivityLifecycleCallbacks(this)
50
+ app.currentActivityOrNull()?.let { activity ->
51
+ currentActivity = activity
52
+ registerActivity(activity)
53
+ handleIntent(activity.intent)
54
+ }
55
+ pendingFirebaseConfig?.let { config ->
56
+ pendingFirebaseConfig = null
57
+ applyFirebaseConfig(app, config)
58
+ }
59
+ }
60
+
61
+ fun initialize(config: AndroidFirebaseConfig) {
62
+ if (!config.hasRequiredFields()) {
63
+ return
64
+ }
65
+
66
+ val context = application
67
+ if (context == null) {
68
+ pendingFirebaseConfig = config
69
+ return
70
+ }
71
+
72
+ applyFirebaseConfig(context, config)
73
+ }
74
+
75
+ fun setOnMessage(callback: (PushMessage) -> Unit) {
76
+ onMessage = callback
77
+ }
78
+
79
+ fun setOnNotificationPress(callback: (PushMessage) -> Unit) {
80
+ onNotificationPress = callback
81
+ val pending = synchronized(lock) {
82
+ val message = pendingPress
83
+ pendingPress = null
84
+ message
85
+ }
86
+ if (pending != null) {
87
+ callback(pending)
88
+ }
89
+ }
90
+
91
+ fun getPermissionStatus(): PermissionStatus {
92
+ val context = application ?: return PermissionStatus.NOTDETERMINED
93
+ val notificationsEnabled = NotificationManagerCompat.from(context).areNotificationsEnabled()
94
+
95
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
96
+ return if (notificationsEnabled) {
97
+ PermissionStatus.AUTHORIZED
98
+ } else {
99
+ PermissionStatus.DENIED
100
+ }
101
+ }
102
+
103
+ val granted =
104
+ ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) ==
105
+ PackageManager.PERMISSION_GRANTED
106
+ if (granted && notificationsEnabled) {
107
+ return PermissionStatus.AUTHORIZED
108
+ }
109
+
110
+ val asked =
111
+ context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
112
+ .getBoolean(PREF_ASKED_PERMISSION, false)
113
+ return if (!asked && !granted) {
114
+ PermissionStatus.NOTDETERMINED
115
+ } else {
116
+ PermissionStatus.DENIED
117
+ }
118
+ }
119
+
120
+ fun requestPermission(onResult: (PermissionStatus) -> Unit) {
121
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
122
+ onResult(getPermissionStatus())
123
+ return
124
+ }
125
+
126
+ val activity = currentActivity
127
+ val launcher = permissionLauncher
128
+ if (activity == null || launcher == null) {
129
+ onResult(getPermissionStatus())
130
+ return
131
+ }
132
+
133
+ if (
134
+ ContextCompat.checkSelfPermission(activity, Manifest.permission.POST_NOTIFICATIONS) ==
135
+ PackageManager.PERMISSION_GRANTED
136
+ ) {
137
+ onResult(getPermissionStatus())
138
+ return
139
+ }
140
+
141
+ permissionWaiters.add(onResult)
142
+ launcher.launch(Manifest.permission.POST_NOTIFICATIONS)
143
+ }
144
+
145
+ fun fetchToken(): String {
146
+ val context = application
147
+ ?: throw IllegalStateException("PushSignal is not initialized")
148
+
149
+ try {
150
+ if (FirebaseApp.getApps(context).isEmpty()) {
151
+ FirebaseApp.initializeApp(context)
152
+ }
153
+ FirebaseApp.getInstance()
154
+ } catch (error: IllegalStateException) {
155
+ throw IllegalStateException(
156
+ "Firebase is not configured. Call initialize({ projectId, applicationId, apiKey, gcmSenderId }) or add google-services.json.",
157
+ error
158
+ )
159
+ }
160
+
161
+ val task = FirebaseMessaging.getInstance().token
162
+ val token = try {
163
+ Tasks.await(task)
164
+ } catch (error: Exception) {
165
+ throw IllegalStateException(
166
+ "Failed to get an FCM token. Call initialize({ projectId, applicationId, apiKey, gcmSenderId }) or add google-services.json.",
167
+ error
168
+ )
169
+ }
170
+
171
+ if (token.isNullOrEmpty()) {
172
+ throw IllegalStateException("Firebase returned an empty FCM token")
173
+ }
174
+
175
+ return token
176
+ }
177
+
178
+ fun emitMessage(message: PushMessage) {
179
+ onMessage?.invoke(message)
180
+ }
181
+
182
+ fun emitMessage(remoteMessage: RemoteMessage) {
183
+ emitMessage(remoteMessage.toPushMessage())
184
+ }
185
+
186
+ override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
187
+ currentActivity = activity
188
+ registerActivity(activity)
189
+ handleIntent(activity.intent)
190
+ }
191
+
192
+ override fun onActivityStarted(activity: Activity) = Unit
193
+
194
+ override fun onActivityResumed(activity: Activity) {
195
+ currentActivity = activity
196
+ handleIntent(activity.intent)
197
+ }
198
+
199
+ override fun onActivityPaused(activity: Activity) {
200
+ if (currentActivity === activity) {
201
+ currentActivity = null
202
+ }
203
+ }
204
+
205
+ override fun onActivityStopped(activity: Activity) = Unit
206
+
207
+ override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) = Unit
208
+
209
+ override fun onActivityDestroyed(activity: Activity) {
210
+ if (currentActivity === activity) {
211
+ currentActivity = null
212
+ permissionLauncher = null
213
+ }
214
+ }
215
+
216
+ private fun registerActivity(activity: Activity) {
217
+ if (!registeredActivities.add(activity)) {
218
+ return
219
+ }
220
+
221
+ val componentActivity = activity as? ComponentActivity ?: return
222
+
223
+ permissionLauncher =
224
+ componentActivity.activityResultRegistry.register(
225
+ PERMISSION_LAUNCHER_KEY,
226
+ componentActivity,
227
+ ActivityResultContracts.RequestPermission()
228
+ ) {
229
+ activity
230
+ .getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
231
+ .edit()
232
+ .putBoolean(PREF_ASKED_PERMISSION, true)
233
+ .apply()
234
+ val status = getPermissionStatus()
235
+ val waiters = permissionWaiters.toList()
236
+ permissionWaiters.clear()
237
+ waiters.forEach { it(status) }
238
+ }
239
+
240
+ componentActivity.addOnNewIntentListener { intent ->
241
+ handleIntent(intent)
242
+ }
243
+ }
244
+
245
+ private fun handleIntent(intent: Intent?) {
246
+ if (intent == null || !intent.isPushTap() || intent.getBooleanExtra(EXTRA_HANDLED, false)) {
247
+ return
248
+ }
249
+
250
+ intent.putExtra(EXTRA_HANDLED, true)
251
+ emitPress(intent.toPushMessage())
252
+ }
253
+
254
+ private fun applyFirebaseConfig(context: Context, config: AndroidFirebaseConfig) {
255
+ if (!config.hasRequiredFields() || FirebaseApp.getApps(context).isNotEmpty()) {
256
+ return
257
+ }
258
+
259
+ try {
260
+ val options =
261
+ FirebaseOptions.Builder()
262
+ .setProjectId(config.projectId!!.trim())
263
+ .setApplicationId(config.applicationId!!.trim())
264
+ .setApiKey(config.apiKey!!.trim())
265
+ .setGcmSenderId(config.gcmSenderId!!.trim())
266
+ .build()
267
+ FirebaseApp.initializeApp(context, options)
268
+ } catch (_: Exception) {
269
+ // Keep initialize quiet; getCredentials reports a missing Firebase app.
270
+ }
271
+ }
272
+
273
+ private fun emitPress(message: PushMessage) {
274
+ val listener = onNotificationPress
275
+ if (listener != null) {
276
+ listener(message)
277
+ } else {
278
+ synchronized(lock) {
279
+ pendingPress = message
280
+ }
281
+ }
282
+ }
283
+ }
284
+
285
+ private fun Application.currentActivityOrNull(): Activity? {
286
+ return try {
287
+ val activityThreadClass = Class.forName("android.app.ActivityThread")
288
+ val activityThread = activityThreadClass.getMethod("currentActivityThread").invoke(null)
289
+ val activitiesField = activityThreadClass.getDeclaredField("mActivities")
290
+ activitiesField.isAccessible = true
291
+ val activities = activitiesField.get(activityThread) as Map<*, *>
292
+ activities.values.firstNotNullOfOrNull { record ->
293
+ val recordClass = record?.javaClass ?: return@firstNotNullOfOrNull null
294
+ val paused = recordClass.getDeclaredField("paused").apply { isAccessible = true }.getBoolean(record)
295
+ if (paused) {
296
+ return@firstNotNullOfOrNull null
297
+ }
298
+ recordClass.getDeclaredField("activity").apply { isAccessible = true }.get(record) as? Activity
299
+ }
300
+ } catch (_: Exception) {
301
+ null
302
+ }
303
+ }
304
+
305
+ private fun Intent.isPushTap(): Boolean {
306
+ val extras = extras ?: return false
307
+ return extras.containsKey("google.message_id") ||
308
+ extras.containsKey("google.sent_time") ||
309
+ extras.containsKey("gcm.n.e") ||
310
+ extras.containsKey("gcm.notification.title")
311
+ }
312
+
313
+ private fun Intent.toPushMessage(): PushMessage {
314
+ val extras = extras ?: Bundle()
315
+ val data = linkedMapOf<String, String>()
316
+ for (key in extras.keySet()) {
317
+ if (key.startsWith("google.") || key.startsWith("gcm.") || key == EXTRA_HANDLED_KEY) {
318
+ continue
319
+ }
320
+ @Suppress("DEPRECATION")
321
+ val value = extras.get(key) ?: continue
322
+ data[key] = value.toString()
323
+ }
324
+
325
+ return PushMessage(
326
+ extras.getString("google.message_id"),
327
+ extras.getString("gcm.n.title")
328
+ ?: extras.getString("gcm.notification.title")
329
+ ?: extras.getString("title"),
330
+ extras.getString("gcm.n.body")
331
+ ?: extras.getString("gcm.notification.body")
332
+ ?: extras.getString("body"),
333
+ data
334
+ )
335
+ }
336
+
337
+ private fun AndroidFirebaseConfig.hasRequiredFields(): Boolean {
338
+ return !projectId.isNullOrBlank() &&
339
+ !applicationId.isNullOrBlank() &&
340
+ !apiKey.isNullOrBlank() &&
341
+ !gcmSenderId.isNullOrBlank()
342
+ }
343
+
344
+ private const val EXTRA_HANDLED_KEY = "pushsignal.handled"
345
+
346
+ internal fun RemoteMessage.toPushMessage(): PushMessage {
347
+ return PushMessage(
348
+ messageId,
349
+ notification?.title,
350
+ notification?.body,
351
+ data
352
+ )
353
+ }
@@ -0,0 +1,34 @@
1
+ package com.margelo.nitro.pushsignal
2
+
3
+ import android.content.ContentProvider
4
+ import android.content.ContentValues
5
+ import android.database.Cursor
6
+ import android.net.Uri
7
+
8
+ class PushSignalInitProvider : ContentProvider() {
9
+ override fun onCreate(): Boolean {
10
+ context?.let(PushSignalCenter::attach)
11
+ return true
12
+ }
13
+
14
+ override fun query(
15
+ uri: Uri,
16
+ projection: Array<out String>?,
17
+ selection: String?,
18
+ selectionArgs: Array<out String>?,
19
+ sortOrder: String?
20
+ ): Cursor? = null
21
+
22
+ override fun getType(uri: Uri): String? = null
23
+
24
+ override fun insert(uri: Uri, values: ContentValues?): Uri? = null
25
+
26
+ override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int = 0
27
+
28
+ override fun update(
29
+ uri: Uri,
30
+ values: ContentValues?,
31
+ selection: String?,
32
+ selectionArgs: Array<out String>?
33
+ ): Int = 0
34
+ }
@@ -0,0 +1,15 @@
1
+ package com.margelo.nitro.pushsignal
2
+
3
+ import com.google.firebase.messaging.FirebaseMessagingService
4
+ import com.google.firebase.messaging.RemoteMessage
5
+
6
+ class PushSignalMessagingService : FirebaseMessagingService() {
7
+ override fun onCreate() {
8
+ super.onCreate()
9
+ PushSignalCenter.attach(applicationContext)
10
+ }
11
+
12
+ override fun onMessageReceived(message: RemoteMessage) {
13
+ PushSignalCenter.emitMessage(message)
14
+ }
15
+ }
@@ -0,0 +1,22 @@
1
+ package com.margelo.nitro.pushsignal
2
+
3
+ import com.facebook.react.BaseReactPackage
4
+ import com.facebook.react.bridge.NativeModule
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.module.model.ReactModuleInfoProvider
7
+
8
+ class PushSignalPackage : BaseReactPackage() {
9
+ override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
10
+ return null
11
+ }
12
+
13
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
14
+ return ReactModuleInfoProvider { HashMap() }
15
+ }
16
+
17
+ companion object {
18
+ init {
19
+ System.loadLibrary("pushsignal")
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,38 @@
1
+ import NitroModules
2
+
3
+ class PushSignal: HybridPushSignalSpec {
4
+ override init() {
5
+ super.init()
6
+ PushSignalCenter.shared.install()
7
+ }
8
+
9
+ func initialize(config: AndroidFirebaseConfig) throws {
10
+ _ = config
11
+ }
12
+
13
+ func getPermissionStatus() throws -> Promise<PermissionStatus> {
14
+ return Promise.async {
15
+ await PushSignalCenter.shared.permissionStatus()
16
+ }
17
+ }
18
+
19
+ func requestPermission() throws -> Promise<PermissionStatus> {
20
+ return Promise.async {
21
+ await PushSignalCenter.shared.requestPermission()
22
+ }
23
+ }
24
+
25
+ func getCredentials() throws -> Promise<PushCredentials> {
26
+ return Promise.async {
27
+ try await PushSignalCenter.shared.fetchCredentials()
28
+ }
29
+ }
30
+
31
+ func setOnMessage(callback: @escaping (PushMessage) -> Void) throws {
32
+ PushSignalCenter.shared.onMessage = callback
33
+ }
34
+
35
+ func setOnNotificationPress(callback: @escaping (PushMessage) -> Void) throws {
36
+ PushSignalCenter.shared.onNotificationPress = callback
37
+ }
38
+ }