react-native-push-signal 0.1.4 → 0.1.6
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/README.md +2 -8
- package/README.ru.md +2 -8
- package/android/src/main/java/com/margelo/nitro/pushsignal/PushSignal.kt +1 -1
- package/android/src/main/java/com/margelo/nitro/pushsignal/PushSignalCenter.kt +23 -69
- package/ios/PushSignal.swift +1 -1
- package/ios/PushSignalCenter.swift +89 -73
- package/ios/PushSignalLaunchStore.m +11 -3
- package/lib/module/pushSignal.native.js +5 -7
- package/lib/module/pushSignal.native.js.map +1 -1
- package/lib/typescript/src/PushSignal.nitro.d.ts +2 -2
- package/lib/typescript/src/PushSignal.nitro.d.ts.map +1 -1
- package/lib/typescript/src/pushSignal.native.d.ts.map +1 -1
- package/nitrogen/generated/android/c++/JHybridPushSignalSpec.cpp +4 -5
- package/nitrogen/generated/android/c++/JHybridPushSignalSpec.hpp +1 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/pushsignal/HybridPushSignalSpec.kt +2 -2
- package/nitrogen/generated/android/pushsignalOnLoad.cpp +0 -2
- package/nitrogen/generated/ios/PushSignal-Swift-Cxx-Bridge.cpp +0 -25
- package/nitrogen/generated/ios/PushSignal-Swift-Cxx-Bridge.hpp +0 -91
- package/nitrogen/generated/ios/c++/HybridPushSignalSpecSwift.hpp +1 -1
- package/nitrogen/generated/ios/swift/HybridPushSignalSpec.swift +1 -1
- package/nitrogen/generated/ios/swift/HybridPushSignalSpec_cxx.swift +5 -26
- package/nitrogen/generated/shared/c++/HybridPushSignalSpec.hpp +1 -1
- package/package.json +1 -1
- package/src/PushSignal.nitro.ts +2 -2
- package/src/pushSignal.native.tsx +8 -13
- package/nitrogen/generated/android/c++/JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_bool_____PushMessage.hpp +0 -128
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/pushsignal/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_bool_____PushMessage.kt +0 -78
- package/nitrogen/generated/ios/swift/Func_std__shared_ptr_Promise_std__shared_ptr_Promise_bool_____PushMessage.swift +0 -61
- package/nitrogen/generated/ios/swift/Func_void_bool.swift +0 -46
- package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_Promise_bool__.swift +0 -66
package/README.md
CHANGED
|
@@ -44,10 +44,6 @@ const credentials = await getCredentials();
|
|
|
44
44
|
|
|
45
45
|
const stopMessages = onMessage((message) => {
|
|
46
46
|
console.log('incoming', message);
|
|
47
|
-
if (message.data.silent === '1') {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
return true;
|
|
51
47
|
});
|
|
52
48
|
|
|
53
49
|
const stopPress = onNotificationPress((message) => {
|
|
@@ -118,15 +114,13 @@ If the host app already declares its own `FirebaseMessagingService`, only one se
|
|
|
118
114
|
|
|
119
115
|
| App state | iOS | Android (notification payload) | Android (data-only) |
|
|
120
116
|
| --- | --- | --- | --- |
|
|
121
|
-
| Foreground | `onMessage
|
|
117
|
+
| Foreground | `onMessage` + system banner | `onMessage` + tray (if title/body) | `onMessage` + tray (if title/body) |
|
|
122
118
|
| Background / killed | System banner. Tap → `onNotificationPress` | System banner. Tap → `onNotificationPress` | No banner. `onMessage` if the process is alive |
|
|
123
119
|
|
|
124
|
-
- `onMessage` — the push arrived while the app is in the foreground (and Android data messages while the process is alive).
|
|
120
|
+
- `onMessage` — the push arrived while the app is in the foreground (and Android data messages while the process is alive). Listeners only receive the payload; they do not control the banner.
|
|
125
121
|
- `onNotificationPress` — the user opened the notification, including a cold start.
|
|
126
122
|
- On iOS, a visible push received in the background or when the app is killed is delivered on tap, not through `onMessage`. That is an OS limit.
|
|
127
123
|
|
|
128
|
-
If `onMessage` throws or takes longer than about 2 seconds, the library does not show a banner.
|
|
129
|
-
|
|
130
124
|
## Web
|
|
131
125
|
|
|
132
126
|
`initialize()` resolves. `getCredentials()` throws. Listeners (`onMessage`, `onNotificationPress`) are no-ops.
|
package/README.ru.md
CHANGED
|
@@ -44,10 +44,6 @@ const credentials = await getCredentials();
|
|
|
44
44
|
|
|
45
45
|
const stopMessages = onMessage((message) => {
|
|
46
46
|
console.log('incoming', message);
|
|
47
|
-
if (message.data.silent === '1') {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
return true;
|
|
51
47
|
});
|
|
52
48
|
|
|
53
49
|
const stopPress = onNotificationPress((message) => {
|
|
@@ -118,15 +114,13 @@ apply plugin: "com.google.gms.google-services"
|
|
|
118
114
|
|
|
119
115
|
| Состояние | iOS | Android (notification payload) | Android (data-only) |
|
|
120
116
|
| --- | --- | --- | --- |
|
|
121
|
-
| Foreground | `onMessage
|
|
117
|
+
| Foreground | `onMessage` + системный баннер | `onMessage` + tray (если есть title/body) | `onMessage` + tray (если есть title/body) |
|
|
122
118
|
| Background / killed | Системный баннер. Тап → `onNotificationPress` | Системный баннер. Тап → `onNotificationPress` | Баннера нет. `onMessage`, если процесс жив |
|
|
123
119
|
|
|
124
|
-
- `onMessage` — пуш пришёл, пока приложение на переднем плане (и Android data-message, пока процесс жив).
|
|
120
|
+
- `onMessage` — пуш пришёл, пока приложение на переднем плане (и Android data-message, пока процесс жив). Слушатель только получает payload и не управляет баннером.
|
|
125
121
|
- `onNotificationPress` — пользователь открыл уведомление, в том числе при холодном старте.
|
|
126
122
|
- На iOS видимый пуш в фоне или при убитом приложении приходит только в тап, не в `onMessage`. Это ограничение ОС.
|
|
127
123
|
|
|
128
|
-
Если `onMessage` бросил ошибку или не ответил примерно за 2 секунды, баннер не показывается.
|
|
129
|
-
|
|
130
124
|
## Web
|
|
131
125
|
|
|
132
126
|
`initialize()` резолвится. `getCredentials()` бросает ошибку. Слушатели (`onMessage`, `onNotificationPress`) ничего не делают.
|
|
@@ -28,7 +28,7 @@ class PushSignal : HybridPushSignalSpec() {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
override fun setOnMessage(callback: (message: PushMessage) ->
|
|
31
|
+
override fun setOnMessage(callback: (message: PushMessage) -> Unit) {
|
|
32
32
|
PushSignalCenter.setOnMessage(callback)
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -18,23 +18,20 @@ import com.google.firebase.FirebaseOptions
|
|
|
18
18
|
import com.google.firebase.messaging.FirebaseMessaging
|
|
19
19
|
import com.google.android.gms.tasks.Tasks
|
|
20
20
|
import com.google.firebase.messaging.RemoteMessage
|
|
21
|
-
import com.margelo.nitro.core.Promise
|
|
22
21
|
import java.util.Collections
|
|
23
22
|
import java.util.UUID
|
|
24
23
|
import java.util.WeakHashMap
|
|
25
24
|
import java.util.concurrent.CopyOnWriteArrayList
|
|
26
|
-
import java.util.concurrent.atomic.AtomicBoolean
|
|
27
25
|
|
|
28
26
|
internal object PushSignalCenter : Application.ActivityLifecycleCallbacks {
|
|
29
27
|
private const val EXTRA_HANDLED = "pushsignal.handled"
|
|
30
28
|
private const val CHANNEL_ID = "push_signal_default"
|
|
31
|
-
private const val FOREGROUND_TIMEOUT_MS = 2_000L
|
|
32
29
|
|
|
33
30
|
private val lock = Any()
|
|
34
31
|
private val mainHandler = Handler(Looper.getMainLooper())
|
|
35
32
|
@Volatile private var application: Application? = null
|
|
36
33
|
@Volatile private var currentActivity: Activity? = null
|
|
37
|
-
@Volatile private var onMessage: ((PushMessage) ->
|
|
34
|
+
@Volatile private var onMessage: ((PushMessage) -> Unit)? = null
|
|
38
35
|
@Volatile private var onNotificationPress: ((PushMessage) -> Unit)? = null
|
|
39
36
|
@Volatile private var pendingPress: PushMessage? = null
|
|
40
37
|
private val pendingMessages = CopyOnWriteArrayList<PushMessage>()
|
|
@@ -78,23 +75,12 @@ internal object PushSignalCenter : Application.ActivityLifecycleCallbacks {
|
|
|
78
75
|
onDone(applyFirebaseConfig(context, config))
|
|
79
76
|
}
|
|
80
77
|
|
|
81
|
-
fun setOnMessage(callback: (PushMessage) ->
|
|
78
|
+
fun setOnMessage(callback: (PushMessage) -> Unit) {
|
|
82
79
|
onMessage = callback
|
|
83
80
|
val queued = pendingMessages.toList()
|
|
84
81
|
pendingMessages.clear()
|
|
85
82
|
queued.forEach { message ->
|
|
86
|
-
runOnMain {
|
|
87
|
-
val inForeground = startedActivityCount > 0 || currentActivity != null
|
|
88
|
-
resolveShouldShowBanner(message) { shouldShow ->
|
|
89
|
-
if (
|
|
90
|
-
shouldShow &&
|
|
91
|
-
inForeground &&
|
|
92
|
-
(!message.title.isNullOrEmpty() || !message.body.isNullOrEmpty())
|
|
93
|
-
) {
|
|
94
|
-
postForegroundNotification(message)
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
83
|
+
runOnMain { deliverMessage(message) }
|
|
98
84
|
}
|
|
99
85
|
}
|
|
100
86
|
|
|
@@ -145,69 +131,37 @@ internal object PushSignalCenter : Application.ActivityLifecycleCallbacks {
|
|
|
145
131
|
|
|
146
132
|
fun emitMessage(remoteMessage: RemoteMessage) {
|
|
147
133
|
val message = remoteMessage.toPushMessage()
|
|
148
|
-
runOnMain {
|
|
149
|
-
val callback = onMessage
|
|
150
|
-
if (callback == null) {
|
|
151
|
-
pendingMessages.add(message)
|
|
152
|
-
return@runOnMain
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
val inForeground = startedActivityCount > 0 || currentActivity != null
|
|
156
|
-
resolveShouldShowBanner(message) { shouldShow ->
|
|
157
|
-
if (
|
|
158
|
-
shouldShow &&
|
|
159
|
-
inForeground &&
|
|
160
|
-
(!message.title.isNullOrEmpty() || !message.body.isNullOrEmpty())
|
|
161
|
-
) {
|
|
162
|
-
postForegroundNotification(message)
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
private fun runOnMain(block: () -> Unit) {
|
|
169
|
-
if (Looper.myLooper() == Looper.getMainLooper()) {
|
|
170
|
-
block()
|
|
171
|
-
} else {
|
|
172
|
-
mainHandler.post(block)
|
|
173
|
-
}
|
|
134
|
+
runOnMain { deliverMessage(message) }
|
|
174
135
|
}
|
|
175
136
|
|
|
176
|
-
private fun
|
|
177
|
-
message: PushMessage,
|
|
178
|
-
onDone: (Boolean) -> Unit
|
|
179
|
-
) {
|
|
137
|
+
private fun deliverMessage(message: PushMessage) {
|
|
180
138
|
val callback = onMessage
|
|
181
139
|
if (callback == null) {
|
|
182
|
-
|
|
140
|
+
pendingMessages.add(message)
|
|
183
141
|
return
|
|
184
142
|
}
|
|
185
143
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
144
|
+
try {
|
|
145
|
+
// Fire-and-forget: JS only needs the payload.
|
|
146
|
+
callback(message)
|
|
147
|
+
} catch (_: Throwable) {
|
|
148
|
+
// Ignore listener failures.
|
|
191
149
|
}
|
|
192
|
-
mainHandler.postDelayed(timeout, FOREGROUND_TIMEOUT_MS)
|
|
193
150
|
|
|
194
|
-
val
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
151
|
+
val inForeground = startedActivityCount > 0 || currentActivity != null
|
|
152
|
+
if (
|
|
153
|
+
inForeground &&
|
|
154
|
+
(!message.title.isNullOrEmpty() || !message.body.isNullOrEmpty())
|
|
155
|
+
) {
|
|
156
|
+
postForegroundNotification(message)
|
|
199
157
|
}
|
|
158
|
+
}
|
|
200
159
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
.catch { finish(true) }
|
|
207
|
-
}
|
|
208
|
-
.catch { finish(true) }
|
|
209
|
-
} catch (_: Throwable) {
|
|
210
|
-
finish(true)
|
|
160
|
+
private fun runOnMain(block: () -> Unit) {
|
|
161
|
+
if (Looper.myLooper() == Looper.getMainLooper()) {
|
|
162
|
+
block()
|
|
163
|
+
} else {
|
|
164
|
+
mainHandler.post(block)
|
|
211
165
|
}
|
|
212
166
|
}
|
|
213
167
|
|
package/ios/PushSignal.swift
CHANGED
|
@@ -19,7 +19,7 @@ class PushSignal: HybridPushSignalSpec {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
func setOnMessage(callback: @escaping (PushMessage) ->
|
|
22
|
+
func setOnMessage(callback: @escaping (PushMessage) -> Void) throws {
|
|
23
23
|
PushSignalCenter.shared.onMessage = callback
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -22,6 +22,7 @@ final class PushSignalCenter: NSObject, UNUserNotificationCenterDelegate {
|
|
|
22
22
|
|
|
23
23
|
private let lock = NSLock()
|
|
24
24
|
private var didInstall = false
|
|
25
|
+
private var didSwizzleAppDelegate = false
|
|
25
26
|
private var didSwizzleNotificationCenter = false
|
|
26
27
|
private var deviceToken: String?
|
|
27
28
|
private var registrationError: Error?
|
|
@@ -33,7 +34,7 @@ final class PushSignalCenter: NSObject, UNUserNotificationCenterDelegate {
|
|
|
33
34
|
private var recentMessageIds: [String: Date] = [:]
|
|
34
35
|
private weak var forwardingDelegate: UNUserNotificationCenterDelegate?
|
|
35
36
|
|
|
36
|
-
var onMessage: ((PushMessage) ->
|
|
37
|
+
var onMessage: ((PushMessage) -> Void)? {
|
|
37
38
|
didSet {
|
|
38
39
|
flushPendingMessages()
|
|
39
40
|
}
|
|
@@ -91,7 +92,7 @@ final class PushSignalCenter: NSObject, UNUserNotificationCenterDelegate {
|
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
func handleDeviceToken(_ deviceToken: Data) {
|
|
94
|
-
let token = deviceToken.map { String(format: "%
|
|
95
|
+
let token = deviceToken.map { String(format: "%02x", $0) }.joined()
|
|
95
96
|
finishRegistration(result: .success(token))
|
|
96
97
|
}
|
|
97
98
|
|
|
@@ -104,19 +105,13 @@ final class PushSignalCenter: NSObject, UNUserNotificationCenterDelegate {
|
|
|
104
105
|
willPresent notification: UNNotification,
|
|
105
106
|
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
|
|
106
107
|
) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
notification: notification,
|
|
115
|
-
ourOptions: ours,
|
|
116
|
-
completionHandler: completionHandler
|
|
117
|
-
)
|
|
118
|
-
}
|
|
119
|
-
}
|
|
108
|
+
deliverMessage(Self.message(from: notification))
|
|
109
|
+
forwardWillPresent(
|
|
110
|
+
center,
|
|
111
|
+
notification: notification,
|
|
112
|
+
ourOptions: Self.foregroundPresentationOptions,
|
|
113
|
+
completionHandler: completionHandler
|
|
114
|
+
)
|
|
120
115
|
}
|
|
121
116
|
|
|
122
117
|
@objc func userNotificationCenter(
|
|
@@ -205,55 +200,26 @@ final class PushSignalCenter: NSObject, UNUserNotificationCenterDelegate {
|
|
|
205
200
|
return body()
|
|
206
201
|
}
|
|
207
202
|
|
|
208
|
-
private func deliverMessage(_ message: PushMessage)
|
|
203
|
+
private func deliverMessage(_ message: PushMessage) {
|
|
209
204
|
guard shouldEmit(message) else {
|
|
210
|
-
return
|
|
205
|
+
return
|
|
211
206
|
}
|
|
212
207
|
|
|
213
208
|
let callback = synchronized { onMessage }
|
|
214
|
-
|
|
215
209
|
guard let callback else {
|
|
216
210
|
synchronized { pendingMessages.append(message) }
|
|
217
|
-
|
|
218
|
-
// before JS has subscribed.
|
|
219
|
-
return true
|
|
211
|
+
return
|
|
220
212
|
}
|
|
221
213
|
|
|
222
|
-
|
|
214
|
+
emitToJs(callback, message: message)
|
|
223
215
|
}
|
|
224
216
|
|
|
225
|
-
private func
|
|
226
|
-
_ callback: @escaping (PushMessage) ->
|
|
217
|
+
private func emitToJs(
|
|
218
|
+
_ callback: @escaping (PushMessage) -> Void,
|
|
227
219
|
message: PushMessage
|
|
228
|
-
)
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
var resumed = false
|
|
232
|
-
let finish: (Bool) -> Void = { value in
|
|
233
|
-
resumeLock.lock()
|
|
234
|
-
defer { resumeLock.unlock() }
|
|
235
|
-
guard !resumed else {
|
|
236
|
-
return
|
|
237
|
-
}
|
|
238
|
-
resumed = true
|
|
239
|
-
continuation.resume(returning: value)
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
DispatchQueue.main.async {
|
|
243
|
-
Task {
|
|
244
|
-
do {
|
|
245
|
-
let inner = try await callback(message).await()
|
|
246
|
-
let shouldShow = try await inner.await()
|
|
247
|
-
finish(shouldShow)
|
|
248
|
-
} catch {
|
|
249
|
-
finish(true)
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
|
255
|
-
finish(true)
|
|
256
|
-
}
|
|
220
|
+
) {
|
|
221
|
+
DispatchQueue.main.async {
|
|
222
|
+
callback(message)
|
|
257
223
|
}
|
|
258
224
|
}
|
|
259
225
|
|
|
@@ -270,9 +236,7 @@ final class PushSignalCenter: NSObject, UNUserNotificationCenterDelegate {
|
|
|
270
236
|
}
|
|
271
237
|
|
|
272
238
|
for message in queued {
|
|
273
|
-
|
|
274
|
-
_ = await self.invokeOnMessage(callback, message: message)
|
|
275
|
-
}
|
|
239
|
+
self.emitToJs(callback, message: message)
|
|
276
240
|
}
|
|
277
241
|
}
|
|
278
242
|
}
|
|
@@ -307,8 +271,10 @@ final class PushSignalCenter: NSObject, UNUserNotificationCenterDelegate {
|
|
|
307
271
|
forwardingDelegate.userNotificationCenter?(
|
|
308
272
|
center,
|
|
309
273
|
willPresent: notification,
|
|
310
|
-
withCompletionHandler: { (forwarded:
|
|
311
|
-
|
|
274
|
+
withCompletionHandler: { (forwarded: Int) in
|
|
275
|
+
// ObjC optional-protocol bridging exposes options as Int here.
|
|
276
|
+
let forwardedOptions = UNNotificationPresentationOptions(rawValue: UInt(forwarded))
|
|
277
|
+
completionHandler(ourOptions.union(forwardedOptions))
|
|
312
278
|
}
|
|
313
279
|
)
|
|
314
280
|
}
|
|
@@ -474,9 +440,13 @@ final class PushSignalCenter: NSObject, UNUserNotificationCenterDelegate {
|
|
|
474
440
|
}
|
|
475
441
|
|
|
476
442
|
private func swizzleAppDelegate() {
|
|
443
|
+
guard !didSwizzleAppDelegate else {
|
|
444
|
+
return
|
|
445
|
+
}
|
|
477
446
|
guard let appDelegate = UIApplication.shared.delegate else {
|
|
478
447
|
return
|
|
479
448
|
}
|
|
449
|
+
didSwizzleAppDelegate = true
|
|
480
450
|
|
|
481
451
|
let target: AnyClass = type(of: appDelegate)
|
|
482
452
|
let source: AnyClass = PushSignalAppDelegateHook.self
|
|
@@ -521,8 +491,18 @@ final class PushSignalCenter: NSObject, UNUserNotificationCenterDelegate {
|
|
|
521
491
|
|
|
522
492
|
let replacementImp = method_getImplementation(replacementMethod)
|
|
523
493
|
let types = method_getTypeEncoding(replacementMethod)
|
|
494
|
+
let superMethod = class_getSuperclass(target).flatMap { class_getInstanceMethod($0, original) }
|
|
524
495
|
|
|
496
|
+
// No implementation on this class yet — install ours and keep superclass under `replacement`.
|
|
525
497
|
if class_addMethod(target, original, replacementImp, types) {
|
|
498
|
+
if let superMethod {
|
|
499
|
+
class_addMethod(
|
|
500
|
+
target,
|
|
501
|
+
replacement,
|
|
502
|
+
method_getImplementation(superMethod),
|
|
503
|
+
method_getTypeEncoding(superMethod)
|
|
504
|
+
)
|
|
505
|
+
}
|
|
526
506
|
return
|
|
527
507
|
}
|
|
528
508
|
|
|
@@ -543,17 +523,16 @@ private final class PushSignalAppDelegateHook: NSObject {
|
|
|
543
523
|
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
|
|
544
524
|
) {
|
|
545
525
|
PushSignalCenter.shared.handleDeviceToken(deviceToken)
|
|
546
|
-
|
|
547
|
-
|
|
526
|
+
forwardToOriginal(
|
|
527
|
+
hooked: #selector(
|
|
528
|
+
UIApplicationDelegate.application(_:didRegisterForRemoteNotificationsWithDeviceToken:)
|
|
529
|
+
),
|
|
530
|
+
original: #selector(
|
|
531
|
+
PushSignalAppDelegateHook.pushSignal_application(_:didRegisterForRemoteNotificationsWithDeviceToken:)
|
|
532
|
+
),
|
|
533
|
+
application: application,
|
|
534
|
+
deviceToken: deviceToken
|
|
548
535
|
)
|
|
549
|
-
guard responds(to: selector),
|
|
550
|
-
let method = class_getInstanceMethod(type(of: self), selector)
|
|
551
|
-
else {
|
|
552
|
-
return
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
typealias Fn = @convention(c) (Any, Selector, UIApplication, Data) -> Void
|
|
556
|
-
unsafeBitCast(method_getImplementation(method), to: Fn.self)(self, selector, application, deviceToken)
|
|
557
536
|
}
|
|
558
537
|
|
|
559
538
|
@objc func pushSignal_application(
|
|
@@ -561,17 +540,54 @@ private final class PushSignalAppDelegateHook: NSObject {
|
|
|
561
540
|
didFailToRegisterForRemoteNotificationsWithError error: Error
|
|
562
541
|
) {
|
|
563
542
|
PushSignalCenter.shared.handleRegistrationError(error)
|
|
564
|
-
|
|
565
|
-
|
|
543
|
+
forwardToOriginal(
|
|
544
|
+
hooked: #selector(
|
|
545
|
+
UIApplicationDelegate.application(_:didFailToRegisterForRemoteNotificationsWithError:)
|
|
546
|
+
),
|
|
547
|
+
original: #selector(
|
|
548
|
+
PushSignalAppDelegateHook.pushSignal_application(_:didFailToRegisterForRemoteNotificationsWithError:)
|
|
549
|
+
),
|
|
550
|
+
application: application,
|
|
551
|
+
error: error as NSError
|
|
566
552
|
)
|
|
567
|
-
|
|
568
|
-
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
private func forwardToOriginal(
|
|
556
|
+
hooked: Selector,
|
|
557
|
+
original: Selector,
|
|
558
|
+
application: UIApplication,
|
|
559
|
+
deviceToken: Data
|
|
560
|
+
) {
|
|
561
|
+
guard responds(to: original),
|
|
562
|
+
let cls = object_getClass(self),
|
|
563
|
+
let originalImp = class_getMethodImplementation(cls, original),
|
|
564
|
+
let hookedImp = class_getMethodImplementation(cls, hooked),
|
|
565
|
+
originalImp != hookedImp
|
|
566
|
+
else {
|
|
567
|
+
return
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
typealias Fn = @convention(c) (Any, Selector, UIApplication, Data) -> Void
|
|
571
|
+
unsafeBitCast(originalImp, to: Fn.self)(self, original, application, deviceToken)
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
private func forwardToOriginal(
|
|
575
|
+
hooked: Selector,
|
|
576
|
+
original: Selector,
|
|
577
|
+
application: UIApplication,
|
|
578
|
+
error: NSError
|
|
579
|
+
) {
|
|
580
|
+
guard responds(to: original),
|
|
581
|
+
let cls = object_getClass(self),
|
|
582
|
+
let originalImp = class_getMethodImplementation(cls, original),
|
|
583
|
+
let hookedImp = class_getMethodImplementation(cls, hooked),
|
|
584
|
+
originalImp != hookedImp
|
|
569
585
|
else {
|
|
570
586
|
return
|
|
571
587
|
}
|
|
572
588
|
|
|
573
589
|
typealias Fn = @convention(c) (Any, Selector, UIApplication, NSError) -> Void
|
|
574
|
-
unsafeBitCast(
|
|
590
|
+
unsafeBitCast(originalImp, to: Fn.self)(self, original, application, error)
|
|
575
591
|
}
|
|
576
592
|
}
|
|
577
593
|
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
#import "PushSignalLaunchStore.h"
|
|
2
2
|
#import <UIKit/UIKit.h>
|
|
3
3
|
|
|
4
|
+
// Swift `@objc(PushSignalCenter)` — declared so messaging via `id` type-checks.
|
|
5
|
+
@interface PushSignalCenter : NSObject
|
|
6
|
+
+ (void)installEarly;
|
|
7
|
+
+ (void)bootstrapWithLaunchOptions:(nullable NSDictionary *)launchOptions;
|
|
8
|
+
@end
|
|
9
|
+
|
|
4
10
|
static NSDictionary *sLaunchOptions;
|
|
5
11
|
|
|
6
12
|
NSDictionary *PushSignalCopyLaunchOptions(void) {
|
|
@@ -10,12 +16,14 @@ NSDictionary *PushSignalCopyLaunchOptions(void) {
|
|
|
10
16
|
@implementation PushSignalLaunchStore
|
|
11
17
|
|
|
12
18
|
+ (void)load {
|
|
19
|
+
// String form: `UIApplicationWillFinishLaunchingNotification` is not declared in
|
|
20
|
+
// every UIKit header set, but the system still posts this name.
|
|
13
21
|
[[NSNotificationCenter defaultCenter]
|
|
14
|
-
addObserverForName
|
|
22
|
+
addObserverForName:@"UIApplicationWillFinishLaunchingNotification"
|
|
15
23
|
object:nil
|
|
16
24
|
queue:nil
|
|
17
25
|
usingBlock:^(NSNotification *notification) {
|
|
18
|
-
|
|
26
|
+
id center = NSClassFromString(@"PushSignalCenter");
|
|
19
27
|
if ([center respondsToSelector:@selector(installEarly)]) {
|
|
20
28
|
[center installEarly];
|
|
21
29
|
}
|
|
@@ -27,7 +35,7 @@ NSDictionary *PushSignalCopyLaunchOptions(void) {
|
|
|
27
35
|
queue:nil
|
|
28
36
|
usingBlock:^(NSNotification *notification) {
|
|
29
37
|
sLaunchOptions = [notification.userInfo copy];
|
|
30
|
-
|
|
38
|
+
id center = NSClassFromString(@"PushSignalCenter");
|
|
31
39
|
if ([center respondsToSelector:@selector(bootstrapWithLaunchOptions:)]) {
|
|
32
40
|
[center bootstrapWithLaunchOptions:sLaunchOptions];
|
|
33
41
|
}
|
|
@@ -10,16 +10,14 @@ function bindNativeCallbacks() {
|
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
12
|
nativeCallbacksBound = true;
|
|
13
|
-
PushSignalHybridObject.setOnMessage(
|
|
14
|
-
const
|
|
15
|
-
const results = await Promise.all(listeners.map(async listener => {
|
|
13
|
+
PushSignalHybridObject.setOnMessage(message => {
|
|
14
|
+
for (const listener of [...messageListeners]) {
|
|
16
15
|
try {
|
|
17
|
-
|
|
16
|
+
void listener(message);
|
|
18
17
|
} catch {
|
|
19
|
-
|
|
18
|
+
// Ignore listener failures so one bad subscriber cannot break delivery.
|
|
20
19
|
}
|
|
21
|
-
}
|
|
22
|
-
return results.some(result => result === true);
|
|
20
|
+
}
|
|
23
21
|
});
|
|
24
22
|
PushSignalHybridObject.setOnNotificationPress(message => {
|
|
25
23
|
pressListeners.forEach(listener => listener(message));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NitroModules","PushSignalHybridObject","createHybridObject","messageListeners","Set","pressListeners","nativeCallbacksBound","bindNativeCallbacks","setOnMessage","message","
|
|
1
|
+
{"version":3,"names":["NitroModules","PushSignalHybridObject","createHybridObject","messageListeners","Set","pressListeners","nativeCallbacksBound","bindNativeCallbacks","setOnMessage","message","listener","setOnNotificationPress","forEach","initialize","config","getCredentials","onMessage","add","delete","onNotificationPress"],"sourceRoot":"../../src","sources":["pushSignal.native.tsx"],"mappings":";;AAAA,SAASA,YAAY,QAAQ,4BAA4B;AASzD,MAAMC,sBAAsB,GAC1BD,YAAY,CAACE,kBAAkB,CAAa,YAAY,CAAC;AAE3D,MAAMC,gBAAgB,GAAG,IAAIC,GAAG,CAAoB,CAAC;AACrD,MAAMC,cAAc,GAAG,IAAID,GAAG,CAAiC,CAAC;AAChE,IAAIE,oBAAoB,GAAG,KAAK;AAEhC,SAASC,mBAAmBA,CAAA,EAAG;EAC7B,IAAID,oBAAoB,EAAE;IACxB;EACF;EAEAA,oBAAoB,GAAG,IAAI;EAE3BL,sBAAsB,CAACO,YAAY,CAAEC,OAAO,IAAK;IAC/C,KAAK,MAAMC,QAAQ,IAAI,CAAC,GAAGP,gBAAgB,CAAC,EAAE;MAC5C,IAAI;QACF,KAAKO,QAAQ,CAACD,OAAO,CAAC;MACxB,CAAC,CAAC,MAAM;QACN;MAAA;IAEJ;EACF,CAAC,CAAC;EAEFR,sBAAsB,CAACU,sBAAsB,CAAEF,OAAO,IAAK;IACzDJ,cAAc,CAACO,OAAO,CAAEF,QAAQ,IAAKA,QAAQ,CAACD,OAAO,CAAC,CAAC;EACzD,CAAC,CAAC;AACJ;AAEA,OAAO,SAASI,UAAUA,CAACC,MAA6B,GAAG,CAAC,CAAC,EAAiB;EAC5E,OAAOb,sBAAsB,CAACY,UAAU,CAACC,MAAM,CAAC;AAClD;AAEA,OAAO,SAASC,cAAcA,CAAA,EAA6B;EACzD,OAAOd,sBAAsB,CAACc,cAAc,CAAC,CAAC;AAChD;AAEA,OAAO,SAASC,SAASA,CAACN,QAA2B,EAAc;EACjEH,mBAAmB,CAAC,CAAC;EACrBJ,gBAAgB,CAACc,GAAG,CAACP,QAAQ,CAAC;EAC9B,OAAO,MAAM;IACXP,gBAAgB,CAACe,MAAM,CAACR,QAAQ,CAAC;EACnC,CAAC;AACH;AAEA,OAAO,SAASS,mBAAmBA,CACjCT,QAAwC,EAC5B;EACZH,mBAAmB,CAAC,CAAC;EACrBF,cAAc,CAACY,GAAG,CAACP,QAAQ,CAAC;EAC5B,OAAO,MAAM;IACXL,cAAc,CAACa,MAAM,CAACR,QAAQ,CAAC;EACjC,CAAC;AACH;AAEAH,mBAAmB,CAAC,CAAC","ignoreList":[]}
|
|
@@ -13,7 +13,7 @@ export interface PushMessage {
|
|
|
13
13
|
body?: string;
|
|
14
14
|
data: Record<string, string>;
|
|
15
15
|
}
|
|
16
|
-
export type OnMessageListener = (message: PushMessage) =>
|
|
16
|
+
export type OnMessageListener = (message: PushMessage) => void | Promise<void>;
|
|
17
17
|
export interface AndroidFirebaseConfig {
|
|
18
18
|
project_id?: string;
|
|
19
19
|
mobilesdk_app_id?: string;
|
|
@@ -26,7 +26,7 @@ export interface PushSignal extends HybridObject<{
|
|
|
26
26
|
}> {
|
|
27
27
|
initialize(config: AndroidFirebaseConfig): Promise<void>;
|
|
28
28
|
getCredentials(): Promise<PushCredentials>;
|
|
29
|
-
setOnMessage(callback: (message: PushMessage) =>
|
|
29
|
+
setOnMessage(callback: (message: PushMessage) => void): void;
|
|
30
30
|
setOnNotificationPress(callback: (message: PushMessage) => void): void;
|
|
31
31
|
}
|
|
32
32
|
//# sourceMappingURL=PushSignal.nitro.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PushSignal.nitro.d.ts","sourceRoot":"","sources":["../../../src/PushSignal.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D,8FAA8F;AAC9F,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,YAAY,CAAC;AAChD,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,YAAY,CAAC;AAEvD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,MAAM,iBAAiB,GAAG,CAC9B,OAAO,EAAE,WAAW,KACjB,
|
|
1
|
+
{"version":3,"file":"PushSignal.nitro.d.ts","sourceRoot":"","sources":["../../../src/PushSignal.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D,8FAA8F;AAC9F,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,YAAY,CAAC;AAChD,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,YAAY,CAAC;AAEvD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,MAAM,iBAAiB,GAAG,CAC9B,OAAO,EAAE,WAAW,KACjB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAW,SAAQ,YAAY,CAAC;IAC/C,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,QAAQ,CAAC;CACnB,CAAC;IACA,UAAU,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,cAAc,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC;IAC3C,YAAY,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,GAAG,IAAI,CAAC;IAC7D,sBAAsB,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,GAAG,IAAI,CAAC;CACxE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pushSignal.native.d.ts","sourceRoot":"","sources":["../../../src/pushSignal.native.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,WAAW,EAEZ,MAAM,uBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"pushSignal.native.d.ts","sourceRoot":"","sources":["../../../src/pushSignal.native.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,WAAW,EAEZ,MAAM,uBAAoB,CAAC;AA+B5B,wBAAgB,UAAU,CAAC,MAAM,GAAE,qBAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAED,wBAAgB,cAAc,IAAI,OAAO,CAAC,eAAe,CAAC,CAEzD;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,IAAI,CAMjE;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,GACvC,MAAM,IAAI,CAMZ"}
|
|
@@ -33,11 +33,10 @@ namespace margelo::nitro::pushsignal { struct PushMessage; }
|
|
|
33
33
|
#include "JAndroidFirebaseConfig.hpp"
|
|
34
34
|
#include "PushMessage.hpp"
|
|
35
35
|
#include <functional>
|
|
36
|
-
#include "
|
|
36
|
+
#include "JFunc_void_PushMessage.hpp"
|
|
37
37
|
#include <NitroModules/JNICallable.hpp>
|
|
38
38
|
#include "JPushMessage.hpp"
|
|
39
39
|
#include <unordered_map>
|
|
40
|
-
#include "JFunc_void_PushMessage.hpp"
|
|
41
40
|
|
|
42
41
|
namespace margelo::nitro::pushsignal {
|
|
43
42
|
|
|
@@ -103,9 +102,9 @@ namespace margelo::nitro::pushsignal {
|
|
|
103
102
|
return __promise;
|
|
104
103
|
}();
|
|
105
104
|
}
|
|
106
|
-
void JHybridPushSignalSpec::setOnMessage(const std::function<
|
|
107
|
-
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<
|
|
108
|
-
method(_javaPart,
|
|
105
|
+
void JHybridPushSignalSpec::setOnMessage(const std::function<void(const PushMessage& /* message */)>& callback) {
|
|
106
|
+
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void_PushMessage::javaobject> /* callback */)>("setOnMessage_cxx");
|
|
107
|
+
method(_javaPart, JFunc_void_PushMessage_cxx::fromCpp(callback));
|
|
109
108
|
}
|
|
110
109
|
void JHybridPushSignalSpec::setOnNotificationPress(const std::function<void(const PushMessage& /* message */)>& callback) {
|
|
111
110
|
static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void_PushMessage::javaobject> /* callback */)>("setOnNotificationPress_cxx");
|
|
@@ -56,7 +56,7 @@ namespace margelo::nitro::pushsignal {
|
|
|
56
56
|
// Methods
|
|
57
57
|
std::shared_ptr<Promise<void>> initialize(const AndroidFirebaseConfig& config) override;
|
|
58
58
|
std::shared_ptr<Promise<PushCredentials>> getCredentials() override;
|
|
59
|
-
void setOnMessage(const std::function<
|
|
59
|
+
void setOnMessage(const std::function<void(const PushMessage& /* message */)>& callback) override;
|
|
60
60
|
void setOnNotificationPress(const std::function<void(const PushMessage& /* message */)>& callback) override;
|
|
61
61
|
|
|
62
62
|
private:
|
package/nitrogen/generated/android/kotlin/com/margelo/nitro/pushsignal/HybridPushSignalSpec.kt
CHANGED
|
@@ -38,11 +38,11 @@ abstract class HybridPushSignalSpec: HybridObject() {
|
|
|
38
38
|
@Keep
|
|
39
39
|
abstract fun getCredentials(): Promise<PushCredentials>
|
|
40
40
|
|
|
41
|
-
abstract fun setOnMessage(callback: (message: PushMessage) ->
|
|
41
|
+
abstract fun setOnMessage(callback: (message: PushMessage) -> Unit): Unit
|
|
42
42
|
|
|
43
43
|
@DoNotStrip
|
|
44
44
|
@Keep
|
|
45
|
-
private fun setOnMessage_cxx(callback:
|
|
45
|
+
private fun setOnMessage_cxx(callback: Func_void_PushMessage): Unit {
|
|
46
46
|
val __result = setOnMessage(callback)
|
|
47
47
|
return __result
|
|
48
48
|
}
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
#include <NitroModules/HybridObjectRegistry.hpp>
|
|
17
17
|
|
|
18
18
|
#include "JHybridPushSignalSpec.hpp"
|
|
19
|
-
#include "JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_bool_____PushMessage.hpp"
|
|
20
19
|
#include "JFunc_void_PushMessage.hpp"
|
|
21
20
|
#include <NitroModules/DefaultConstructableObject.hpp>
|
|
22
21
|
|
|
@@ -43,7 +42,6 @@ void registerAllNatives() {
|
|
|
43
42
|
|
|
44
43
|
// Register native JNI methods
|
|
45
44
|
margelo::nitro::pushsignal::JHybridPushSignalSpec::CxxPart::registerNatives();
|
|
46
|
-
margelo::nitro::pushsignal::JFunc_std__shared_ptr_Promise_std__shared_ptr_Promise_bool_____PushMessage_cxx::registerNatives();
|
|
47
45
|
margelo::nitro::pushsignal::JFunc_void_PushMessage_cxx::registerNatives();
|
|
48
46
|
|
|
49
47
|
// Register Nitro Hybrid Objects
|