mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
f21fa4ecb7
Summary: In https://github.com/facebook/react-native/issues/25427, radex added initial support for running React Native projects on macOS via Catalyst. However, `RCTWebSocket` was disabled for that target because of some compilation issues. This meant that running projects via a connection to the packager wasn't possible: no live reload, and projects must be run in "Release" mode. It also meant making manual changes to Xcode projects deploying to macOS and scattering a number of conditional checks throughout the codebase. In this change, I've implemented support for `RCTWebSocket` on the macOS target and re-enabled the affected features. Live reload and the inspector now work for macOS targets. Manual modifications of Xcode build settings are no longer necessary for react-native projects running on macOS.  ### Limitations There's no binding which displays the developer menu (since there's no shake event on macOS). We'll probably want to add one, perhaps to the menu bar. I've chosen not to commit the modifications to RNTester which enable macOS support, since that would imply more "official" support for this target than I suspect you all would like to convey. I'm happy to add those chunks if it would be helpful. ## Changelog [iOS] [Added] - Added web socket support for macOS (Catalyst), enabling debug builds and live reload Pull Request resolved: https://github.com/facebook/react-native/pull/27469 Test Plan: * Open RNTester/RNTester.xcodeproj with Xcode 11.2.1, run it like a normal iOS app -- make sure it compiles and runs correctly (no regression) * Select "My Mac" as device target, and run. You may need to configure a valid development team to make signing work. * RNTester should run fine with no additional configuration. Modify a file in RNTester, note that live reload is now working. * Test the developer inspector. To display the developer menu, you'll need to manually show it; here's an example diff which does that: ``` diff --git a/RNTester/js/RNTesterApp.ios.js b/RNTester/js/RNTesterApp.ios.js index 8245a68d12..a447ad3b1b 100644 --- a/RNTester/js/RNTesterApp.ios.js +++ b/RNTester/js/RNTesterApp.ios.js @@ -19,6 +19,8 @@ const React = require('react'); const SnapshotViewIOS = require('./examples/Snapshot/SnapshotViewIOS.ios'); const URIActionMap = require('./utils/URIActionMap'); +import NativeDevMenu from '../../Libraries/NativeModules/specs/NativeDevMenu'; + const { AppRegistry, AsyncStorage, @@ -143,6 +145,7 @@ class RNTesterApp extends React.Component<Props, RNTesterNavigationState> { UNSAFE_componentWillMount() { BackHandler.addEventListener('hardwareBackPress', this._handleBack); + NativeDevMenu.show(); } componentDidMount() { ``` Reviewed By: sammy-SC Differential Revision: D18945861 Pulled By: hramos fbshipit-source-id: edcf02c5803742c89a845a3e5d72bc7dacae839f
604 lines
23 KiB
Plaintext
604 lines
23 KiB
Plaintext
/*
|
|
* 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.
|
|
*/
|
|
|
|
#import <React/RCTPushNotificationManager.h>
|
|
|
|
#import <UserNotifications/UserNotifications.h>
|
|
|
|
#import <FBReactNativeSpec/FBReactNativeSpec.h>
|
|
#import <React/RCTBridge.h>
|
|
#import <React/RCTConvert.h>
|
|
#import <React/RCTEventDispatcher.h>
|
|
#import <React/RCTUtils.h>
|
|
|
|
#import "RCTPushNotificationPlugins.h"
|
|
|
|
NSString *const RCTRemoteNotificationReceived = @"RemoteNotificationReceived";
|
|
|
|
static NSString *const kLocalNotificationReceived = @"LocalNotificationReceived";
|
|
static NSString *const kRemoteNotificationsRegistered = @"RemoteNotificationsRegistered";
|
|
static NSString *const kRegisterUserNotificationSettings = @"RegisterUserNotificationSettings";
|
|
static NSString *const kRemoteNotificationRegistrationFailed = @"RemoteNotificationRegistrationFailed";
|
|
|
|
static NSString *const kErrorUnableToRequestPermissions = @"E_UNABLE_TO_REQUEST_PERMISSIONS";
|
|
|
|
#if !TARGET_OS_TV
|
|
@implementation RCTConvert (NSCalendarUnit)
|
|
|
|
RCT_ENUM_CONVERTER(NSCalendarUnit,
|
|
(@{
|
|
@"year": @(NSCalendarUnitYear),
|
|
@"month": @(NSCalendarUnitMonth),
|
|
@"week": @(NSCalendarUnitWeekOfYear),
|
|
@"day": @(NSCalendarUnitDay),
|
|
@"hour": @(NSCalendarUnitHour),
|
|
@"minute": @(NSCalendarUnitMinute)
|
|
}),
|
|
0,
|
|
integerValue)
|
|
|
|
@end
|
|
|
|
@interface RCTPushNotificationManager () <NativePushNotificationManagerIOSSpec>
|
|
@property (nonatomic, strong) NSMutableDictionary *remoteNotificationCallbacks;
|
|
@end
|
|
|
|
@implementation RCTConvert (UILocalNotification)
|
|
|
|
+ (UILocalNotification *)UILocalNotification:(id)json
|
|
{
|
|
NSDictionary<NSString *, id> *details = [self NSDictionary:json];
|
|
BOOL isSilent = [RCTConvert BOOL:details[@"isSilent"]];
|
|
UILocalNotification *notification = [UILocalNotification new];
|
|
notification.alertTitle = [RCTConvert NSString:details[@"alertTitle"]];
|
|
notification.fireDate = [RCTConvert NSDate:details[@"fireDate"]] ?: [NSDate date];
|
|
notification.alertBody = [RCTConvert NSString:details[@"alertBody"]];
|
|
notification.alertAction = [RCTConvert NSString:details[@"alertAction"]];
|
|
notification.userInfo = [RCTConvert NSDictionary:details[@"userInfo"]];
|
|
notification.category = [RCTConvert NSString:details[@"category"]];
|
|
notification.repeatInterval = [RCTConvert NSCalendarUnit:details[@"repeatInterval"]];
|
|
if (details[@"applicationIconBadgeNumber"]) {
|
|
notification.applicationIconBadgeNumber = [RCTConvert NSInteger:details[@"applicationIconBadgeNumber"]];
|
|
}
|
|
if (!isSilent) {
|
|
notification.soundName = [RCTConvert NSString:details[@"soundName"]] ?: UILocalNotificationDefaultSoundName;
|
|
}
|
|
return notification;
|
|
}
|
|
|
|
RCT_ENUM_CONVERTER(UIBackgroundFetchResult, (@{
|
|
@"UIBackgroundFetchResultNewData": @(UIBackgroundFetchResultNewData),
|
|
@"UIBackgroundFetchResultNoData": @(UIBackgroundFetchResultNoData),
|
|
@"UIBackgroundFetchResultFailed": @(UIBackgroundFetchResultFailed),
|
|
}), UIBackgroundFetchResultNoData, integerValue)
|
|
|
|
@end
|
|
#else
|
|
@interface RCTPushNotificationManager () <NativePushNotificationManagerIOS>
|
|
@end
|
|
#endif //TARGET_OS_TV / TARGET_OS_UIKITFORMAC
|
|
|
|
@implementation RCTPushNotificationManager
|
|
{
|
|
RCTPromiseResolveBlock _requestPermissionsResolveBlock;
|
|
}
|
|
|
|
#if !TARGET_OS_TV && !TARGET_OS_UIKITFORMAC
|
|
|
|
static NSDictionary *RCTFormatLocalNotification(UILocalNotification *notification)
|
|
{
|
|
NSMutableDictionary *formattedLocalNotification = [NSMutableDictionary dictionary];
|
|
if (notification.fireDate) {
|
|
NSDateFormatter *formatter = [NSDateFormatter new];
|
|
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"];
|
|
NSString *fireDateString = [formatter stringFromDate:notification.fireDate];
|
|
formattedLocalNotification[@"fireDate"] = fireDateString;
|
|
}
|
|
formattedLocalNotification[@"alertAction"] = RCTNullIfNil(notification.alertAction);
|
|
formattedLocalNotification[@"alertBody"] = RCTNullIfNil(notification.alertBody);
|
|
formattedLocalNotification[@"applicationIconBadgeNumber"] = @(notification.applicationIconBadgeNumber);
|
|
formattedLocalNotification[@"category"] = RCTNullIfNil(notification.category);
|
|
formattedLocalNotification[@"soundName"] = RCTNullIfNil(notification.soundName);
|
|
formattedLocalNotification[@"userInfo"] = RCTNullIfNil(RCTJSONClean(notification.userInfo));
|
|
formattedLocalNotification[@"remote"] = @NO;
|
|
return formattedLocalNotification;
|
|
}
|
|
|
|
API_AVAILABLE(ios(10.0))
|
|
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[@"date"] = dateString;
|
|
}
|
|
|
|
formattedNotification[@"title"] = RCTNullIfNil(content.title);
|
|
formattedNotification[@"body"] = RCTNullIfNil(content.body);
|
|
formattedNotification[@"category"] = RCTNullIfNil(content.categoryIdentifier);
|
|
formattedNotification[@"thread-id"] = RCTNullIfNil(content.threadIdentifier);
|
|
formattedNotification[@"userInfo"] = RCTNullIfNil(RCTJSONClean(content.userInfo));
|
|
|
|
return formattedNotification;
|
|
}
|
|
|
|
#endif //TARGET_OS_TV / TARGET_OS_UIKITFORMAC
|
|
|
|
RCT_EXPORT_MODULE()
|
|
|
|
- (dispatch_queue_t)methodQueue
|
|
{
|
|
return dispatch_get_main_queue();
|
|
}
|
|
|
|
#if !TARGET_OS_TV && !TARGET_OS_UIKITFORMAC
|
|
- (void)startObserving
|
|
{
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(handleLocalNotificationReceived:)
|
|
name:kLocalNotificationReceived
|
|
object:nil];
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(handleRemoteNotificationReceived:)
|
|
name:RCTRemoteNotificationReceived
|
|
object:nil];
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(handleRegisterUserNotificationSettings:)
|
|
name:kRegisterUserNotificationSettings
|
|
object:nil];
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(handleRemoteNotificationsRegistered:)
|
|
name:kRemoteNotificationsRegistered
|
|
object:nil];
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(handleRemoteNotificationRegistrationError:)
|
|
name:kRemoteNotificationRegistrationFailed
|
|
object:nil];
|
|
}
|
|
|
|
- (void)stopObserving
|
|
{
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
}
|
|
|
|
- (NSArray<NSString *> *)supportedEvents
|
|
{
|
|
return @[@"localNotificationReceived",
|
|
@"remoteNotificationReceived",
|
|
@"remoteNotificationsRegistered",
|
|
@"remoteNotificationRegistrationError"];
|
|
}
|
|
|
|
+ (void)didRegisterUserNotificationSettings:(__unused UIUserNotificationSettings *)notificationSettings
|
|
{
|
|
if ([UIApplication instancesRespondToSelector:@selector(registerForRemoteNotifications)]) {
|
|
[RCTSharedApplication() registerForRemoteNotifications];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:kRegisterUserNotificationSettings
|
|
object:self
|
|
userInfo:@{@"notificationSettings": notificationSettings}];
|
|
}
|
|
}
|
|
|
|
+ (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
|
|
{
|
|
NSMutableString *hexString = [NSMutableString string];
|
|
NSUInteger deviceTokenLength = deviceToken.length;
|
|
const unsigned char *bytes = reinterpret_cast<const unsigned char *>(deviceToken.bytes);
|
|
for (NSUInteger i = 0; i < deviceTokenLength; i++) {
|
|
[hexString appendFormat:@"%02x", bytes[i]];
|
|
}
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:kRemoteNotificationsRegistered
|
|
object:self
|
|
userInfo:@{@"deviceToken" : [hexString copy]}];
|
|
}
|
|
|
|
+ (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
|
|
{
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:kRemoteNotificationRegistrationFailed
|
|
object:self
|
|
userInfo:@{@"error": error}];
|
|
}
|
|
|
|
+ (void)didReceiveRemoteNotification:(NSDictionary *)notification
|
|
{
|
|
NSDictionary *userInfo = @{@"notification": notification};
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:RCTRemoteNotificationReceived
|
|
object:self
|
|
userInfo:userInfo];
|
|
}
|
|
|
|
+ (void)didReceiveRemoteNotification:(NSDictionary *)notification
|
|
fetchCompletionHandler:(RCTRemoteNotificationCallback)completionHandler
|
|
{
|
|
NSDictionary *userInfo = @{@"notification": notification, @"completionHandler": completionHandler};
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:RCTRemoteNotificationReceived
|
|
object:self
|
|
userInfo:userInfo];
|
|
}
|
|
|
|
+ (void)didReceiveLocalNotification:(UILocalNotification *)notification
|
|
{
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:kLocalNotificationReceived
|
|
object:self
|
|
userInfo:RCTFormatLocalNotification(notification)];
|
|
}
|
|
|
|
- (void)handleLocalNotificationReceived:(NSNotification *)notification
|
|
{
|
|
[self sendEventWithName:@"localNotificationReceived" body:notification.userInfo];
|
|
}
|
|
|
|
- (void)handleRemoteNotificationReceived:(NSNotification *)notification
|
|
{
|
|
NSMutableDictionary *remoteNotification = [NSMutableDictionary dictionaryWithDictionary:notification.userInfo[@"notification"]];
|
|
RCTRemoteNotificationCallback completionHandler = notification.userInfo[@"completionHandler"];
|
|
NSString *notificationId = [[NSUUID UUID] UUIDString];
|
|
remoteNotification[@"notificationId"] = notificationId;
|
|
remoteNotification[@"remote"] = @YES;
|
|
if (completionHandler) {
|
|
if (!self.remoteNotificationCallbacks) {
|
|
// Lazy initialization
|
|
self.remoteNotificationCallbacks = [NSMutableDictionary dictionary];
|
|
}
|
|
self.remoteNotificationCallbacks[notificationId] = completionHandler;
|
|
}
|
|
|
|
[self sendEventWithName:@"remoteNotificationReceived" body:remoteNotification];
|
|
}
|
|
|
|
- (void)handleRemoteNotificationsRegistered:(NSNotification *)notification
|
|
{
|
|
[self sendEventWithName:@"remoteNotificationsRegistered" body:notification.userInfo];
|
|
}
|
|
|
|
- (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification
|
|
{
|
|
NSError *error = notification.userInfo[@"error"];
|
|
NSDictionary *errorDetails = @{
|
|
@"message": error.localizedDescription,
|
|
@"code": @(error.code),
|
|
@"details": error.userInfo,
|
|
};
|
|
[self sendEventWithName:@"remoteNotificationRegistrationError" body:errorDetails];
|
|
}
|
|
|
|
- (void)handleRegisterUserNotificationSettings:(NSNotification *)notification
|
|
{
|
|
if (_requestPermissionsResolveBlock == nil) {
|
|
return;
|
|
}
|
|
|
|
UIUserNotificationSettings *notificationSettings = notification.userInfo[@"notificationSettings"];
|
|
NSDictionary *notificationTypes = @{
|
|
@"alert": @((notificationSettings.types & UIUserNotificationTypeAlert) > 0),
|
|
@"sound": @((notificationSettings.types & UIUserNotificationTypeSound) > 0),
|
|
@"badge": @((notificationSettings.types & UIUserNotificationTypeBadge) > 0),
|
|
};
|
|
|
|
_requestPermissionsResolveBlock(notificationTypes);
|
|
// Clean up listener added in requestPermissions
|
|
[self removeListeners:1];
|
|
_requestPermissionsResolveBlock = nil;
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(onFinishRemoteNotification:(NSString *)notificationId fetchResult:(NSString *)fetchResult) {
|
|
UIBackgroundFetchResult result = [RCTConvert UIBackgroundFetchResult:fetchResult];
|
|
RCTRemoteNotificationCallback completionHandler = self.remoteNotificationCallbacks[notificationId];
|
|
if (!completionHandler) {
|
|
RCTLogError(@"There is no completion handler with notification id: %@", notificationId);
|
|
return;
|
|
}
|
|
completionHandler(result);
|
|
[self.remoteNotificationCallbacks removeObjectForKey:notificationId];
|
|
}
|
|
|
|
/**
|
|
* Update the application icon badge number on the home screen
|
|
*/
|
|
RCT_EXPORT_METHOD(setApplicationIconBadgeNumber:(double)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:(JS::NativePushNotificationManagerIOS::SpecRequestPermissionsPermission &)permissions
|
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
reject:(RCTPromiseRejectBlock)reject)
|
|
{
|
|
if (RCTRunningInAppExtension()) {
|
|
reject(kErrorUnableToRequestPermissions, nil, RCTErrorWithMessage(@"Requesting push notifications is currently unavailable in an app extension"));
|
|
return;
|
|
}
|
|
|
|
if (_requestPermissionsResolveBlock != nil) {
|
|
RCTLogError(@"Cannot call requestPermissions twice before the first has returned.");
|
|
return;
|
|
}
|
|
|
|
// Add a listener to make sure that startObserving has been called
|
|
[self addListener:@"remoteNotificationsRegistered"];
|
|
_requestPermissionsResolveBlock = resolve;
|
|
|
|
UIUserNotificationType types = UIUserNotificationTypeNone;
|
|
|
|
if (permissions.alert()) {
|
|
types |= UIUserNotificationTypeAlert;
|
|
}
|
|
if (permissions.badge()) {
|
|
types |= UIUserNotificationTypeBadge;
|
|
}
|
|
if (permissions.sound()) {
|
|
types |= UIUserNotificationTypeSound;
|
|
}
|
|
|
|
UIUserNotificationSettings *notificationSettings =
|
|
[UIUserNotificationSettings settingsForTypes:types categories:nil];
|
|
[RCTSharedApplication() registerUserNotificationSettings:notificationSettings];
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(abandonPermissions)
|
|
{
|
|
[RCTSharedApplication() unregisterForRemoteNotifications];
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(checkPermissions:(RCTResponseSenderBlock)callback)
|
|
{
|
|
if (RCTRunningInAppExtension()) {
|
|
callback(@[@{@"alert": @NO, @"badge": @NO, @"sound": @NO}]);
|
|
return;
|
|
}
|
|
|
|
NSUInteger types = [RCTSharedApplication() currentUserNotificationSettings].types;
|
|
callback(@[@{
|
|
@"alert": @((types & UIUserNotificationTypeAlert) > 0),
|
|
@"badge": @((types & UIUserNotificationTypeBadge) > 0),
|
|
@"sound": @((types & UIUserNotificationTypeSound) > 0),
|
|
}]);
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(presentLocalNotification:(JS::NativePushNotificationManagerIOS::Notification &)notification)
|
|
{
|
|
NSMutableDictionary *notificationDict = [NSMutableDictionary new];
|
|
notificationDict[@"alertTitle"] = notification.alertTitle();
|
|
notificationDict[@"alertBody"] = notification.alertBody();
|
|
notificationDict[@"alertAction"] = notification.alertAction();
|
|
notificationDict[@"userInfo"] = notification.userInfo();
|
|
notificationDict[@"category"] = notification.category();
|
|
notificationDict[@"repeatInterval"] = notification.repeatInterval();
|
|
if (notification.fireDate()) {
|
|
notificationDict[@"fireDate"] = @(*notification.fireDate());
|
|
}
|
|
if (notification.applicationIconBadgeNumber()) {
|
|
notificationDict[@"applicationIconBadgeNumber"] = @(*notification.applicationIconBadgeNumber());
|
|
}
|
|
if (notification.isSilent()) {
|
|
notificationDict[@"isSilent"] = @(*notification.isSilent());
|
|
}
|
|
[RCTSharedApplication() presentLocalNotificationNow:[RCTConvert UILocalNotification:notificationDict]];
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(scheduleLocalNotification:(JS::NativePushNotificationManagerIOS::Notification &)notification)
|
|
{
|
|
NSMutableDictionary *notificationDict = [NSMutableDictionary new];
|
|
notificationDict[@"alertTitle"] = notification.alertTitle();
|
|
notificationDict[@"alertBody"] = notification.alertBody();
|
|
notificationDict[@"alertAction"] = notification.alertAction();
|
|
notificationDict[@"userInfo"] = notification.userInfo();
|
|
notificationDict[@"category"] = notification.category();
|
|
notificationDict[@"repeatInterval"] = notification.repeatInterval();
|
|
if (notification.fireDate()) {
|
|
notificationDict[@"fireDate"] = @(*notification.fireDate());
|
|
}
|
|
if (notification.applicationIconBadgeNumber()) {
|
|
notificationDict[@"applicationIconBadgeNumber"] = @(*notification.applicationIconBadgeNumber());
|
|
}
|
|
if (notification.isSilent()) {
|
|
notificationDict[@"isSilent"] = @(*notification.isSilent());
|
|
}
|
|
[RCTSharedApplication() scheduleLocalNotification:[RCTConvert UILocalNotification:notificationDict]];
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(cancelAllLocalNotifications)
|
|
{
|
|
[RCTSharedApplication() cancelAllLocalNotifications];
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(cancelLocalNotifications:(NSDictionary<NSString *, id> *)userInfo)
|
|
{
|
|
for (UILocalNotification *notification in RCTSharedApplication().scheduledLocalNotifications) {
|
|
__block BOOL matchesAll = YES;
|
|
NSDictionary<NSString *, id> *notificationInfo = notification.userInfo;
|
|
// Note: we do this with a loop instead of just `isEqualToDictionary:`
|
|
// because we only require that all specified userInfo values match the
|
|
// notificationInfo values - notificationInfo may contain additional values
|
|
// which we don't care about.
|
|
[userInfo enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) {
|
|
if (![notificationInfo[key] isEqual:obj]) {
|
|
matchesAll = NO;
|
|
*stop = YES;
|
|
}
|
|
}];
|
|
if (matchesAll) {
|
|
[RCTSharedApplication() cancelLocalNotification:notification];
|
|
}
|
|
}
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve
|
|
reject:(__unused RCTPromiseRejectBlock)reject)
|
|
{
|
|
NSMutableDictionary<NSString *, id> *initialNotification =
|
|
[self.bridge.launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] mutableCopy];
|
|
|
|
UILocalNotification *initialLocalNotification =
|
|
self.bridge.launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
|
|
|
|
if (initialNotification) {
|
|
initialNotification[@"remote"] = @YES;
|
|
resolve(initialNotification);
|
|
} else if (initialLocalNotification) {
|
|
resolve(RCTFormatLocalNotification(initialLocalNotification));
|
|
} else {
|
|
resolve((id)kCFNull);
|
|
}
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(getScheduledLocalNotifications:(RCTResponseSenderBlock)callback)
|
|
{
|
|
NSArray<UILocalNotification *> *scheduledLocalNotifications = RCTSharedApplication().scheduledLocalNotifications;
|
|
NSMutableArray<NSDictionary *> *formattedScheduledLocalNotifications = [NSMutableArray new];
|
|
for (UILocalNotification *notification in scheduledLocalNotifications) {
|
|
[formattedScheduledLocalNotifications addObject:RCTFormatLocalNotification(notification)];
|
|
}
|
|
callback(@[formattedScheduledLocalNotifications]);
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(removeAllDeliveredNotifications)
|
|
{
|
|
// TODO: T56867629
|
|
if (@available(iOS 10.0, tvOS 10.0, *)) {
|
|
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
|
[center removeAllDeliveredNotifications];
|
|
}
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(removeDeliveredNotifications:(NSArray<NSString *> *)identifiers)
|
|
{
|
|
// TODO: T56867629
|
|
if (@available(iOS 10.0, tvOS 10.0, *)) {
|
|
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
|
[center removeDeliveredNotificationsWithIdentifiers:identifiers];
|
|
}
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(getDeliveredNotifications:(RCTResponseSenderBlock)callback)
|
|
{
|
|
// TODO: T56867629
|
|
if (@available(iOS 10.0, tvOS 10.0, *)) {
|
|
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]);
|
|
}];
|
|
}
|
|
}
|
|
|
|
#else //TARGET_OS_TV / TARGET_OS_UIKITFORMAC
|
|
|
|
RCT_EXPORT_METHOD(onFinishRemoteNotification:(NSString *)notificationId fetchResult:(NSString *)fetchResult)
|
|
{
|
|
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(setApplicationIconBadgeNumber:(double)number)
|
|
{
|
|
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(getApplicationIconBadgeNumber:(RCTResponseSenderBlock)callback)
|
|
{
|
|
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(requestPermissions:(JS::NativePushNotificationManagerIOS::SpecRequestPermissionsPermission &)permissions
|
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
reject:(RCTPromiseRejectBlock)reject)
|
|
{
|
|
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(abandonPermissions)
|
|
{
|
|
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(checkPermissions:(RCTResponseSenderBlock)callback)
|
|
{
|
|
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(presentLocalNotification:(JS::NativePushNotificationManagerIOS::Notification &)notification)
|
|
{
|
|
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(scheduleLocalNotification:(JS::NativePushNotificationManagerIOS::Notification &)notification)
|
|
{
|
|
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(cancelAllLocalNotifications)
|
|
{
|
|
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(cancelLocalNotifications:(NSDictionary<NSString *, id> *)userInfo)
|
|
{
|
|
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve
|
|
reject:(__unused RCTPromiseRejectBlock)reject)
|
|
{
|
|
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(getScheduledLocalNotifications:(RCTResponseSenderBlock)callback)
|
|
{
|
|
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(removeAllDeliveredNotifications)
|
|
{
|
|
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(removeDeliveredNotifications:(NSArray<NSString *> *)identifiers)
|
|
{
|
|
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
|
|
}
|
|
|
|
RCT_EXPORT_METHOD(getDeliveredNotifications:(RCTResponseSenderBlock)callback)
|
|
{
|
|
RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd));
|
|
}
|
|
|
|
- (NSArray<NSString *> *)supportedEvents
|
|
{
|
|
return @[];
|
|
}
|
|
|
|
#endif //TARGET_OS_TV / TARGET_OS_UIKITFORMAC
|
|
|
|
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModuleWithJsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
|
|
{
|
|
return std::make_shared<facebook::react::NativePushNotificationManagerIOSSpecJSI>(self, jsInvoker);
|
|
}
|
|
|
|
@end
|
|
|
|
Class RCTPushNotificationManagerCls(void) {
|
|
return RCTPushNotificationManager.class;
|
|
}
|