123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518 |
- /**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @format
- * @flow
- */
- 'use strict';
- const NativeEventEmitter = require('../EventEmitter/NativeEventEmitter');
- import NativePushNotificationManagerIOS from './NativePushNotificationManagerIOS';
- const invariant = require('invariant');
- const PushNotificationEmitter = new NativeEventEmitter(
- NativePushNotificationManagerIOS,
- );
- const _notifHandlers = new Map();
- const DEVICE_NOTIF_EVENT = 'remoteNotificationReceived';
- const NOTIF_REGISTER_EVENT = 'remoteNotificationsRegistered';
- const NOTIF_REGISTRATION_ERROR_EVENT = 'remoteNotificationRegistrationError';
- const DEVICE_LOCAL_NOTIF_EVENT = 'localNotificationReceived';
- export type ContentAvailable = 1 | null | void;
- export type FetchResult = {
- NewData: string,
- NoData: string,
- ResultFailed: string,
- ...
- };
- /**
- * An event emitted by PushNotificationIOS.
- */
- export type PushNotificationEventName = $Keys<{
- /**
- * Fired when a remote notification is received. The handler will be invoked
- * with an instance of `PushNotificationIOS`.
- */
- notification: string,
- /**
- * Fired when a local notification is received. The handler will be invoked
- * with an instance of `PushNotificationIOS`.
- */
- localNotification: string,
- /**
- * Fired when the user registers for remote notifications. The handler will be
- * invoked with a hex string representing the deviceToken.
- */
- register: string,
- /**
- * Fired when the user fails to register for remote notifications. Typically
- * occurs when APNS is having issues, or the device is a simulator. The
- * handler will be invoked with {message: string, code: number, details: any}.
- */
- registrationError: string,
- ...
- }>;
- /**
- *
- * Handle push notifications for your app, including permission handling and
- * icon badge number.
- *
- * See https://reactnative.dev/docs/pushnotificationios.html
- */
- class PushNotificationIOS {
- _data: Object;
- _alert: string | Object;
- _sound: string;
- _category: string;
- _contentAvailable: ContentAvailable;
- _badgeCount: number;
- _notificationId: string;
- _isRemote: boolean;
- _remoteNotificationCompleteCallbackCalled: boolean;
- _threadID: string;
- static FetchResult: FetchResult = {
- NewData: 'UIBackgroundFetchResultNewData',
- NoData: 'UIBackgroundFetchResultNoData',
- ResultFailed: 'UIBackgroundFetchResultFailed',
- };
- /**
- * Schedules the localNotification for immediate presentation.
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#presentlocalnotification
- */
- static presentLocalNotification(details: Object) {
- invariant(
- NativePushNotificationManagerIOS,
- 'PushNotificationManager is not available.',
- );
- NativePushNotificationManagerIOS.presentLocalNotification(details);
- }
- /**
- * Schedules the localNotification for future presentation.
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#schedulelocalnotification
- */
- static scheduleLocalNotification(details: Object) {
- invariant(
- NativePushNotificationManagerIOS,
- 'PushNotificationManager is not available.',
- );
- NativePushNotificationManagerIOS.scheduleLocalNotification(details);
- }
- /**
- * Cancels all scheduled localNotifications.
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#cancelalllocalnotifications
- */
- static cancelAllLocalNotifications() {
- invariant(
- NativePushNotificationManagerIOS,
- 'PushNotificationManager is not available.',
- );
- NativePushNotificationManagerIOS.cancelAllLocalNotifications();
- }
- /**
- * Remove all delivered notifications from Notification Center.
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#removealldeliverednotifications
- */
- static removeAllDeliveredNotifications(): void {
- invariant(
- NativePushNotificationManagerIOS,
- 'PushNotificationManager is not available.',
- );
- NativePushNotificationManagerIOS.removeAllDeliveredNotifications();
- }
- /**
- * Provides you with a list of the app’s notifications that are still displayed in Notification Center.
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#getdeliverednotifications
- */
- static getDeliveredNotifications(
- callback: (notifications: Array<Object>) => void,
- ): void {
- invariant(
- NativePushNotificationManagerIOS,
- 'PushNotificationManager is not available.',
- );
- NativePushNotificationManagerIOS.getDeliveredNotifications(callback);
- }
- /**
- * Removes the specified notifications from Notification Center
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#removedeliverednotifications
- */
- static removeDeliveredNotifications(identifiers: Array<string>): void {
- invariant(
- NativePushNotificationManagerIOS,
- 'PushNotificationManager is not available.',
- );
- NativePushNotificationManagerIOS.removeDeliveredNotifications(identifiers);
- }
- /**
- * Sets the badge number for the app icon on the home screen.
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#setapplicationiconbadgenumber
- */
- static setApplicationIconBadgeNumber(number: number) {
- invariant(
- NativePushNotificationManagerIOS,
- 'PushNotificationManager is not available.',
- );
- NativePushNotificationManagerIOS.setApplicationIconBadgeNumber(number);
- }
- /**
- * Gets the current badge number for the app icon on the home screen.
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#getapplicationiconbadgenumber
- */
- static getApplicationIconBadgeNumber(callback: Function) {
- invariant(
- NativePushNotificationManagerIOS,
- 'PushNotificationManager is not available.',
- );
- NativePushNotificationManagerIOS.getApplicationIconBadgeNumber(callback);
- }
- /**
- * Cancel local notifications.
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#cancellocalnotification
- */
- static cancelLocalNotifications(userInfo: Object) {
- invariant(
- NativePushNotificationManagerIOS,
- 'PushNotificationManager is not available.',
- );
- NativePushNotificationManagerIOS.cancelLocalNotifications(userInfo);
- }
- /**
- * Gets the local notifications that are currently scheduled.
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#getscheduledlocalnotifications
- */
- static getScheduledLocalNotifications(callback: Function) {
- invariant(
- NativePushNotificationManagerIOS,
- 'PushNotificationManager is not available.',
- );
- NativePushNotificationManagerIOS.getScheduledLocalNotifications(callback);
- }
- /**
- * Attaches a listener to remote or local notification events while the app
- * is running in the foreground or the background.
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#addeventlistener
- */
- static addEventListener(type: PushNotificationEventName, handler: Function) {
- invariant(
- type === 'notification' ||
- type === 'register' ||
- type === 'registrationError' ||
- type === 'localNotification',
- 'PushNotificationIOS only supports `notification`, `register`, `registrationError`, and `localNotification` events',
- );
- let listener;
- if (type === 'notification') {
- listener = PushNotificationEmitter.addListener(
- DEVICE_NOTIF_EVENT,
- notifData => {
- handler(new PushNotificationIOS(notifData));
- },
- );
- } else if (type === 'localNotification') {
- listener = PushNotificationEmitter.addListener(
- DEVICE_LOCAL_NOTIF_EVENT,
- notifData => {
- handler(new PushNotificationIOS(notifData));
- },
- );
- } else if (type === 'register') {
- listener = PushNotificationEmitter.addListener(
- NOTIF_REGISTER_EVENT,
- registrationInfo => {
- handler(registrationInfo.deviceToken);
- },
- );
- } else if (type === 'registrationError') {
- listener = PushNotificationEmitter.addListener(
- NOTIF_REGISTRATION_ERROR_EVENT,
- errorInfo => {
- handler(errorInfo);
- },
- );
- }
- _notifHandlers.set(type, listener);
- }
- /**
- * Removes the event listener. Do this in `componentWillUnmount` to prevent
- * memory leaks.
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#removeeventlistener
- */
- static removeEventListener(
- type: PushNotificationEventName,
- handler: Function,
- ) {
- invariant(
- type === 'notification' ||
- type === 'register' ||
- type === 'registrationError' ||
- type === 'localNotification',
- 'PushNotificationIOS only supports `notification`, `register`, `registrationError`, and `localNotification` events',
- );
- const listener = _notifHandlers.get(type);
- if (!listener) {
- return;
- }
- listener.remove();
- _notifHandlers.delete(type);
- }
- /**
- * Requests notification permissions from iOS, prompting the user's
- * dialog box. By default, it will request all notification permissions, but
- * a subset of these can be requested by passing a map of requested
- * permissions.
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#requestpermissions
- */
- static requestPermissions(permissions?: {
- alert?: boolean,
- badge?: boolean,
- sound?: boolean,
- ...
- }): Promise<{
- alert: boolean,
- badge: boolean,
- sound: boolean,
- ...
- }> {
- let requestedPermissions = {
- alert: true,
- badge: true,
- sound: true,
- };
- if (permissions) {
- requestedPermissions = {
- alert: !!permissions.alert,
- badge: !!permissions.badge,
- sound: !!permissions.sound,
- };
- }
- invariant(
- NativePushNotificationManagerIOS,
- 'PushNotificationManager is not available.',
- );
- return NativePushNotificationManagerIOS.requestPermissions(
- requestedPermissions,
- );
- }
- /**
- * Unregister for all remote notifications received via Apple Push Notification service.
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#abandonpermissions
- */
- static abandonPermissions() {
- invariant(
- NativePushNotificationManagerIOS,
- 'PushNotificationManager is not available.',
- );
- NativePushNotificationManagerIOS.abandonPermissions();
- }
- /**
- * See what push permissions are currently enabled. `callback` will be
- * invoked with a `permissions` object.
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#checkpermissions
- */
- static checkPermissions(callback: Function) {
- invariant(typeof callback === 'function', 'Must provide a valid callback');
- invariant(
- NativePushNotificationManagerIOS,
- 'PushNotificationManager is not available.',
- );
- NativePushNotificationManagerIOS.checkPermissions(callback);
- }
- /**
- * This method returns a promise that resolves to either the notification
- * object if the app was launched by a push notification, or `null` otherwise.
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#getinitialnotification
- */
- static getInitialNotification(): Promise<?PushNotificationIOS> {
- invariant(
- NativePushNotificationManagerIOS,
- 'PushNotificationManager is not available.',
- );
- return NativePushNotificationManagerIOS.getInitialNotification().then(
- notification => {
- return notification && new PushNotificationIOS(notification);
- },
- );
- }
- /**
- * You will never need to instantiate `PushNotificationIOS` yourself.
- * Listening to the `notification` event and invoking
- * `getInitialNotification` is sufficient
- *
- */
- constructor(nativeNotif: Object) {
- this._data = {};
- this._remoteNotificationCompleteCallbackCalled = false;
- this._isRemote = nativeNotif.remote;
- if (this._isRemote) {
- this._notificationId = nativeNotif.notificationId;
- }
- if (nativeNotif.remote) {
- // Extract data from Apple's `aps` dict as defined:
- // https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html
- Object.keys(nativeNotif).forEach(notifKey => {
- const notifVal = nativeNotif[notifKey];
- if (notifKey === 'aps') {
- this._alert = notifVal.alert;
- this._sound = notifVal.sound;
- this._badgeCount = notifVal.badge;
- this._category = notifVal.category;
- this._contentAvailable = notifVal['content-available'];
- this._threadID = notifVal['thread-id'];
- } else {
- this._data[notifKey] = notifVal;
- }
- });
- } else {
- // Local notifications aren't being sent down with `aps` dict.
- this._badgeCount = nativeNotif.applicationIconBadgeNumber;
- this._sound = nativeNotif.soundName;
- this._alert = nativeNotif.alertBody;
- this._data = nativeNotif.userInfo;
- this._category = nativeNotif.category;
- }
- }
- /**
- * This method is available for remote notifications that have been received via:
- * `application:didReceiveRemoteNotification:fetchCompletionHandler:`
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#finish
- */
- finish(fetchResult: string) {
- if (
- !this._isRemote ||
- !this._notificationId ||
- this._remoteNotificationCompleteCallbackCalled
- ) {
- return;
- }
- this._remoteNotificationCompleteCallbackCalled = true;
- invariant(
- NativePushNotificationManagerIOS,
- 'PushNotificationManager is not available.',
- );
- NativePushNotificationManagerIOS.onFinishRemoteNotification(
- this._notificationId,
- fetchResult,
- );
- }
- /**
- * An alias for `getAlert` to get the notification's main message string
- */
- getMessage(): ?string | ?Object {
- // alias because "alert" is an ambiguous name
- return this._alert;
- }
- /**
- * Gets the sound string from the `aps` object
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#getsound
- */
- getSound(): ?string {
- return this._sound;
- }
- /**
- * Gets the category string from the `aps` object
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#getcategory
- */
- getCategory(): ?string {
- return this._category;
- }
- /**
- * Gets the notification's main message from the `aps` object
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#getalert
- */
- getAlert(): ?string | ?Object {
- return this._alert;
- }
- /**
- * Gets the content-available number from the `aps` object
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#getcontentavailable
- */
- getContentAvailable(): ContentAvailable {
- return this._contentAvailable;
- }
- /**
- * Gets the badge count number from the `aps` object
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#getbadgecount
- */
- getBadgeCount(): ?number {
- return this._badgeCount;
- }
- /**
- * Gets the data object on the notif
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#getdata
- */
- getData(): ?Object {
- return this._data;
- }
- /**
- * Gets the thread ID on the notif
- *
- * See https://reactnative.dev/docs/pushnotificationios.html#getthreadid
- */
- getThreadID(): ?string {
- return this._threadID;
- }
- }
- module.exports = PushNotificationIOS;
|