Commit e4921f36 authored by Ran Greenberg's avatar Ran Greenberg Committed by GitHub

Merge pull request #103 from reberhardt7/dismiss-notifications

Use UserNotifications to create/dismiss local notifications
parents 77bce6a6 d945506c
...@@ -326,7 +326,6 @@ Example: ...@@ -326,7 +326,6 @@ Example:
let localNotification = NotificationsIOS.localNotification({ let localNotification = NotificationsIOS.localNotification({
alertBody: "Local notificiation!", alertBody: "Local notificiation!",
alertTitle: "Local Notification Title", alertTitle: "Local Notification Title",
alertAction: "Click here to open",
soundName: "chime.aiff", soundName: "chime.aiff",
category: "SOME_CATEGORY", category: "SOME_CATEGORY",
userInfo: { } userInfo: { }
...@@ -338,7 +337,7 @@ Notification object contains: ...@@ -338,7 +337,7 @@ Notification object contains:
- **`fireDate`**- The date and time when the system should deliver the notification (optinal - default is immidiate dispatch). - **`fireDate`**- The date and time when the system should deliver the notification (optinal - default is immidiate dispatch).
- `alertBody`- The message displayed in the notification alert. - `alertBody`- The message displayed in the notification alert.
- `alertTitle`- The title of the notification, displayed in the notifications center. - `alertTitle`- The title of the notification, displayed in the notifications center.
- `alertAction`- The "action" displayed beneath an actionable notification. - `alertAction`- The "action" displayed beneath an actionable notification on the lockscreen (e.g. "Slide to **open**"). Note that Apple no longer shows this in iOS 10.
- `soundName`- The sound played when the notification is fired (optional). - `soundName`- The sound played when the notification is fired (optional).
- `category`- The category of this notification, required for [interactive notifications](#interactive--actionable-notifications-ios-only) (optional). - `category`- The category of this notification, required for [interactive notifications](#interactive--actionable-notifications-ios-only) (optional).
- `userInfo`- An optional object containing additional notification data. - `userInfo`- An optional object containing additional notification data.
...@@ -357,8 +356,9 @@ NotificationsAndroid.localNotification({ ...@@ -357,8 +356,9 @@ NotificationsAndroid.localNotification({
Upon notification opening (tapping by the device user), all data fields will be delivered as-is). Upon notification opening (tapping by the device user), all data fields will be delivered as-is).
### Cancel Local Notification ### Cancel Scheduled Local Notifications
The `NotificationsIOS.localNotification()` and `NotificationsAndroid.localNotification()` methods return unique `notificationId` values, which can be used in order to cancel specific local notifications. You can cancel local notification by calling `NotificationsIOS.cancelLocalNotification(notificationId)` or `NotificationsAndroid.cancelLocalNotification(notificationId)`.
The `NotificationsIOS.localNotification()` and `NotificationsAndroid.localNotification()` methods return unique `notificationId` values, which can be used in order to cancel specific local notifications that were scheduled for delivery on `fireDate` and have not yet been delivered. You can cancel local notification by calling `NotificationsIOS.cancelLocalNotification(notificationId)` or `NotificationsAndroid.cancelLocalNotification(notificationId)`.
Example (iOS): Example (iOS):
...@@ -366,7 +366,6 @@ Example (iOS): ...@@ -366,7 +366,6 @@ Example (iOS):
let someLocalNotification = NotificationsIOS.localNotification({ let someLocalNotification = NotificationsIOS.localNotification({
alertBody: "Local notificiation!", alertBody: "Local notificiation!",
alertTitle: "Local Notification Title", alertTitle: "Local Notification Title",
alertAction: "Click here to open",
soundName: "chime.aiff", soundName: "chime.aiff",
category: "SOME_CATEGORY", category: "SOME_CATEGORY",
userInfo: { } userInfo: { }
...@@ -375,12 +374,26 @@ let someLocalNotification = NotificationsIOS.localNotification({ ...@@ -375,12 +374,26 @@ let someLocalNotification = NotificationsIOS.localNotification({
NotificationsIOS.cancelLocalNotification(someLocalNotification); NotificationsIOS.cancelLocalNotification(someLocalNotification);
``` ```
### Cancel All Local Notifications (iOS-only!) To cancel all local notifications (**iOS only!**), use `cancelAllLocalNotifications()`:
```javascript ```javascript
NotificationsIOS.cancelAllLocalNotifications(); NotificationsIOS.cancelAllLocalNotifications();
``` ```
### Cancel Delivered Local Notifications (iOS 10+ only)
To dismiss notifications from the notification center that have already been shown to the user, call `NotificationsIOS.removeDeliveredNotifications([notificationId])`:
```javascript
let someLocalNotification = NotificationsIOS.localNotification({...});
NotificationsIOS.removeDeliveredNotifications([someLocalNotification]);
```
Call `removeAllDeliveredNotifications()` to dismiss all delivered notifications
(note that this will dismiss push notifications in addition to local
notifications).
--- ---
## Managed Notifications (iOS only) ## Managed Notifications (iOS only)
...@@ -440,6 +453,28 @@ Now the server should push the notification a bit differently- background instea ...@@ -440,6 +453,28 @@ Now the server should push the notification a bit differently- background instea
--- ---
## Remove notifications (iOS only)
### getDeliveredNotifications
`PushNotification.getDeliveredNotifications(callback: (notifications: Array<Object>) => void)`
Provides you with a list of the app’s notifications that are still displayed in Notification Center.
### removeDeliveredNotifications
`PushNotification.removeDeliveredNotifications(identifiers: Array<String>)`
Removes the specified notifications from Notification Center.
### removeAllDeliveredNotifications
`PushNotification.removeAllDeliveredNotifications()`
Removes all delivered notifications from Notification Center.
---
## PushKit API (iOS only) ## PushKit API (iOS only)
The PushKit framework provides the classes for your iOS apps to receive background pushes from remote servers. it has better support for background notifications compared to regular push notifications with `content-available: 1`. More info in [iOS PushKit documentation](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Reference/PushKit_Framework/). The PushKit framework provides the classes for your iOS apps to receive background pushes from remote servers. it has better support for background notifications compared to regular push notifications with `content-available: 1`. More info in [iOS PushKit documentation](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Reference/PushKit_Framework/).
......
...@@ -15,6 +15,9 @@ ...@@ -15,6 +15,9 @@
#import "RCTUtils.h" #import "RCTUtils.h"
#endif #endif
#import "RNNotificationsBridgeQueue.h" #import "RNNotificationsBridgeQueue.h"
#import <UserNotifications/UserNotifications.h>
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
NSString* const RNNotificationCreateAction = @"CREATE"; NSString* const RNNotificationCreateAction = @"CREATE";
NSString* const RNNotificationClearAction = @"CLEAR"; NSString* const RNNotificationClearAction = @"CLEAR";
...@@ -107,6 +110,61 @@ RCT_ENUM_CONVERTER(UIUserNotificationActionBehavior, (@{ ...@@ -107,6 +110,61 @@ RCT_ENUM_CONVERTER(UIUserNotificationActionBehavior, (@{
} }
@end @end
@implementation RCTConvert (UNNotificationRequest)
+ (UNNotificationRequest *)UNNotificationRequest:(id)json withId:(NSString*)notificationId
{
NSDictionary<NSString *, id> *details = [self NSDictionary:json];
UNMutableNotificationContent *content = [UNMutableNotificationContent new];
content.body = [RCTConvert NSString:details[@"alertBody"]];
content.title = [RCTConvert NSString:details[@"alertTitle"]];
content.sound = [RCTConvert NSString:details[@"soundName"]]
? [UNNotificationSound soundNamed:[RCTConvert NSString:details[@"soundName"]]]
: [UNNotificationSound defaultSound];
content.userInfo = [RCTConvert NSDictionary:details[@"userInfo"]] ?: @{};
content.categoryIdentifier = [RCTConvert NSString:details[@"category"]];
NSDate *triggerDate = [RCTConvert NSDate:details[@"fireDate"]];
UNCalendarNotificationTrigger *trigger = nil;
if (triggerDate != nil) {
NSDateComponents *triggerDateComponents = [[NSCalendar currentCalendar]
components:NSCalendarUnitYear +
NSCalendarUnitMonth + NSCalendarUnitDay +
NSCalendarUnitHour + NSCalendarUnitMinute +
NSCalendarUnitSecond + NSCalendarUnitTimeZone
fromDate:triggerDate];
trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:triggerDateComponents
repeats:NO];
}
return [UNNotificationRequest requestWithIdentifier:notificationId
content:content trigger:trigger];
}
@end
static NSDictionary *RCTFormatUNNotification(UNNotification *notification)
{
NSMutableDictionary *formattedNotification = [NSMutableDictionary dictionary];
UNNotificationContent *content = notification.request.content;
formattedNotification[@"identifier"] = notification.request.identifier;
if (notification.date) {
NSDateFormatter *formatter = [NSDateFormatter new];
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"];
NSString *dateString = [formatter stringFromDate:notification.date];
formattedNotification[@"fireDate"] = dateString;
}
formattedNotification[@"alertTitle"] = RCTNullIfNil(content.title);
formattedNotification[@"alertBody"] = RCTNullIfNil(content.body);
formattedNotification[@"category"] = RCTNullIfNil(content.categoryIdentifier);
formattedNotification[@"thread-id"] = RCTNullIfNil(content.threadIdentifier);
formattedNotification[@"userInfo"] = RCTNullIfNil(RCTJSONClean(content.userInfo));
return formattedNotification;
}
@implementation RNNotifications @implementation RNNotifications
RCT_EXPORT_MODULE() RCT_EXPORT_MODULE()
...@@ -521,25 +579,35 @@ RCT_EXPORT_METHOD(consumeBackgroundQueue) ...@@ -521,25 +579,35 @@ RCT_EXPORT_METHOD(consumeBackgroundQueue)
RCT_EXPORT_METHOD(localNotification:(NSDictionary *)notification withId:(NSString *)notificationId) RCT_EXPORT_METHOD(localNotification:(NSDictionary *)notification withId:(NSString *)notificationId)
{ {
UILocalNotification* localNotification = [RCTConvert UILocalNotification:notification]; if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10")) {
NSMutableArray* userInfo = localNotification.userInfo.mutableCopy; UNNotificationRequest* localNotification = [RCTConvert UNNotificationRequest:notification withId:notificationId];
[userInfo setValue:notificationId forKey:@"__id"]; [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:localNotification withCompletionHandler:nil];
localNotification.userInfo = userInfo;
if ([notification objectForKey:@"fireDate"] != nil) {
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
} else { } else {
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification]; UILocalNotification* localNotification = [RCTConvert UILocalNotification:notification];
NSMutableArray* userInfo = localNotification.userInfo.mutableCopy;
[userInfo setValue:notificationId forKey:@"__id"];
localNotification.userInfo = userInfo;
if ([notification objectForKey:@"fireDate"] != nil) {
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
} else {
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}
} }
} }
RCT_EXPORT_METHOD(cancelLocalNotification:(NSString *)notificationId) RCT_EXPORT_METHOD(cancelLocalNotification:(NSString *)notificationId)
{ {
for (UILocalNotification* notification in [UIApplication sharedApplication].scheduledLocalNotifications) { if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10")) {
NSDictionary* notificationInfo = notification.userInfo; UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center removePendingNotificationRequestsWithIdentifiers:@[notificationId]];
} else {
for (UILocalNotification* notification in [UIApplication sharedApplication].scheduledLocalNotifications) {
NSDictionary* notificationInfo = notification.userInfo;
if ([[notificationInfo objectForKey:@"__id"] isEqualToString:notificationId]) { if ([[notificationInfo objectForKey:@"__id"] isEqualToString:notificationId]) {
[[UIApplication sharedApplication] cancelLocalNotification:notification]; [[UIApplication sharedApplication] cancelLocalNotification:notification];
}
} }
} }
} }
...@@ -552,7 +620,7 @@ RCT_EXPORT_METHOD(cancelAllLocalNotifications) ...@@ -552,7 +620,7 @@ RCT_EXPORT_METHOD(cancelAllLocalNotifications)
RCT_EXPORT_METHOD(isRegisteredForRemoteNotifications:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) RCT_EXPORT_METHOD(isRegisteredForRemoteNotifications:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
{ {
BOOL ans; BOOL ans;
if (TARGET_IPHONE_SIMULATOR) { if (TARGET_IPHONE_SIMULATOR) {
ans = [[[UIApplication sharedApplication] currentUserNotificationSettings] types] != 0; ans = [[[UIApplication sharedApplication] currentUserNotificationSettings] types] != 0;
} }
...@@ -572,4 +640,39 @@ RCT_EXPORT_METHOD(checkPermissions:(RCTPromiseResolveBlock) resolve ...@@ -572,4 +640,39 @@ RCT_EXPORT_METHOD(checkPermissions:(RCTPromiseResolveBlock) resolve
}); });
} }
#if !TARGET_OS_TV
RCT_EXPORT_METHOD(removeAllDeliveredNotifications)
{
if ([UNUserNotificationCenter class]) {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center removeAllDeliveredNotifications];
}
}
RCT_EXPORT_METHOD(removeDeliveredNotifications:(NSArray<NSString *> *)identifiers)
{
if ([UNUserNotificationCenter class]) {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center removeDeliveredNotificationsWithIdentifiers:identifiers];
}
}
RCT_EXPORT_METHOD(getDeliveredNotifications:(RCTResponseSenderBlock)callback)
{
if ([UNUserNotificationCenter class]) {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) {
NSMutableArray<NSDictionary *> *formattedNotifications = [NSMutableArray new];
for (UNNotification *notification in notifications) {
[formattedNotifications addObject:RCTFormatUNNotification(notification)];
}
callback(@[formattedNotifications]);
}];
}
}
#endif !TARGET_OS_TV
@end @end
...@@ -216,4 +216,39 @@ export default class NotificationsIOS { ...@@ -216,4 +216,39 @@ export default class NotificationsIOS {
static checkPermissions() { static checkPermissions() {
return NativeRNNotifications.checkPermissions(); return NativeRNNotifications.checkPermissions();
} }
/**
* 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: Array<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: Array<Object>) => void) {
return NativeRNNotifications.getDeliveredNotifications(callback);
}
} }
...@@ -5,6 +5,7 @@ export default class IOSNotification { ...@@ -5,6 +5,7 @@ export default class IOSNotification {
_badge: number; _badge: number;
_category: string; _category: string;
_type: string; // regular / managed _type: string; // regular / managed
_thread: string;
constructor(notification: Object) { constructor(notification: Object) {
this._data = {}; this._data = {};
...@@ -21,6 +22,7 @@ export default class IOSNotification { ...@@ -21,6 +22,7 @@ export default class IOSNotification {
this._badge = notification.aps.badge; this._badge = notification.aps.badge;
this._category = notification.managedAps.category; this._category = notification.managedAps.category;
this._type = "managed"; this._type = "managed";
this._thread = notification.aps["thread-id"];
} else if ( } else if (
notification.aps && notification.aps &&
notification.aps.alert) { notification.aps.alert) {
...@@ -30,6 +32,7 @@ export default class IOSNotification { ...@@ -30,6 +32,7 @@ export default class IOSNotification {
this._badge = notification.aps.badge; this._badge = notification.aps.badge;
this._category = notification.aps.category; this._category = notification.aps.category;
this._type = "regular"; this._type = "regular";
this._thread = notification.aps["thread-id"];
} }
Object.keys(notification).filter(key => key !== "aps").forEach(key => { Object.keys(notification).filter(key => key !== "aps").forEach(key => {
...@@ -60,4 +63,8 @@ export default class IOSNotification { ...@@ -60,4 +63,8 @@ export default class IOSNotification {
getType(): ?string { getType(): ?string {
return this._type; return this._type;
} }
getThread(): ?string {
return this._thread;
}
} }
...@@ -30,11 +30,15 @@ describe("NotificationsIOS", () => { ...@@ -30,11 +30,15 @@ describe("NotificationsIOS", () => {
nativeCancelAllLocalNotifications, nativeCancelAllLocalNotifications,
nativeSetBadgesCount, nativeSetBadgesCount,
nativeIsRegisteredForRemoteNotifications, nativeIsRegisteredForRemoteNotifications,
nativeCheckPermissions; nativeCheckPermissions,
nativeRemoveAllDeliveredNotifications,
nativeRemoveDeliveredNotifications,
nativeGetDeliveredNotifications;
let NotificationsIOS, NotificationAction, NotificationCategory; let NotificationsIOS, NotificationAction, NotificationCategory;
let someHandler = () => {}; let someHandler = () => {};
let constantGuid = "some-random-uuid"; let constantGuid = "some-random-uuid";
let identifiers = ["some-random-uuid", "other-random-uuid"];
/*eslint-enable indent*/ /*eslint-enable indent*/
before(() => { before(() => {
...@@ -53,6 +57,9 @@ describe("NotificationsIOS", () => { ...@@ -53,6 +57,9 @@ describe("NotificationsIOS", () => {
nativeSetBadgesCount = sinon.spy(); nativeSetBadgesCount = sinon.spy();
nativeIsRegisteredForRemoteNotifications = sinon.spy(); nativeIsRegisteredForRemoteNotifications = sinon.spy();
nativeCheckPermissions = sinon.spy(); nativeCheckPermissions = sinon.spy();
nativeRemoveAllDeliveredNotifications = sinon.spy();
nativeRemoveDeliveredNotifications = sinon.spy();
nativeGetDeliveredNotifications = sinon.spy();
let libUnderTest = proxyquire("../index.ios", { let libUnderTest = proxyquire("../index.ios", {
"uuid": { "uuid": {
...@@ -71,7 +78,10 @@ describe("NotificationsIOS", () => { ...@@ -71,7 +78,10 @@ describe("NotificationsIOS", () => {
cancelAllLocalNotifications: nativeCancelAllLocalNotifications, cancelAllLocalNotifications: nativeCancelAllLocalNotifications,
setBadgesCount: nativeSetBadgesCount, setBadgesCount: nativeSetBadgesCount,
isRegisteredForRemoteNotifications: nativeIsRegisteredForRemoteNotifications, isRegisteredForRemoteNotifications: nativeIsRegisteredForRemoteNotifications,
checkPermissions: nativeCheckPermissions checkPermissions: nativeCheckPermissions,
removeAllDeliveredNotifications: nativeRemoveAllDeliveredNotifications,
removeDeliveredNotifications: nativeRemoveDeliveredNotifications,
getDeliveredNotifications: nativeGetDeliveredNotifications
} }
}, },
NativeAppEventEmitter: { NativeAppEventEmitter: {
...@@ -112,6 +122,9 @@ describe("NotificationsIOS", () => { ...@@ -112,6 +122,9 @@ describe("NotificationsIOS", () => {
nativeCancelAllLocalNotifications.reset(); nativeCancelAllLocalNotifications.reset();
nativeIsRegisteredForRemoteNotifications.reset(); nativeIsRegisteredForRemoteNotifications.reset();
nativeCheckPermissions.reset(); nativeCheckPermissions.reset();
nativeRemoveAllDeliveredNotifications.reset();
nativeRemoveDeliveredNotifications.reset();
nativeGetDeliveredNotifications.reset();
}); });
after(() => { after(() => {
...@@ -129,6 +142,9 @@ describe("NotificationsIOS", () => { ...@@ -129,6 +142,9 @@ describe("NotificationsIOS", () => {
nativeCancelAllLocalNotifications = null; nativeCancelAllLocalNotifications = null;
nativeIsRegisteredForRemoteNotifications = null; nativeIsRegisteredForRemoteNotifications = null;
nativeCheckPermissions = null; nativeCheckPermissions = null;
nativeRemoveAllDeliveredNotifications = null;
nativeRemoveDeliveredNotifications = null;
nativeGetDeliveredNotifications = null;
NotificationsIOS = null; NotificationsIOS = null;
NotificationAction = null; NotificationAction = null;
...@@ -306,7 +322,6 @@ describe("NotificationsIOS", () => { ...@@ -306,7 +322,6 @@ describe("NotificationsIOS", () => {
}); });
}); });
describe("Is registered for remote notifications ", () => { describe("Is registered for remote notifications ", () => {
it("should call native is registered for remote notifications", () => { it("should call native is registered for remote notifications", () => {
NotificationsIOS.isRegisteredForRemoteNotifications(); NotificationsIOS.isRegisteredForRemoteNotifications();
...@@ -322,4 +337,29 @@ describe("NotificationsIOS", () => { ...@@ -322,4 +337,29 @@ describe("NotificationsIOS", () => {
}); });
}); });
describe("Remove all delivered notifications", () => {
it("should call native remove all delivered notifications method", () => {
NotificationsIOS.removeAllDeliveredNotifications();
expect(nativeRemoveAllDeliveredNotifications).to.have.been.calledWith();
});
});
describe("Remove delivered notifications", () => {
it("should call native remove delivered notifications method", () => {
NotificationsIOS.removeDeliveredNotifications(identifiers);
expect(nativeRemoveDeliveredNotifications).to.have.been.calledWith(identifiers);
});
});
describe("Get delivered notifications", () => {
it("should call native get delivered notifications method", () => {
const callback = (notifications) => console.log(notifications);
NotificationsIOS.getDeliveredNotifications(callback);
expect(nativeGetDeliveredNotifications).to.have.been.calledWith(callback);
});
});
}); });
...@@ -4,7 +4,7 @@ import IOSNotification from "../notification.ios"; ...@@ -4,7 +4,7 @@ import IOSNotification from "../notification.ios";
describe("iOS Notification Object", () => { describe("iOS Notification Object", () => {
let notification; let notification;
let someBadgeCount = 123, someSound = "someSound", someCategory = "some_notification_category"; let someBadgeCount = 123, someSound = "someSound", someCategory = "some_notification_category", someThread = "thread-1";
describe("for a regular iOS push notification", () => { describe("for a regular iOS push notification", () => {
let regularNativeNotifications = [ let regularNativeNotifications = [
...@@ -17,7 +17,8 @@ describe("iOS Notification Object", () => { ...@@ -17,7 +17,8 @@ describe("iOS Notification Object", () => {
}, },
badge: someBadgeCount, badge: someBadgeCount,
sound: someSound, sound: someSound,
category: someCategory category: someCategory,
"thread-id": someThread
}, },
key1: "value1", key1: "value1",
key2: "value2" key2: "value2"
...@@ -33,7 +34,8 @@ describe("iOS Notification Object", () => { ...@@ -33,7 +34,8 @@ describe("iOS Notification Object", () => {
}, },
badge: someBadgeCount, badge: someBadgeCount,
sound: someSound, sound: someSound,
category: someCategory category: someCategory,
"thread-id": someThread
}, },
key1: "value1", key1: "value1",
key2: "value2" key2: "value2"
...@@ -65,6 +67,10 @@ describe("iOS Notification Object", () => { ...@@ -65,6 +67,10 @@ describe("iOS Notification Object", () => {
expect(notification.getCategory()).to.equal(someCategory); expect(notification.getCategory()).to.equal(someCategory);
}); });
it("should return the thread", () => {
expect(notification.getThread()).to.equal("thread-1");
});
it("should return the custom data", () => { it("should return the custom data", () => {
expect(notification.getData()).to.deep.equal({ key1: "value1", key2: "value2" }); expect(notification.getData()).to.deep.equal({ key1: "value1", key2: "value2" });
}); });
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment