Skip to content

feat: replace apple-deprecated notification method #66

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ios/RNCPushNotificationIOS.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ extern NSString *const RNCRemoteNotificationReceived;

typedef void (^RNCRemoteNotificationCallback)(UIBackgroundFetchResult result);

#if !TARGET_OS_TV
#if !TARGET_OS_TV && !TARGET_OS_UIKITFORMAC
+ (void)didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings;
+ (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
+ (void)didReceiveRemoteNotification:(NSDictionary *)notification;
Expand Down
192 changes: 127 additions & 65 deletions ios/RNCPushNotificationIOS.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

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";
Expand Down Expand Up @@ -68,20 +67,20 @@ + (UILocalNotification *)UILocalNotification:(id)json
}

RCT_ENUM_CONVERTER(UIBackgroundFetchResult, (@{
@"UIBackgroundFetchResultNewData": @(UIBackgroundFetchResultNewData),
@"UIBackgroundFetchResultNoData": @(UIBackgroundFetchResultNoData),
@"UIBackgroundFetchResultFailed": @(UIBackgroundFetchResultFailed),
}), UIBackgroundFetchResultNoData, integerValue)
@"UIBackgroundFetchResultNewData": @(UIBackgroundFetchResultNewData),
@"UIBackgroundFetchResultNoData": @(UIBackgroundFetchResultNoData),
@"UIBackgroundFetchResultFailed": @(UIBackgroundFetchResultFailed),
}), UIBackgroundFetchResultNoData, integerValue)

@end
#endif //TARGET_OS_TV
#else
@interface RNCPushNotificationIOS () <NativePushNotificationManagerIOS>
@end
#endif //TARGET_OS_TV / TARGET_OS_UIKITFORMAC

@implementation RNCPushNotificationIOS
{
RCTPromiseResolveBlock _requestPermissionsResolveBlock;
}

#if !TARGET_OS_TV
#if !TARGET_OS_TV && !TARGET_OS_UIKITFORMAC

static NSDictionary *RCTFormatLocalNotification(UILocalNotification *notification)
{
Expand All @@ -102,6 +101,7 @@ @implementation RNCPushNotificationIOS
return formattedLocalNotification;
}

API_AVAILABLE(ios(10.0))
static NSDictionary *RCTFormatUNNotification(UNNotification *notification)
{
NSMutableDictionary *formattedNotification = [NSMutableDictionary dictionary];
Expand All @@ -125,7 +125,7 @@ @implementation RNCPushNotificationIOS
return formattedNotification;
}

#endif //TARGET_OS_TV
#endif //TARGET_OS_TV / TARGET_OS_UIKITFORMAC

RCT_EXPORT_MODULE()

Expand All @@ -134,7 +134,7 @@ - (dispatch_queue_t)methodQueue
return dispatch_get_main_queue();
}

#if !TARGET_OS_TV
#if !TARGET_OS_TV && !TARGET_OS_UIKITFORMAC
- (void)startObserving
{
[[NSNotificationCenter defaultCenter] addObserver:self
Expand All @@ -145,10 +145,6 @@ - (void)startObserving
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
Expand All @@ -174,19 +170,13 @@ - (void)stopObserving

+ (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 = deviceToken.bytes;
const unsigned char *bytes = reinterpret_cast<const unsigned char *>(deviceToken.bytes);
for (NSUInteger i = 0; i < deviceTokenLength; i++) {
[hexString appendFormat:@"%02x", bytes[i]];
}
Expand Down Expand Up @@ -258,32 +248,13 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification
{
NSError *error = notification.userInfo[@"error"];
NSDictionary *errorDetails = @{
@"message": error.localizedDescription,
@"code": @(error.code),
@"details": error.userInfo,
};
@"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:(UIBackgroundFetchResult)result) {
RNCRemoteNotificationCallback completionHandler = self.remoteNotificationCallbacks[notificationId];
if (!completionHandler) {
Expand Down Expand Up @@ -318,15 +289,9 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification
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) {
Expand All @@ -343,9 +308,19 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification
types = UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound;
}

UIUserNotificationSettings *notificationSettings =
[UIUserNotificationSettings settingsForTypes:types categories:nil];
[RCTSharedApplication() registerUserNotificationSettings:notificationSettings];
[UNUserNotificationCenter.currentNotificationCenter
requestAuthorizationWithOptions:types
completionHandler:^(BOOL granted, NSError *_Nullable error) {

if (error != NULL) {
reject(@"-1", @"Error - Push authorization request failed.", error);
} else {
[RCTSharedApplication() registerForRemoteNotifications];
[UNUserNotificationCenter.currentNotificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
resolve(RCTPromiseResolveValueForUNNotificationSettings(settings));
}];
}
}];
}

RCT_EXPORT_METHOD(abandonPermissions)
Expand All @@ -356,16 +331,24 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification
RCT_EXPORT_METHOD(checkPermissions:(RCTResponseSenderBlock)callback)
{
if (RCTRunningInAppExtension()) {
callback(@[@{@"alert": @NO, @"badge": @NO, @"sound": @NO}]);
callback(@[RCTSettingsDictForUNNotificationSettings(NO, NO, NO)]);
return;
}

NSUInteger types = [RCTSharedApplication() currentUserNotificationSettings].types;
callback(@[@{
@"alert": @((types & UIUserNotificationTypeAlert) > 0),
@"badge": @((types & UIUserNotificationTypeBadge) > 0),
@"sound": @((types & UIUserNotificationTypeSound) > 0),
}]);
[UNUserNotificationCenter.currentNotificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
callback(@[RCTPromiseResolveValueForUNNotificationSettings(settings)]);
}];
}

static inline NSDictionary *RCTPromiseResolveValueForUNNotificationSettings(UNNotificationSettings* _Nonnull settings) {
return RCTSettingsDictForUNNotificationSettings(settings.alertSetting == UNNotificationSettingEnabled,
settings.badgeSetting == UNNotificationSettingEnabled,
settings.soundSetting == UNNotificationSettingEnabled);
}

static inline NSDictionary *RCTSettingsDictForUNNotificationSettings(BOOL alert, BOOL badge, BOOL sound) {
return @{@"alert": @(alert), @"badge": @(badge), @"sound": @(sound)};
}
}

RCT_EXPORT_METHOD(presentLocalNotification:(UILocalNotification *)notification)
Expand Down Expand Up @@ -464,13 +447,92 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification
}
}

#else //TARGET_OS_TV
#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
#endif //TARGET_OS_TV / TARGET_OS_UIKITFORMAC

@end