diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h index fd1ceb9c9d9c4d..cf754c044933f7 100644 --- a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h +++ b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h @@ -2054,9 +2054,9 @@ namespace facebook { namespace JS { namespace NativePushNotificationManagerIOS { struct SpecRequestPermissionsPermission { - folly::Optional alert() const; - folly::Optional badge() const; - folly::Optional sound() const; + bool alert() const; + bool badge() const; + bool sound() const; SpecRequestPermissionsPermission(NSDictionary *const v) : _v(v) {} private: @@ -3568,20 +3568,20 @@ inline JS::NativePlatformConstantsIOS::Constants::Builder::Builder(const Input i inline JS::NativePlatformConstantsIOS::Constants::Builder::Builder(Constants i) : _factory(^{ return i.unsafeRawValue(); }) {} -inline folly::Optional JS::NativePushNotificationManagerIOS::SpecRequestPermissionsPermission::alert() const +inline bool JS::NativePushNotificationManagerIOS::SpecRequestPermissionsPermission::alert() const { id const p = _v[@"alert"]; - return RCTBridgingToOptionalBool(p); + return RCTBridgingToBool(p); } -inline folly::Optional JS::NativePushNotificationManagerIOS::SpecRequestPermissionsPermission::badge() const +inline bool JS::NativePushNotificationManagerIOS::SpecRequestPermissionsPermission::badge() const { id const p = _v[@"badge"]; - return RCTBridgingToOptionalBool(p); + return RCTBridgingToBool(p); } -inline folly::Optional JS::NativePushNotificationManagerIOS::SpecRequestPermissionsPermission::sound() const +inline bool JS::NativePushNotificationManagerIOS::SpecRequestPermissionsPermission::sound() const { id const p = _v[@"sound"]; - return RCTBridgingToOptionalBool(p); + return RCTBridgingToBool(p); } inline bool JS::NativePushNotificationManagerIOS::Permissions::alert() const { diff --git a/Libraries/PushNotificationIOS/NativePushNotificationManagerIOS.js b/Libraries/PushNotificationIOS/NativePushNotificationManagerIOS.js index 8eb5095163681c..3ff1b129841c08 100644 --- a/Libraries/PushNotificationIOS/NativePushNotificationManagerIOS.js +++ b/Libraries/PushNotificationIOS/NativePushNotificationManagerIOS.js @@ -46,9 +46,9 @@ export interface Spec extends TurboModule { +setApplicationIconBadgeNumber: (num: number) => void; +getApplicationIconBadgeNumber: (callback: (num: number) => void) => void; +requestPermissions: (permission: {| - +alert?: ?boolean, - +badge?: ?boolean, - +sound?: ?boolean, + +alert: boolean, + +badge: boolean, + +sound: boolean, |}) => Promise; +abandonPermissions: () => void; +checkPermissions: (callback: (permissions: Permissions) => void) => void; diff --git a/Libraries/PushNotificationIOS/PushNotificationIOS.js b/Libraries/PushNotificationIOS/PushNotificationIOS.js index ed25d41d3936fa..43548d4a7aa0bc 100644 --- a/Libraries/PushNotificationIOS/PushNotificationIOS.js +++ b/Libraries/PushNotificationIOS/PushNotificationIOS.js @@ -306,19 +306,17 @@ class PushNotificationIOS { badge: boolean, sound: boolean, }> { - let requestedPermissions = {}; + let requestedPermissions = { + alert: true, + badge: true, + sound: true, + }; if (permissions) { requestedPermissions = { alert: !!permissions.alert, badge: !!permissions.badge, sound: !!permissions.sound, }; - } else { - requestedPermissions = { - alert: true, - badge: true, - sound: true, - }; } invariant( NativePushNotificationManagerIOS, diff --git a/Libraries/PushNotificationIOS/RCTPushNotificationManager.m b/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm similarity index 75% rename from Libraries/PushNotificationIOS/RCTPushNotificationManager.m rename to Libraries/PushNotificationIOS/RCTPushNotificationManager.mm index 019649ad4117ab..09d2c42a40ffbd 100644 --- a/Libraries/PushNotificationIOS/RCTPushNotificationManager.m +++ b/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm @@ -9,11 +9,14 @@ #import +#import #import #import #import #import +#import "RCTPushNotificationPlugins.h" + NSString *const RCTRemoteNotificationReceived = @"RemoteNotificationReceived"; static NSString *const kLocalNotificationReceived = @"LocalNotificationReceived"; @@ -40,7 +43,7 @@ @implementation RCTConvert (NSCalendarUnit) @end -@interface RCTPushNotificationManager () +@interface RCTPushNotificationManager () @property (nonatomic, strong) NSMutableDictionary *remoteNotificationCallbacks; @end @@ -73,6 +76,9 @@ + (UILocalNotification *)UILocalNotification:(id)json @"UIBackgroundFetchResultFailed": @(UIBackgroundFetchResultFailed), }), UIBackgroundFetchResultNoData, integerValue) +@end +#else +@interface RCTPushNotificationManager () @end #endif //TARGET_OS_TV / TARGET_OS_UIKITFORMAC @@ -187,7 +193,7 @@ + (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSMutableString *hexString = [NSMutableString string]; NSUInteger deviceTokenLength = deviceToken.length; - const unsigned char *bytes = deviceToken.bytes; + const unsigned char *bytes = reinterpret_cast(deviceToken.bytes); for (NSUInteger i = 0; i < deviceTokenLength; i++) { [hexString appendFormat:@"%02x", bytes[i]]; } @@ -285,7 +291,8 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification _requestPermissionsResolveBlock = nil; } -RCT_EXPORT_METHOD(onFinishRemoteNotification:(NSString *)notificationId fetchResult:(UIBackgroundFetchResult)result) { +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); @@ -298,7 +305,7 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification /** * Update the application icon badge number on the home screen */ -RCT_EXPORT_METHOD(setApplicationIconBadgeNumber:(NSInteger)number) +RCT_EXPORT_METHOD(setApplicationIconBadgeNumber:(double)number) { RCTSharedApplication().applicationIconBadgeNumber = number; } @@ -311,9 +318,9 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification callback(@[@(RCTSharedApplication().applicationIconBadgeNumber)]); } -RCT_EXPORT_METHOD(requestPermissions:(NSDictionary *)permissions - resolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) +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")); @@ -330,18 +337,15 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification _requestPermissionsResolveBlock = resolve; UIUserNotificationType types = UIUserNotificationTypeNone; - if (permissions) { - if ([RCTConvert BOOL:permissions[@"alert"]]) { - types |= UIUserNotificationTypeAlert; - } - if ([RCTConvert BOOL:permissions[@"badge"]]) { - types |= UIUserNotificationTypeBadge; - } - if ([RCTConvert BOOL:permissions[@"sound"]]) { - types |= UIUserNotificationTypeSound; - } - } else { - types = UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound; + + if (permissions.alert()) { + types |= UIUserNotificationTypeAlert; + } + if (permissions.badge()) { + types |= UIUserNotificationTypeBadge; + } + if (permissions.sound()) { + types |= UIUserNotificationTypeSound; } UIUserNotificationSettings *notificationSettings = @@ -369,14 +373,46 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification }]); } -RCT_EXPORT_METHOD(presentLocalNotification:(UILocalNotification *)notification) +RCT_EXPORT_METHOD(presentLocalNotification:(JS::NativePushNotificationManagerIOS::Notification &)notification) { - [RCTSharedApplication() presentLocalNotificationNow: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:(UILocalNotification *)notification) +RCT_EXPORT_METHOD(scheduleLocalNotification:(JS::NativePushNotificationManagerIOS::Notification &)notification) { - [RCTSharedApplication() scheduleLocalNotification: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) @@ -470,6 +506,84 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification #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 *)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 *)identifiers) +{ + RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd)); +} + +RCT_EXPORT_METHOD(getDeliveredNotifications:(RCTResponseSenderBlock)callback) +{ + RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd)); +} + - (NSArray *)supportedEvents { return @[]; @@ -477,4 +591,13 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification #endif //TARGET_OS_TV / TARGET_OS_UIKITFORMAC +- (std::shared_ptr)getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker +{ + return std::make_shared(self, jsInvoker); +} + @end + +Class RCTPushNotificationManagerCls(void) { + return RCTPushNotificationManager.class; +} diff --git a/Libraries/PushNotificationIOS/RCTPushNotificationPlugins.h b/Libraries/PushNotificationIOS/RCTPushNotificationPlugins.h new file mode 100644 index 00000000000000..34c8f014b33afb --- /dev/null +++ b/Libraries/PushNotificationIOS/RCTPushNotificationPlugins.h @@ -0,0 +1,40 @@ +/** + * 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. + * + * @generated by an internal plugin build system + */ + +#ifdef RN_DISABLE_OSS_PLUGIN_HEADER + +// FB Internal: FBRCTPushNotificationPlugins.h is autogenerated by the build system. +#import + +#else + +// OSS-compatibility layer + +#import + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage" + +#ifdef __cplusplus +extern "C" { +#endif + +// RCTTurboModuleManagerDelegate should call this to resolve module classes. +Class RCTPushNotificationClassProvider(const char *name); + +// Lookup functions +Class RCTPushNotificationManagerCls(void) __attribute__((used)); + +#ifdef __cplusplus +} +#endif + +#pragma GCC diagnostic pop + +#endif // RN_DISABLE_OSS_PLUGIN_HEADER diff --git a/Libraries/PushNotificationIOS/RCTPushNotificationPlugins.mm b/Libraries/PushNotificationIOS/RCTPushNotificationPlugins.mm new file mode 100644 index 00000000000000..587a7b17a86688 --- /dev/null +++ b/Libraries/PushNotificationIOS/RCTPushNotificationPlugins.mm @@ -0,0 +1,32 @@ +/** + * 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. + * + * @generated by an internal plugin build system + */ + +#ifndef RN_DISABLE_OSS_PLUGIN_HEADER + +// OSS-compatibility layer + +#import "RCTPushNotificationPlugins.h" + +#import +#import + +Class RCTPushNotificationClassProvider(const char *name) { + static std::unordered_map sCoreModuleClassMap = { + {"PushNotificationManager", RCTPushNotificationManagerCls}, + }; + + auto p = sCoreModuleClassMap.find(name); + if (p != sCoreModuleClassMap.end()) { + auto classFunc = p->second; + return classFunc(); + } + return nil; +} + +#endif // RN_DISABLE_OSS_PLUGIN_HEADER diff --git a/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec b/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec index a15cc0186d6c99..dd60fb15859f82 100644 --- a/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec +++ b/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec @@ -16,19 +16,32 @@ else source[:tag] = "v#{version}" end +folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' +folly_version = '2018.10.22.00' + Pod::Spec.new do |s| s.name = "React-RCTPushNotification" s.version = version - s.summary = "A library for handling push notifications for your app, including permission handling and icon badge number." + s.summary = "A library for handling push notifications for your app, including permission handling and icon badge number." s.homepage = "http://facebook.github.io/react-native/" s.documentation_url = "https://facebook.github.io/react-native/docs/pushnotificationios" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" s.platforms = { :ios => "9.0", :tvos => "9.2" } + s.compiler_flags = folly_compiler_flags + ' -Wno-nullability-completeness' s.source = source - s.source_files = "*.{m}" + s.source_files = "*.{m,mm}" s.preserve_paths = "package.json", "LICENSE", "LICENSE-docs" s.header_dir = "RCTPushNotification" + s.pod_target_xcconfig = { + "USE_HEADERMAP" => "YES", + "CLANG_CXX_LANGUAGE_STANDARD" => "c++14", + "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/Folly\"" + } + s.framework = "UserNotifications" + s.dependency "FBReactNativeSpec", version + s.dependency "RCTTypeSafety", version s.dependency "React-Core/RCTPushNotificationHeaders", version + s.dependency "ReactCommon/turbomodule/core", version end diff --git a/RNTester/Podfile.lock b/RNTester/Podfile.lock index a4df36729205ba..00f017ed4c4272 100644 --- a/RNTester/Podfile.lock +++ b/RNTester/Podfile.lock @@ -234,7 +234,10 @@ PODS: - React-Core/RCTNetworkHeaders (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTPushNotification (1000.0.0): + - FBReactNativeSpec (= 1000.0.0) + - RCTTypeSafety (= 1000.0.0) - React-Core/RCTPushNotificationHeaders (= 1000.0.0) + - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTSettings (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - Folly (= 2018.10.22.00) @@ -394,7 +397,7 @@ SPEC CHECKSUMS: React-RCTImage: 3ee9a6cd02c7741ebe3a001d51a18c349019778f React-RCTLinking: 7ccb8f6dcfd4b95b68a73119aca7bca9fa530b08 React-RCTNetwork: 565fa6cc6108db9210fe5774f04ce52edccbb8ed - React-RCTPushNotification: acffa8af6a20e6d41b041a8c4cb4bea0de9df0dd + React-RCTPushNotification: 494ccfc569e2a699c0cc1a816eaebf8197a2ebc8 React-RCTSettings: 8138286da8de74839cb436dd37704ed64d4bfe78 React-RCTTest: d148e0657ce77ffd43a10325c284f47f25fb0532 React-RCTText: 9078167d3bc011162326f2d8ef4dd580ec1eca17