5
5
6
6
React Native VoIP Push Notification - Currently iOS >= 8.0 only
7
7
8
- ## Motivation
9
-
10
- Since iOS 8.0 there is an execellent feature called ** VoIP Push Notification** ([ PushKit] [ 1 ] ), while in React Native only the traditional push notification is supported which limits the possibilities of building a VoIP app with React Native (like me!).
11
-
12
- To understand the benefits of ** Voip Push Notification** , please see [ VoIP Best Practices] [ 2 ] .
13
-
14
- ** Note 1** : Not sure if Android support this sort of stuff since I'm neither an iOS nor Android expert, from my limited understanding that GCM's [ sending high priority push notification] [ 5 ] might be the case. Correct me if I'm wrong!
15
-
16
- ** Note 2** This module is inspired by [ PushNotificationIOS] [ 6 ] and [ React Native Push Notification] [ 7 ]
17
-
18
8
## RN Version
19
9
20
10
* 1.1.0+ ( RN 40+ )
@@ -103,7 +93,19 @@ Make sure you enabled the folowing in `Xcode` -> `Signing & Capabilities`:
103
93
104
94
- (BOOL)application:(UIApplication * )application didFinishLaunchingWithOptions:(NSDictionary * )launchOptions
105
95
{
106
- ...
96
+ RCTBridge * bridge = [[ RCTBridge alloc] initWithDelegate: self launchOptions: launchOptions ] ;
97
+
98
+
99
+
100
+ // ===== (THIS IS OPTIONAL) =====
101
+ // --- register VoipPushNotification here ASAP rather than in JS. Doing this from the JS side may be too slow for some use cases
102
+ // --- see: https://github.com/react-native-webrtc/react-native-voip-push-notification/issues/59#issuecomment-691685841
103
+ [ RNVoipPushNotificationManager voipRegistration] ;
104
+ // ===== (THIS IS OPTIONAL) =====
105
+
106
+
107
+
108
+ RCTRootView * rootView = [[ RCTRootView alloc] initWithBridge: bridge moduleName:@"AppName" initialProperties: nil ] ;
107
109
}
108
110
109
111
...
@@ -121,13 +123,7 @@ Make sure you enabled the folowing in `Xcode` -> `Signing & Capabilities`:
121
123
// --- The system calls this method when a previously provided push token is no longer valid for use. No action is necessary on your part to reregister the push type. Instead, use this method to notify your server not to send push notifications using the matching push token.
122
124
}
123
125
124
-
125
- // --- Handle incoming pushes (for ios <= 10)
126
- - (void)pushRegistry:(PKPushRegistry * )registry didReceiveIncomingPushWithPayload:(PKPushPayload * )payload forType:(PKPushType)type {
127
- [ RNVoipPushNotificationManager didReceiveIncomingPushWithPayload: payload forType:(NSString * )type] ;
128
- }
129
-
130
- // --- Handle incoming pushes (for ios >= 11)
126
+ // --- Handle incoming pushes
131
127
- (void)pushRegistry:(PKPushRegistry * )registry didReceiveIncomingPushWithPayload:(PKPushPayload * )payload forType:(PKPushType)type withCompletionHandler:(void (^)(void))completion {
132
128
133
129
@@ -160,34 +156,61 @@ Make sure you enabled the folowing in `Xcode` -> `Signing & Capabilities`:
160
156
## Linking:
161
157
162
158
On RN60+, auto linking with pod file should work.
163
- Or you can try below:
164
-
165
- ## Linking Manually:
159
+ <details>
160
+ <summary>Linking Manually</summary>
166
161
167
- ### Add PushKit Framework:
162
+ ### Add PushKit Framework:
163
+
164
+ - In your Xcode project, select `Build Phases` --> `Link Binary With Libraries`
165
+ - Add `PushKit.framework`
166
+
167
+ ### Add RNVoipPushNotification:
168
+
169
+ #### Option 1: Use [rnpm][3]
170
+
171
+ ```bash
172
+ rnpm link react-native-voip-push-notification
173
+ ```
174
+
175
+ ** Note** : If you're using rnpm link make sure the ` Header Search Paths ` is ` recursive ` . (In step 3 of manually linking)
176
+
177
+ #### Option 2: Manually
178
+
179
+ 1 . Drag ` node_modules/react-native-voip-push-notification/ios/RNVoipPushNotification.xcodeproj ` under ` <your_xcode_project>/Libraries `
180
+ 2 . Select ` <your_xcode_project> ` --> ` Build Phases ` --> ` Link Binary With Libraries `
181
+ - Drag ` Libraries/RNVoipPushNotification.xcodeproj/Products/libRNVoipPushNotification.a ` to ` Link Binary With Libraries `
182
+ 3 . Select ` <your_xcode_project> ` --> ` Build Settings `
183
+ - In ` Header Search Paths ` , add ` $(SRCROOT)/../node_modules/react-native-voip-push-notification/ios/RNVoipPushNotification ` with ` recursive `
184
+ </details>
168
185
169
- - In your Xcode project, select `Build Phases` --> `Link Binary With Libraries`
170
- - Add `PushKit.framework`
186
+ ## API and Usage:
171
187
172
- ### Add RNVoipPushNotification :
188
+ #### Native API :
173
189
174
- #### Option 1: Use [rnpm][3]
190
+ Voip Push is time sensitive, these native API mainly used in AppDelegate.m, especially before JS bridge is up.
191
+ This usually
175
192
176
- ```bash
177
- rnpm link react-native-voip-push-notification
178
- ```
193
+ * ` (void)voipRegistration ` ---
194
+ register delegate for PushKit if you like to register in AppDelegate.m ASAP instead JS side ( too late for some use cases )
195
+ * ` (void)didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type ` ---
196
+ call this api to fire 'register' event to JS
197
+ * ` (void)didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type ` ---
198
+ call this api to fire 'notification' event to JS
199
+ * ` (void)addCompletionHandler:(NSString *)uuid completionHandler:(RNVoipPushNotificationCompletion)completionHandler ` ---
200
+ add completionHandler to RNVoipPush module
201
+ * ` (void)removeCompletionHandler:(NSString *)uuid ` ---
202
+ remove completionHandler to RNVoipPush module
179
203
180
- ** Note ** : If you're using rnpm link make sure the ` Header Search Paths ` is ` recursive ` . (In step 3 of manually linking)
204
+ #### JS API:
181
205
182
- #### Option 2: Manually
206
+ * ` registerVoipToken() ` --- JS method to register PushKit delegate
207
+ * ` onVoipNotificationCompleted(notification.uuid) ` --- JS mehtod to tell PushKit we have handled received voip push
183
208
184
- 1 . Drag ` node_modules/react-native-voip-push-notification/ios/RNVoipPushNotification.xcodeproj ` under ` <your_xcode_project>/Libraries `
185
- 2 . Select ` <your_xcode_project> ` --> ` Build Phases ` --> ` Link Binary With Libraries `
186
- - Drag ` Libraries/RNVoipPushNotification.xcodeproj/Products/libRNVoipPushNotification.a ` to ` Link Binary With Libraries `
187
- 3 . Select ` <your_xcode_project> ` --> ` Build Settings `
188
- - In ` Header Search Paths ` , add ` $(SRCROOT)/../node_modules/react-native-voip-push-notification/ios/RNVoipPushNotification ` with ` recursive `
209
+ #### Events:
189
210
190
- ## Usage:
211
+ * ` 'register' ` --- fired when PushKit give us the latest token
212
+ * ` 'notification' ` --- fired when received voip push notification
213
+ * ` 'didLoadWithEvents' ` --- fired when there are not-fired events been cached before js bridge is up
191
214
192
215
``` javascript
193
216
@@ -201,51 +224,48 @@ class MyComponent extends React.Component {
201
224
202
225
...
203
226
204
- componentDidMount () { // or anywhere which is most comfortable and appropriate for you
205
- VoipPushNotification .requestPermissions (); // --- optional, you can use another library to request permissions
206
- VoipPushNotification .registerVoipToken (); // --- required
207
-
208
- VoipPushNotification .addEventListener (' register' , (token ) => {
209
- // --- send token to your apn provider server
210
- });
211
-
212
- VoipPushNotification .addEventListener (' localNotification' , (notification ) => {
213
- // --- when user click local push
214
- });
215
-
216
- VoipPushNotification .addEventListener (' notification' , (notification ) => {
217
- // --- when receive remote voip push, register your VoIP client, show local notification ... etc
218
- // this.doRegisterOrSomething();
227
+ // --- or anywhere which is most comfortable and appropriate for you, usually ASAP
228
+ componentDidMount () {
229
+ VoipPushNotification .registerVoipToken (); // --- register token
230
+
231
+ VoipPushNotification .addEventListener (' didLoadWithEvents' , (events ) => {
232
+ // --- this will fire when there are events occured before js bridge initialized
233
+ // --- use this event to execute your event handler manually by event type
234
+
235
+ if (! events || ! Array .isArray (events) || events .length < 1 ) {
236
+ return ;
237
+ }
238
+ for (let voipPushEvent of events) {
239
+ let { name, data } = voipPushEvent;
240
+ if (name === VoipPushNotification .RNVoipPushRemoteNotificationsRegisteredEvent ) {
241
+ this .onVoipPushNotificationRegistered (data);
242
+ } else if (name === VoipPushNotification .RNVoipPushRemoteNotificationReceivedEvent ) {
243
+ this .onVoipPushNotificationiReceived (data);
244
+ }
245
+ }
246
+ });
219
247
220
- // --- This is a boolean constant exported by this module
221
- // --- you can use this constant to distinguish the app is launched by VoIP push notification or not
222
- if (VoipPushNotification .wakeupByPush ) {
223
- // this.doSomething()
224
-
225
- // --- remember to set this static variable back to false
226
- // --- since the constant are exported only at initialization time, and it will keep the same in the whole app
227
- VoipPushNotification .wakeupByPush = false ;
228
- }
229
-
230
-
231
- // --- optionally, if you `addCompletionHandler` from the native side, once you have done the js jobs to initiate a call, call `completion()`
232
- VoipPushNotification .onVoipNotificationCompleted (notification .getData ().uuid );
233
-
234
-
235
- /**
236
- * Local Notification Payload
237
- *
238
- * - `alertBody` : The message displayed in the notification alert.
239
- * - `alertAction` : The "action" displayed beneath an actionable notification. Defaults to "view";
240
- * - `soundName` : The sound played when the notification is fired (optional).
241
- * - `category` : The category of this notification, required for actionable notifications (optional).
242
- * - `userInfo` : An optional object containing additional notification data.
243
- */
244
- VoipPushNotification .presentLocalNotification ({
245
- alertBody: " hello! " + notification .getMessage ()
246
- });
247
- });
248
- }
248
+ // --- onVoipPushNotificationRegistered
249
+ VoipPushNotification .addEventListener (' register' , (token ) => {
250
+ // --- send token to your apn provider server
251
+ });
252
+
253
+ // --- onVoipPushNotificationiReceived
254
+ VoipPushNotification .addEventListener (' notification' , (notification ) => {
255
+ // --- when receive remote voip push, register your VoIP client, show local notification ... etc
256
+ this .doSomething ();
257
+
258
+ // --- optionally, if you `addCompletionHandler` from the native side, once you have done the js jobs to initiate a call, call `completion()`
259
+ VoipPushNotification .onVoipNotificationCompleted (notification .uuid );
260
+ });
261
+ }
262
+
263
+ // --- unsubscribe event listeners
264
+ componentWillUnmount () {
265
+ VoipPushNotification .removeEventListener (' didLoadWithEvents' );
266
+ VoipPushNotification .removeEventListener (' register' );
267
+ VoipPushNotification .removeEventListener (' notification' );
268
+ }
249
269
...
250
270
}
251
271
@@ -263,6 +283,3 @@ class MyComponent extends React.Component {
263
283
[ 2 ] : https://developer.apple.com/library/ios/documentation/Performance/Conceptual/EnergyGuide-iOS/OptimizeVoIP.html
264
284
[ 3 ] : https://github.com/rnpm/rnpm
265
285
[ 4 ] : https://opensource.org/licenses/ISC
266
- [ 5 ] : https://developers.google.com/cloud-messaging/concept-options#setting-the-priority-of-a-message
267
- [ 6 ] : https://facebook.github.io/react-native/docs/pushnotificationios.html
268
- [ 7 ] : https://github.com/zo0r/react-native-push-notification
0 commit comments