/** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ #import "RCTPushNotificationManager.h" #import "RCTBridge.h" #import "RCTConvert.h" #import "RCTEventDispatcher.h" #import "RCTUtils.h" #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0 #define UIUserNotificationTypeAlert UIRemoteNotificationTypeAlert #define UIUserNotificationTypeBadge UIRemoteNotificationTypeBadge #define UIUserNotificationTypeSound UIRemoteNotificationTypeSound #define UIUserNotificationTypeNone UIRemoteNotificationTypeNone #define UIUserNotificationType UIRemoteNotificationType #endif NSString *const RCTRemoteNotificationReceived = @"RemoteNotificationReceived"; NSString *const RCTRemoteNotificationsRegistered = @"RemoteNotificationsRegistered"; @implementation RCTConvert (UILocalNotification) + (UILocalNotification *)UILocalNotification:(id)json { NSDictionary *details = [self NSDictionary:json]; UILocalNotification *notification = [UILocalNotification new]; notification.fireDate = [RCTConvert NSDate:details[@"fireDate"]] ?: [NSDate date]; notification.alertBody = [RCTConvert NSString:details[@"alertBody"]]; return notification; } @end @implementation RCTPushNotificationManager { NSDictionary *_initialNotification; } RCT_EXPORT_MODULE() @synthesize bridge = _bridge; - (instancetype)init { if ((self = [super init])) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleRemoteNotificationReceived:) name:RCTRemoteNotificationReceived object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleRemoteNotificationsRegistered:) name:RCTRemoteNotificationsRegistered object:nil]; } return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)setBridge:(RCTBridge *)bridge { _bridge = bridge; _initialNotification = [bridge.launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] copy]; } + (void)application:(__unused UIApplication *)application didRegisterUserNotificationSettings:(__unused UIUserNotificationSettings *)notificationSettings { if ([application respondsToSelector:@selector(registerForRemoteNotifications)]) { [application registerForRemoteNotifications]; } } + (void)application:(__unused UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSMutableString *hexString = [NSMutableString string]; NSUInteger deviceTokenLength = deviceToken.length; const unsigned char *bytes = deviceToken.bytes; for (NSUInteger i = 0; i < deviceTokenLength; i++) { [hexString appendFormat:@"%02x", bytes[i]]; } NSDictionary *userInfo = @{ @"deviceToken" : [hexString copy] }; [[NSNotificationCenter defaultCenter] postNotificationName:RCTRemoteNotificationsRegistered object:self userInfo:userInfo]; } + (void)application:(__unused UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification { [[NSNotificationCenter defaultCenter] postNotificationName:RCTRemoteNotificationReceived object:self userInfo:notification]; } - (void)handleRemoteNotificationReceived:(NSNotification *)notification { [_bridge.eventDispatcher sendDeviceEventWithName:@"remoteNotificationReceived" body:notification.userInfo]; } - (void)handleRemoteNotificationsRegistered:(NSNotification *)notification { [_bridge.eventDispatcher sendDeviceEventWithName:@"remoteNotificationsRegistered" body:notification.userInfo]; } /** * Update the application icon badge number on the home screen */ RCT_EXPORT_METHOD(setApplicationIconBadgeNumber:(NSInteger)number) { RCTSharedApplication().applicationIconBadgeNumber = number; } /** * Get the current application icon badge number on the home screen */ RCT_EXPORT_METHOD(getApplicationIconBadgeNumber:(RCTResponseSenderBlock)callback) { callback(@[ @(RCTSharedApplication().applicationIconBadgeNumber) ]); } RCT_EXPORT_METHOD(requestPermissions:(NSDictionary *)permissions) { if (RCTRunningInAppExtension()) { return; } UIUserNotificationType types = UIUserNotificationTypeNone; if (permissions) { if ([permissions[@"alert"] boolValue]) { types |= UIUserNotificationTypeAlert; } if ([permissions[@"badge"] boolValue]) { types |= UIUserNotificationTypeBadge; } if ([permissions[@"sound"] boolValue]) { types |= UIUserNotificationTypeSound; } } else { types = UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound; } UIApplication *app = RCTSharedApplication(); if ([app respondsToSelector:@selector(registerUserNotificationSettings:)]) { UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:(NSUInteger)types categories:nil]; [app registerUserNotificationSettings:notificationSettings]; [app registerForRemoteNotifications]; } else { [app registerForRemoteNotificationTypes:(NSUInteger)types]; } } RCT_EXPORT_METHOD(abandonPermissions) { [RCTSharedApplication() unregisterForRemoteNotifications]; } RCT_EXPORT_METHOD(checkPermissions:(RCTResponseSenderBlock)callback) { if (RCTRunningInAppExtension()) { NSDictionary *permissions = @{@"alert": @(NO), @"badge": @(NO), @"sound": @(NO)}; callback(@[permissions]); return; } NSUInteger types = 0; if ([UIApplication instancesRespondToSelector:@selector(currentUserNotificationSettings)]) { types = [RCTSharedApplication() currentUserNotificationSettings].types; } else { #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0 types = [RCTSharedApplication() enabledRemoteNotificationTypes]; #endif } NSMutableDictionary *permissions = [NSMutableDictionary new]; permissions[@"alert"] = @((types & UIUserNotificationTypeAlert) > 0); permissions[@"badge"] = @((types & UIUserNotificationTypeBadge) > 0); permissions[@"sound"] = @((types & UIUserNotificationTypeSound) > 0); callback(@[permissions]); } - (NSDictionary *)constantsToExport { return @{ @"initialNotification": RCTNullIfNil(_initialNotification), }; } RCT_EXPORT_METHOD(presentLocalNotification:(UILocalNotification *)notification) { [RCTSharedApplication() presentLocalNotificationNow:notification]; } RCT_EXPORT_METHOD(scheduleLocalNotification:(UILocalNotification *)notification) { [RCTSharedApplication() scheduleLocalNotification:notification]; } RCT_EXPORT_METHOD(cancelAllLocalNotifications) { [RCTSharedApplication() cancelAllLocalNotifications]; } @end