Skip to content

Commit d983455

Browse files
authored
Merge pull request #212 from react-native-push-notification-ios/next
2 parents f41002a + 220e235 commit d983455

File tree

9 files changed

+846
-84
lines changed

9 files changed

+846
-84
lines changed

README.md

Lines changed: 126 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77

88
React Native Push Notification API for iOS.
99

10+
| Notification | With Action | With TextInput Action |
11+
| ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
12+
| <img src="https://user-images.githubusercontent.com/6936373/97115527-77c6ee80-173a-11eb-8440-049590a25f31.jpeg" width="320"/> | <img src="https://user-images.githubusercontent.com/6936373/97115526-772e5800-173a-11eb-8b51-c5263bced07a.jpeg" width="320"/> | <img src="https://user-images.githubusercontent.com/6936373/97115522-74cbfe00-173a-11eb-9644-fc1d5e634d6b.jpeg" width="320"/> |
13+
1014
## Getting started
1115

1216
### Install
@@ -89,11 +93,6 @@ At the top of the file:
8993
Then, add the following lines:
9094

9195
```objective-c
92-
// Required to register for notifications
93-
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
94-
{
95-
[RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings];
96-
}
9796
// Required for the register event.
9897
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
9998
{
@@ -110,20 +109,13 @@ fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
110109
{
111110
[RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
112111
}
113-
// IOS 10+ Required for localNotification event
112+
// Required for localNotification event
114113
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
115114
didReceiveNotificationResponse:(UNNotificationResponse *)response
116115
withCompletionHandler:(void (^)(void))completionHandler
117116
{
118117
[RNCPushNotificationIOS didReceiveNotificationResponse:response];
119-
completionHandler();
120118
}
121-
// IOS 4-10 Required for the localNotification event.
122-
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
123-
{
124-
[RNCPushNotificationIOS didReceiveLocalNotification:notification];
125-
}
126-
127119
```
128120

129121
And then in your AppDelegate implementation, add the following:
@@ -184,6 +176,57 @@ export const App = () => {
184176
};
185177
```
186178

179+
## How to perform different action based on user selected action.
180+
181+
```js
182+
export const App = () => {
183+
const [permissions, setPermissions] = useState({});
184+
185+
/**
186+
* By calling this function, notification with category `userAction` will have action buttons
187+
*/
188+
const setNotificationCategories = () => {
189+
PushNotificationIOS.setNotificationCategories([
190+
{
191+
id: 'userAction',
192+
actions: [
193+
{id: 'open', title: 'Open', options: {foreground: true}},
194+
{
195+
id: 'ignore',
196+
title: 'Desruptive',
197+
options: {foreground: true, destructive: true},
198+
},
199+
{
200+
id: 'text',
201+
title: 'Text Input',
202+
options: {foreground: true},
203+
textInput: {buttonTitle: 'Send'},
204+
},
205+
],
206+
},
207+
]);
208+
};
209+
210+
useEffect(() => {
211+
PushNotificationIOS.addEventListener('notification', onRemoteNotification);
212+
});
213+
214+
const onRemoteNotification = (notification) => {
215+
const actionIdentifier = notification.getActionIdentifier();
216+
217+
if (actionIdentifier === 'open') {
218+
// Perform action based on open action
219+
}
220+
221+
if (actionIdentifier === 'text') {
222+
// Text that of user input.
223+
const userText = notification.getUserText();
224+
// Perform action based on textinput action
225+
}
226+
};
227+
};
228+
```
229+
187230
# Reference
188231

189232
## Methods
@@ -194,6 +237,7 @@ export const App = () => {
194237
PushNotificationIOS.presentLocalNotification(details);
195238
```
196239

240+
_Deprecated_ - use `addNotificationRequest` instead.
197241
Schedules the localNotification for immediate presentation.
198242

199243
**Parameters:**
@@ -221,6 +265,7 @@ details is an object containing:
221265
PushNotificationIOS.scheduleLocalNotification(details);
222266
```
223267

268+
_Deprecated_ - use `addNotificationRequest` instead.
224269
Schedules the localNotification for future presentation.
225270

226271
**Parameters:**
@@ -244,13 +289,78 @@ details is an object containing:
244289

245290
---
246291

247-
### `cancelAllLocalNotifications()`
292+
### `addNotificationRequest()`
293+
294+
```jsx
295+
PushNotificationIOS.addNotificationRequest(request);
296+
```
297+
298+
Sends notificationRequest to notification center at specified firedate.
299+
Fires immediately if firedate is not set.
300+
301+
**Parameters:**
302+
303+
| Name | Type | Required | Description |
304+
| ------- | ------ | -------- | ----------- |
305+
| request | object | Yes | See below. |
306+
307+
request is an object containing:
308+
309+
- `id`: Identifier of the notification. Required in order to be able to retrieve specific notification. (required)
310+
- `title`: A short description of the reason for the alert.
311+
- `subtitle`: A secondary description of the reason for the alert.
312+
- `body` : The message displayed in the notification alert.
313+
- `badge` The number to display as the app's icon badge. Setting the number to 0 removes the icon badge.
314+
- `fireDate` : The date and time when the system should deliver the notification.
315+
- `repeats` : Sets notification to repeat daily. Must be used with fireDate.
316+
- `sound` : The sound played when the notification is fired.
317+
- `category` : The category of this notification, required for actionable notifications.
318+
- `isSilent` : If true, the notification will appear without sound.
319+
- `userInfo` : An object containing additional notification data.
320+
321+
---
322+
323+
### `setNotificationCategories()`
324+
325+
```jsx
326+
PushNotificationIOS.setNotificationCategories(categories);
327+
```
328+
329+
Sets category for the notification center.
330+
Allows you to add specific actions for notification with specific category.
331+
332+
**Parameters:**
333+
334+
| Name | Type | Required | Description |
335+
| ---------- | -------- | -------- | ----------- |
336+
| categories | object[] | Yes | See below. |
337+
338+
`category` is an object containing:
339+
340+
- `id`: Identifier of the notification category. Notification with this category will have the specified actions. (required)
341+
- `actions`: An array of notification actions to be attached to the notification of category id.
342+
343+
`action` is an object containing:
344+
345+
- `id`: Identifier of Action. This value will be returned as actionIdentifier when notification is received.
346+
- `title`: Text to be shown on notification action button.
347+
- `options`: Options for notification action.
348+
- `foreground`: If `true`, action will be displayed on notification.
349+
- `destructive`: If `true`, action will be displayed as destructive notification.
350+
- `authenticationRequired`: If `true`, action will only be displayed for authenticated user.
351+
- `textInput`: Option for textInput action. If textInput prop exists, then user action will automatically become a text input action. The text user inputs will be in the userText field of the received notification.
352+
- `buttonTitle`: Text to be shown on button when user finishes text input. Default is "Send" or its equivalent word in user's language setting.
353+
- `placeholder`: Placeholder for text input for text input action.
354+
355+
---
356+
357+
### `remooveAllPendingNotificationRequests()`
248358

249359
```jsx
250-
PushNotificationIOS.cancelAllLocalNotifications();
360+
PushNotificationIOS.remooveAllPendingNotificationRequests();
251361
```
252362

253-
Cancels all scheduled localNotifications
363+
Removes all pending notification requests in the notification center.
254364

255365
---
256366

example/App.js

Lines changed: 98 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -55,28 +55,23 @@ export const App = () => {
5555

5656
return () => {
5757
PushNotificationIOS.removeEventListener('register');
58-
PushNotificationIOS.removeEventListener(
59-
'registrationError'
60-
);
61-
PushNotificationIOS.removeEventListener(
62-
'notification'
63-
);
64-
PushNotificationIOS.removeEventListener(
65-
'localNotification'
66-
);
58+
PushNotificationIOS.removeEventListener('registrationError');
59+
PushNotificationIOS.removeEventListener('notification');
60+
PushNotificationIOS.removeEventListener('localNotification');
6761
};
62+
// eslint-disable-next-line react-hooks/exhaustive-deps
6863
}, []);
6964

7065
const sendNotification = () => {
7166
DeviceEventEmitter.emit('remoteNotificationReceived', {
7267
remote: true,
7368
aps: {
74-
alert: 'Sample notification',
75-
badge: '+1',
69+
alert: {title: 'title', subtitle: 'subtitle', body: 'body'},
70+
badge: 1,
7671
sound: 'default',
77-
alertTitle: 'title',
7872
category: 'REACT_NATIVE',
7973
'content-available': 1,
74+
'mutable-content': 1,
8075
},
8176
});
8277
};
@@ -87,7 +82,7 @@ export const App = () => {
8782
aps: {
8883
category: 'REACT_NATIVE',
8984
'content-available': 1,
90-
}
85+
},
9186
});
9287
};
9388

@@ -102,10 +97,70 @@ export const App = () => {
10297
const scheduleLocalNotification = () => {
10398
PushNotificationIOS.scheduleLocalNotification({
10499
alertBody: 'Test Local Notification',
105-
fireDate: new Date().toISOString(),
100+
fireDate: new Date(new Date().valueOf() + 2000).toISOString(),
106101
});
107102
};
108103

104+
const addNotificationRequest = () => {
105+
PushNotificationIOS.addNotificationRequest({
106+
id: 'test',
107+
title: 'title',
108+
subtitle: 'subtitle',
109+
body: 'body',
110+
category: 'test',
111+
threadId: 'thread-id',
112+
fireDate: new Date(new Date().valueOf() + 2000),
113+
repeats: true,
114+
});
115+
};
116+
117+
const getPendingNotificationRequests = () => {
118+
PushNotificationIOS.getPendingNotificationRequests((requests) => {
119+
Alert.alert('Push Notification Received', JSON.stringify(requests), [
120+
{
121+
text: 'Dismiss',
122+
onPress: null,
123+
},
124+
]);
125+
});
126+
};
127+
128+
const setNotificationCategories = async () => {
129+
PushNotificationIOS.setNotificationCategories([
130+
{
131+
id: 'test',
132+
actions: [
133+
{id: 'open', title: 'Open', options: {foreground: true}},
134+
{
135+
id: 'ignore',
136+
title: 'Desruptive',
137+
options: {foreground: true, destructive: true},
138+
},
139+
{
140+
id: 'text',
141+
title: 'Text Input',
142+
options: {foreground: true},
143+
textInput: {buttonTitle: 'Send'},
144+
},
145+
],
146+
},
147+
]);
148+
Alert.alert(
149+
'setNotificationCategories',
150+
`Set notification category complete`,
151+
[
152+
{
153+
text: 'Dismiss',
154+
onPress: null,
155+
},
156+
],
157+
);
158+
};
159+
160+
const removeAllPendingNotificationRequests = () => {
161+
PushNotificationIOS.removeAllPendingNotificationRequests();
162+
};
163+
109164
const onRegistered = (deviceToken) => {
110165
Alert.alert('Registered For Remote Push', `Device Token: ${deviceToken}`, [
111166
{
@@ -129,10 +184,11 @@ export const App = () => {
129184
};
130185

131186
const onRemoteNotification = (notification) => {
132-
const isClicked = notification.getData().userInteraction === 1
187+
const isClicked = notification.getData().userInteraction === 1;
133188

134189
const result = `
135190
Title: ${notification.getTitle()};\n
191+
Subtitle: ${notification.getSubtitle()};\n
136192
Message: ${notification.getMessage()};\n
137193
badge: ${notification.getBadgeCount()};\n
138194
sound: ${notification.getSound()};\n
@@ -148,7 +204,7 @@ export const App = () => {
148204
},
149205
]);
150206
} else {
151-
Alert.alert('Push Notification Received', result, [
207+
Alert.alert('Push Notification Received', result, [
152208
{
153209
text: 'Dismiss',
154210
onPress: null,
@@ -158,12 +214,16 @@ export const App = () => {
158214
};
159215

160216
const onLocalNotification = (notification) => {
161-
const isClicked = notification.getData().userInteraction === 1
217+
const isClicked = notification.getData().userInteraction === 1;
162218

163219
Alert.alert(
164220
'Local Notification Received',
165221
`Alert title: ${notification.getTitle()},
166-
'Alert message: ${notification.getMessage()},
222+
Alert subtitle: ${notification.getSubtitle()},
223+
Alert message: ${notification.getMessage()},
224+
Thread Id: ${notification.getThreadID()},
225+
Action Id: ${notification.getActionIdentifier()},
226+
User Text: ${notification.getUserText()},
167227
Notification is clicked: ${String(isClicked)}.`,
168228
[
169229
{
@@ -192,8 +252,22 @@ export const App = () => {
192252
onPress={scheduleLocalNotification}
193253
label="Schedule fake local notification"
194254
/>
195-
196-
<Button onPress={sendSilentNotification} label="Send fake silent notification" />
255+
<Button
256+
onPress={addNotificationRequest}
257+
label="Add Notification Request"
258+
/>
259+
<Button
260+
onPress={setNotificationCategories}
261+
label="Set notification categories"
262+
/>
263+
<Button
264+
onPress={removeAllPendingNotificationRequests}
265+
label="Remove All Pending Notification Requests"
266+
/>
267+
<Button
268+
onPress={sendSilentNotification}
269+
label="Send fake silent notification"
270+
/>
197271

198272
<Button
199273
onPress={() => PushNotificationIOS.setApplicationIconBadgeNumber(42)}
@@ -203,6 +277,10 @@ export const App = () => {
203277
onPress={() => PushNotificationIOS.setApplicationIconBadgeNumber(0)}
204278
label="Clear app's icon badge"
205279
/>
280+
<Button
281+
onPress={getPendingNotificationRequests}
282+
label="Get Pending Notification Requests"
283+
/>
206284
<View>
207285
<Button onPress={showPermissions} label="Show enabled permissions" />
208286
<Text>{JSON.stringify(permissions)}</Text>

0 commit comments

Comments
 (0)