2
0
mirror of synced 2025-02-22 19:18:36 +00:00

[notifications] Start iOS implementation of notifications

This commit is contained in:
Chris Bianca 2018-02-14 09:07:29 +00:00
parent fb57dc5482
commit 6b911b207b
3 changed files with 252 additions and 9 deletions

View File

@ -15,11 +15,13 @@
// notifications via APNS
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
@import UserNotifications;
@interface RNFirebaseMessaging () <UNUserNotificationCenterDelegate>
#else
@interface RNFirebaseMessaging ()
#endif
@property (nonatomic, strong) NSMutableDictionary *callbackHandlers;
@end
#endif
@implementation RNFirebaseMessaging

View File

@ -1,20 +1,255 @@
#import "RNFirebaseNotifications.h"
#if __has_include(<FirebaseMessaging/FIRMessaging.h>)
#import <React/RCTUtils.h>
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
@import UserNotifications;
#endif
@implementation RNFirebaseNotifications
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(cancelAllNotifications) {
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
[RCTSharedApplication() cancelAllLocalNotifications];
} else {
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
UNUserNotificationCenter *notificationCenter = [UNUserNotificationCenter currentNotificationCenter];
if (notificationCenter != nil) {
[[UNUserNotificationCenter currentNotificationCenter] removeAllPendingNotificationRequests];
}
#endif
}
}
RCT_EXPORT_METHOD(cancelNotification:(NSString*) notificationId) {
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
for (UILocalNotification *notification in RCTSharedApplication().scheduledLocalNotifications) {
NSDictionary *notificationInfo = notification.userInfo;
if ([notificationId isEqualToString:[notificationInfo valueForKey:@"notificationId"]]) {
[RCTSharedApplication() cancelLocalNotification:notification];
}
}
} else {
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
UNUserNotificationCenter *notificationCenter = [UNUserNotificationCenter currentNotificationCenter];
if (notificationCenter != nil) {
[[UNUserNotificationCenter currentNotificationCenter] removePendingNotificationRequestsWithIdentifiers:@[notificationId]];
}
#endif
}
}
RCT_EXPORT_METHOD(displayNotification:(NSDictionary*) notification
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
UILocalNotification* notif = [self buildUILocalNotification:notification];
[RCTSharedApplication() presentLocalNotificationNow:notif];
resolve(nil);
} else {
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
UNNotificationRequest* request = [self buildUNNotificationRequest:notification];
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (!error) {
resolve(nil);
}else{
reject(@"notifications/display_notification_error", @"Failed to display notificaton", error);
}
}];
#endif
}
}
RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){
UILocalNotification *localUserInfo = [self bridge].launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
if (localUserInfo) {
// TODO: Proper format
resolve([[localUserInfo userInfo] copy]);
UILocalNotification *localNotification = [self bridge].launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotification) {
NSDictionary *notification = [self parseUILocalNotification:localNotification];
resolve(notification);
} else {
resolve(nil);
}
}
RCT_EXPORT_METHOD(getScheduledNotifications:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
NSMutableArray* notifications = [[NSMutableArray alloc] init];
for (UILocalNotification *notif in [RCTSharedApplication() scheduledLocalNotifications]){
NSDictionary *notification = [self parseUILocalNotification:notif];
[notifications addObject:notification];
}
resolve(notifications);
} else {
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
[[UNUserNotificationCenter currentNotificationCenter] getPendingNotificationRequestsWithCompletionHandler:^(NSArray<UNNotificationRequest *> * _Nonnull requests) {
NSMutableArray* notifications = [[NSMutableArray alloc] init];
for (UNNotificationRequest *notif in requests){
NSDictionary *notification = [self parseUNNotificationRequest:notif];
[notifications addObject:notification];
}
resolve(notifications);
}];
#endif
}
}
RCT_EXPORT_METHOD(removeAllDeliveredNotifications) {
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
// No such functionality on iOS 8/9
} else {
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
UNUserNotificationCenter *notificationCenter = [UNUserNotificationCenter currentNotificationCenter];
if (notificationCenter != nil) {
[[UNUserNotificationCenter currentNotificationCenter] removeAllDeliveredNotifications];
}
#endif
}
}
RCT_EXPORT_METHOD(removeDeliveredNotification:(NSString*) notificationId) {
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
// No such functionality on iOS 8/9
} else {
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
UNUserNotificationCenter *notificationCenter = [UNUserNotificationCenter currentNotificationCenter];
if (notificationCenter != nil) {
[[UNUserNotificationCenter currentNotificationCenter] removeDeliveredNotificationsWithIdentifiers:@[notificationId]];
}
#endif
}
}
RCT_EXPORT_METHOD(scheduleNotification:(NSDictionary*) notification
schedule:(NSDictionary*) schedule
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
UILocalNotification* notif = [self buildUILocalNotification:notification];
// TODO: Schedule
[RCTSharedApplication() scheduleLocalNotification:notif];
resolve(nil);
} else {
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
UNNotificationRequest* request = [self buildUNNotificationRequest:notification];
// TODO: Schedule
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (!error) {
resolve(nil);
}else{
reject(@"notification/schedule_notification_error", @"Failed to schedule notificaton", error);
}
}];
#endif
}
}
- (UILocalNotification*) buildUILocalNotification:(NSDictionary *) notification {
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
if (notification[@"body"]) {
localNotification.alertBody = notification[@"body"];
}
if (notification[@"data"]) {
localNotification.userInfo = notification[@"data"];
}
if (notification[@"sound"]) {
localNotification.soundName = notification[@"sound"];
}
if (notification[@"title"]) {
localNotification.alertTitle = notification[@"title"];
}
if (notification[@"ios"]) {
NSDictionary *ios = notification[@"ios"];
if (ios[@"alertAction"]) {
localNotification.alertAction = ios[@"alertAction"];
}
if (ios[@"badge"]) {
NSNumber *badge = ios[@"badge"];
localNotification.applicationIconBadgeNumber = badge.integerValue;
}
if (ios[@"category"]) {
localNotification.category = ios[@"category"];
}
if (ios[@"hasAction"]) {
localNotification.hasAction = ios[@"hasAction"];
}
if (ios[@"launchImage"]) {
localNotification.alertLaunchImage = ios[@"launchImage"];
}
}
return localNotification;
}
- (UNNotificationRequest*) buildUNNotificationRequest:(NSDictionary *) notification {
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
if (notification[@"body"]) {
content.body = notification[@"body"];
}
if (notification[@"data"]) {
content.userInfo = notification[@"data"];
}
if (notification[@"sound"]) {
content.sound = notification[@"sound"];
}
if (notification[@"subtitle"]) {
content.title = notification[@"subtitle"];
}
if (notification[@"title"]) {
content.title = notification[@"title"];
}
if (notification[@"ios"]) {
NSDictionary *ios = notification[@"ios"];
if (ios[@"attachments"]) {
NSMutableArray *attachments = [[NSMutableArray alloc] init];
for (NSDictionary *a in ios[@"attachments"]) {
NSString *identifier = a[@"identifier"];
NSURL *url = [NSURL URLWithString:a[@"url"]];
NSDictionary *options = a[@"options"];
NSError *error;
UNNotificationAttachment *attachment = [UNNotificationAttachment attachmentWithIdentifier:identifier URL:url options:options error:&error];
if (attachment) {
[attachments addObject:attachment];
} else {
NSLog(@"Failed to create attachment: %@", error);
}
}
content.attachments = attachments;
}
if (ios[@"badge"]) {
content.badge = ios[@"badge"];
}
if (ios[@"category"]) {
content.categoryIdentifier = ios[@"category"];
}
if (ios[@"launchImage"]) {
content.launchImageName = ios[@"launchImage"];
}
if (ios[@"threadIdentifier"]) {
content.threadIdentifier = ios[@"threadIdentifier"];
}
}
// TODO: Scheduling
return [UNNotificationRequest requestWithIdentifier:notification[@"ios"][@"identifier"] content:content trigger:nil];
}
- (NSDictionary*) parseUILocalNotification:(UILocalNotification *) localNotification {
NSMutableDictionary *notification = [[NSMutableDictionary alloc] init];
return notification;
// TODO
}
- (NSDictionary*) parseUNNotificationRequest:(UNNotificationRequest *) localNotification {
// TODO
}
- (NSArray<NSString *> *)supportedEvents {
return @[];
}

View File

@ -73,7 +73,7 @@ export default class Notifications extends ModuleBase {
}
cancelAllNotifications(): Promise<void> {
return getNativeModule(this).cancelAllLocalNotifications();
return getNativeModule(this).cancelAllNotifications();
}
/**
@ -85,7 +85,7 @@ export default class Notifications extends ModuleBase {
if (!notificationId) {
return Promise.reject(new Error('Missing notificationId'));
}
return getNativeModule(this).cancelLocalNotification(notificationId);
return getNativeModule(this).cancelNotification(notificationId);
}
/**
@ -102,12 +102,18 @@ export default class Notifications extends ModuleBase {
return getNativeModule(this).displayNotification(notification.build());
}
getInitialNotification(): Promise<Object> {
return getNativeModule(this).getInitialNotification();
// TODO
// .then(notification => (notification ? new Notification(this, notification) : null));
}
/**
* Returns an array of all scheduled notifications
* @returns {Promise.<Array>}
*/
getScheduledNotifications(): Promise<Object[]> {
return getNativeModule(this).getScheduledLocalNotifications();
return getNativeModule(this).getScheduledNotifications();
}
onNotification(