index.ios.js 8.24 KB
Newer Older
Lidan Hifi's avatar
Lidan Hifi committed
1
/**
Lidan Hifi's avatar
Lidan Hifi committed
2
 * @providesModule RNNotifications
Lidan Hifi's avatar
Lidan Hifi committed
3 4
 * @flow
 */
Lidan Hifi's avatar
Lidan Hifi committed
5
"use strict";
6
import { NativeModules, DeviceEventEmitter, NativeAppEventEmitter } from "react-native";
Lidan Hifi's avatar
Lidan Hifi committed
7
import Map from "core-js/library/es6/map";
8
import uuid from "uuid";
9
const NativeRNNotifications = NativeModules.RNNotifications; // eslint-disable-line no-unused-vars
10
import IOSNotification from "./notification.ios";
Lidan Hifi's avatar
Lidan Hifi committed
11

12
export const DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT = "remoteNotificationsRegistered";
13
export const DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT = "remoteNotificationsRegistrationFailed";
14
export const DEVICE_PUSH_KIT_REGISTERED_EVENT = "pushKitRegistered";
15 16 17
export const DEVICE_NOTIFICATION_RECEIVED_FOREGROUND_EVENT = "notificationReceivedForeground";
export const DEVICE_NOTIFICATION_RECEIVED_BACKGROUND_EVENT = "notificationReceivedBackground";
export const DEVICE_NOTIFICATION_OPENED_EVENT = "notificationOpened";
Lidan Hifi's avatar
Lidan Hifi committed
18

19 20 21 22
const DEVICE_NOTIFICATION_ACTION_RECEIVED = "notificationActionReceived";

const _exportedEvents = [
  DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT,
23
  DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT,
24 25 26 27 28
  DEVICE_PUSH_KIT_REGISTERED_EVENT,
  DEVICE_NOTIFICATION_RECEIVED_FOREGROUND_EVENT,
  DEVICE_NOTIFICATION_RECEIVED_BACKGROUND_EVENT,
  DEVICE_NOTIFICATION_OPENED_EVENT
];
Leon Mok's avatar
Leon Mok committed
29 30
const _notificationHandlers = new Map();
const _actionHandlers = new Map();
31
let _actionListener;
Lidan Hifi's avatar
Lidan Hifi committed
32

33 34 35 36 37 38 39 40 41 42 43 44 45
export class NotificationAction {
  constructor(options: Object, handler: Function) {
    this.options = options;
    this.handler = handler;
  }
}

export class NotificationCategory {
  constructor(options: Object) {
    this.options = options;
  }
}

46
export default class NotificationsIOS {
Lidan Hifi's avatar
Lidan Hifi committed
47 48 49 50 51 52
  /**
   * Attaches a listener to remote notification events while the app is running
   * in the foreground or the background.
   *
   * Valid events are:
   *
53
   * - `remoteNotificationsRegistered` : Fired when the user registers for remote notifications. The handler will be invoked with a hex string representing the deviceToken.
Lidan Hifi's avatar
Lidan Hifi committed
54 55 56 57 58
   * - `notificationReceivedForeground` : Fired when a notification (local / remote) is received when app is on foreground state.
   * - `notificationReceivedBackground`: Fired when a background notification is received.
   * - `notificationOpened`: Fired when a notification (local / remote) is opened.
   */
  static addEventListener(type: string, handler: Function) {
59 60 61 62 63 64 65 66
    if (_exportedEvents.indexOf(type) !== -1) {
      let listener;

      if (type === DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT) {
        listener = DeviceEventEmitter.addListener(
          DEVICE_REMOTE_NOTIFICATIONS_REGISTERED_EVENT,
          registration => handler(registration.deviceToken)
        );
67 68 69 70 71
      } else if (type === DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT) {
        listener = DeviceEventEmitter.addListener(
          DEVICE_REMOTE_NOTIFICATIONS_REGISTRATION_FAILED_EVENT,
          error => handler(error)
        );
72 73 74 75 76 77 78 79 80 81 82
      } else if (type === DEVICE_PUSH_KIT_REGISTERED_EVENT) {
        listener = DeviceEventEmitter.addListener(
          DEVICE_PUSH_KIT_REGISTERED_EVENT,
          registration => handler(registration.pushKitToken)
        );
      } else {
        listener = DeviceEventEmitter.addListener(
          type,
          notification => handler(new IOSNotification(notification))
        );
      }
Lidan Hifi's avatar
Lidan Hifi committed
83

Lidan Hifi's avatar
Lidan Hifi committed
84
      _notificationHandlers.set(handler, listener);
Lidan Hifi's avatar
Lidan Hifi committed
85 86 87 88 89 90 91 92
    }
  }

  /**
   * Removes the event listener. Do this in `componentWillUnmount` to prevent
   * memory leaks
   */
  static removeEventListener(type: string, handler: Function) {
93
    if (_exportedEvents.indexOf(type) !== -1) {
Leon Mok's avatar
Leon Mok committed
94 95 96 97
      const listener = _notificationHandlers.get(handler);
      if (listener) {
        listener.remove();
        _notificationHandlers.delete(handler);
Lidan Hifi's avatar
Lidan Hifi committed
98
      }
Lidan Hifi's avatar
Lidan Hifi committed
99 100 101

    }
  }
102

103
  static _actionHandlerDispatcher(action: Object) {
Leon Mok's avatar
Leon Mok committed
104
    const actionHandler = _actionHandlers.get(action.identifier);
105 106

    if (actionHandler) {
107 108
      action.notification = new IOSNotification(action.notification);

109 110 111
      actionHandler(action, () => {
        NativeRNNotifications.completionHandler(action.completionKey);
      });
112
    }
113 114 115 116 117
  }

  /**
   * Sets the notification categories
   */
118
  static requestPermissions(categories: Array<NotificationCategory>) {
119 120 121
    let notificationCategories = [];

    if (categories) {
122
      // subscribe once for all actions
123
      _actionListener = NativeAppEventEmitter.addListener(DEVICE_NOTIFICATION_ACTION_RECEIVED, this._actionHandlerDispatcher.bind(this));
124

125 126 127 128
      notificationCategories = categories.map(category => {
        return Object.assign({}, category.options, {
          actions: category.options.actions.map(action => {
            // subscribe to action event
129
            _actionHandlers.set(action.options.identifier, action.handler);
130 131 132 133 134 135 136

            return action.options;
          })
        });
      });
    }

137 138 139 140 141 142 143 144
    NativeRNNotifications.requestPermissionsWithCategories(notificationCategories);
  }

  /**
   * Unregister for all remote notifications received via Apple Push Notification service.
   */
  static abandonPermissions() {
    NativeRNNotifications.abandonPermissions();
145
  }
146 147 148 149 150 151 152 153 154 155 156 157

  /**
   * Removes the event listener. Do this in `componentWillUnmount` to prevent
   * memory leaks
   */
  static resetCategories() {
    if (_actionListener) {
      _actionListener.remove();
    }

    _actionHandlers.clear();
  }
158

159 160 161 162 163 164 165 166
  static registerPushKit() {
    NativeRNNotifications.registerPushKit();
  }

  static backgroundTimeRemaining(callback: Function) {
    NativeRNNotifications.backgroundTimeRemaining(callback);
  }

167 168 169 170
  static consumeBackgroundQueue() {
    NativeRNNotifications.consumeBackgroundQueue();
  }

171
  static log(message: string) {
172 173
    NativeRNNotifications.log(message);
  }
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188

  /**
   * Presenting local notification
   *
   * notification is an object containing:
   *
   * - `alertBody` : The message displayed in the notification alert.
   * - `alertTitle` : The message title displayed in the notification.
   * - `alertAction` : The "action" displayed beneath an actionable notification. Defaults to "view";
   * - `soundName` : The sound played when the notification is fired (optional).
   * - `category`  : The category of this notification, required for actionable notifications (optional).
   * - `userInfo`  : An optional object containing additional notification data.
   * - `fireDate` : The date and time when the system should deliver the notification. if not specified, the notification will be dispatched immediately.
   */
  static localNotification(notification: Object) {
Leon Mok's avatar
Leon Mok committed
189
    const notificationId = uuid.v4();
190 191 192 193 194 195 196 197 198 199 200
    NativeRNNotifications.localNotification(notification, notificationId);

    return notificationId;
  }

  static cancelLocalNotification(notificationId: String) {
    NativeRNNotifications.cancelLocalNotification(notificationId);
  }

  static cancelAllLocalNotifications() {
    NativeRNNotifications.cancelAllLocalNotifications();
201
  }
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236

  /**
   * Remove all delivered notifications from Notification Center
   */
  static removeAllDeliveredNotifications() {
    return NativeRNNotifications.removeAllDeliveredNotifications();
  }

  /**
   * Removes the specified notifications from Notification Center
   *
   * @param identifiers Array of notification identifiers
   */
  static removeDeliveredNotifications(identifiers: [string]) {
    return NativeRNNotifications.removeDeliveredNotifications(identifiers);
  }

  /**
   * Provides you with a list of the app’s notifications that are still displayed in Notification Center
   *
   * @param callback Function which receive an array of delivered notifications
   *
   *  A delivered notification is an object containing:
   *
   * - `identifier`  : The identifier of this notification.
   * - `alertBody` : The message displayed in the notification alert.
   * - `alertTitle` : The message title displayed in the notification.
   * - `category`  : The category of this notification, if has one.
   * - `userInfo`  : An optional object containing additional notification data.
   * - `thread-id`  : The thread identifier of this notification, if has one.
   * - `fireDate` : The date and time when the system should deliver the notification. if not specified, the notification will be dispatched immediately.
   */
  static getDeliveredNotifications(callback: (notifications: [Object]) => void) {
    return NativeRNNotifications.getDeliveredNotifications(callback);
  }
Lidan Hifi's avatar
Lidan Hifi committed
237
}