From d0fefcb866b54f2e325202979946e6e5c668e71c Mon Sep 17 00:00:00 2001 From: yogevbd Date: Sat, 3 Aug 2019 22:34:46 +0300 Subject: [PATCH] Identical API for Android and iOS --- RNNotifications/RCTConvert+RNNotifications.h | 2 +- RNNotifications/RCTConvert+RNNotifications.m | 6 +- RNNotifications/RNBridgeModule.m | 4 +- RNNotifications/RNCommandsHandler.h | 2 +- RNNotifications/RNCommandsHandler.m | 4 +- RNNotifications/RNEventEmitter.h | 12 +- RNNotifications/RNEventEmitter.m | 2 +- RNNotifications/RNNotificationCenter.h | 2 +- RNNotifications/RNNotificationCenter.m | 2 +- RNNotifications/RNNotificationEventHandler.m | 4 +- .../RNNotificationEventHandlerTests.m | 4 +- .../wix/reactnativenotifications/Defs.java | 1 - .../RNNotificationsModule.java | 8 +- .../core/notification/PushNotification.java | 9 +- example/android/myapplication/build.gradle | 2 +- .../app/MainActivity.java | 2 +- example/index.android.js | 168 ------------------ example/{index.ios.js => index.js} | 8 +- lib/src/Notifications.ts | 15 +- lib/src/adapters/CompletionCallbackWrapper.ts | 17 +- lib/src/adapters/NativeCommandsSender.ts | 11 +- lib/src/adapters/NativeEventsReceiver.ts | 8 +- lib/src/adapters/UniqueIdProvider.ts | 4 +- lib/src/commands/Commands.test.ts | 27 +-- lib/src/commands/Commands.ts | 10 +- lib/src/events/EventsRegistry.test.ts | 40 ++++- 26 files changed, 129 insertions(+), 245 deletions(-) delete mode 100644 example/index.android.js rename example/{index.ios.js => index.js} (93%) diff --git a/RNNotifications/RCTConvert+RNNotifications.h b/RNNotifications/RCTConvert+RNNotifications.h index e357848..13445ee 100644 --- a/RNNotifications/RCTConvert+RNNotifications.h +++ b/RNNotifications/RCTConvert+RNNotifications.h @@ -10,7 +10,7 @@ @end @interface RCTConvert (UNNotificationRequest) -+ (UNNotificationRequest *)UNNotificationRequest:(id)json withId:(NSString*)notificationId; ++ (UNNotificationRequest *)UNNotificationRequest:(id)json withId:(NSNumber*)notificationId; @end @interface RCTConvert (UNNotification) diff --git a/RNNotifications/RCTConvert+RNNotifications.m b/RNNotifications/RCTConvert+RNNotifications.m index d499892..b9a744b 100644 --- a/RNNotifications/RCTConvert+RNNotifications.m +++ b/RNNotifications/RCTConvert+RNNotifications.m @@ -55,7 +55,7 @@ @implementation RCTConvert (UNNotificationRequest) -+ (UNNotificationRequest *)UNNotificationRequest:(id)json withId:(NSString*)notificationId ++ (UNNotificationRequest *)UNNotificationRequest:(id)json withId:(NSNumber*)notificationId { NSDictionary *details = [self NSDictionary:json]; @@ -68,7 +68,7 @@ if ([RCTConvert BOOL:details[@"silent"]]) { content.sound = nil; } - content.userInfo = [RCTConvert NSDictionary:details[@"userInfo"]] ?: @{}; + content.userInfo = [RCTConvert NSDictionary:details] ?: @{}; content.categoryIdentifier = [RCTConvert NSString:details[@"category"]]; NSDate *triggerDate = [RCTConvert NSDate:details[@"fireDate"]]; @@ -84,7 +84,7 @@ repeats:NO]; } - return [UNNotificationRequest requestWithIdentifier:notificationId + return [UNNotificationRequest requestWithIdentifier:[NSString stringWithFormat:@"%@", notificationId] content:content trigger:trigger]; } diff --git a/RNNotifications/RNBridgeModule.m b/RNNotifications/RNBridgeModule.m index 804d3cf..cf319ed 100644 --- a/RNNotifications/RNBridgeModule.m +++ b/RNNotifications/RNBridgeModule.m @@ -68,8 +68,8 @@ RCT_EXPORT_METHOD(setBadgesCount:(int)count) { [_commandsHandler setBadgesCount:count]; } -RCT_EXPORT_METHOD(localNotification:(NSDictionary *)notification withId:(NSString *)notificationId) { - [_commandsHandler sendLocalNotification:notification withId:notificationId]; +RCT_EXPORT_METHOD(postLocalNotification:(NSDictionary *)notification withId:(nonnull NSNumber *)notificationId) { + [_commandsHandler postLocalNotification:notification withId:notificationId]; } RCT_EXPORT_METHOD(cancelLocalNotification:(NSString *)notificationId) { diff --git a/RNNotifications/RNCommandsHandler.h b/RNNotifications/RNCommandsHandler.h index a55b795..2cf4044 100644 --- a/RNNotifications/RNCommandsHandler.h +++ b/RNNotifications/RNCommandsHandler.h @@ -23,7 +23,7 @@ - (void)setBadgesCount:(int)count; -- (void)sendLocalNotification:(NSDictionary *)notification withId:(NSString *)notificationId; +- (void)postLocalNotification:(NSDictionary *)notification withId:(NSNumber *)notificationId; - (void)cancelLocalNotification:(NSString *)notificationId; diff --git a/RNNotifications/RNCommandsHandler.m b/RNNotifications/RNCommandsHandler.m index e0e3061..e1ac12f 100644 --- a/RNNotifications/RNCommandsHandler.m +++ b/RNNotifications/RNCommandsHandler.m @@ -50,8 +50,8 @@ [[UIApplication sharedApplication] setApplicationIconBadgeNumber:count]; } -- (void)sendLocalNotification:(NSDictionary *)notification withId:(NSString *)notificationId { - [_notificationCenter sendLocalNotification:notification withId:notificationId]; +- (void)postLocalNotification:(NSDictionary *)notification withId:(NSNumber *)notificationId { + [_notificationCenter postLocalNotification:notification withId:notificationId]; } - (void)cancelLocalNotification:(NSString *)notificationId { diff --git a/RNNotifications/RNEventEmitter.h b/RNNotifications/RNEventEmitter.h index 011477d..691cf03 100644 --- a/RNNotifications/RNEventEmitter.h +++ b/RNNotifications/RNEventEmitter.h @@ -1,11 +1,11 @@ #import -static NSString* const RNRegistered = @"remoteNotificationsRegistered"; -static NSString* const RNRegistrationFailed = @"remoteNotificationsRegistrationFailed"; -static NSString* const RNPushKitRegistered = @"pushKitRegistered"; -static NSString* const RNNotificationReceivedForeground = @"notificationReceivedForeground"; -static NSString* const RNNotificationOpened = @"notificationOpened"; -static NSString* const RNPushKitNotificationReceived = @"pushKitNotificationReceived"; +static NSString* const RNRegistered = @"remoteNotificationsRegistered"; +static NSString* const RNRegistrationFailed = @"remoteNotificationsRegistrationFailed"; +static NSString* const RNPushKitRegistered = @"pushKitRegistered"; +static NSString* const RNNotificationReceived = @"notificationReceived"; +static NSString* const RNNotificationOpened = @"notificationOpened"; +static NSString* const RNPushKitNotificationReceived = @"pushKitNotificationReceived"; @interface RNEventEmitter : RCTEventEmitter diff --git a/RNNotifications/RNEventEmitter.m b/RNNotifications/RNEventEmitter.m index c5764b1..c6d7a70 100644 --- a/RNNotifications/RNEventEmitter.m +++ b/RNNotifications/RNEventEmitter.m @@ -8,7 +8,7 @@ RCT_EXPORT_MODULE(); return @[RNRegistered, RNRegistrationFailed, RNPushKitRegistered, - RNNotificationReceivedForeground, + RNNotificationReceived, RNNotificationOpened, RNPushKitNotificationReceived]; } diff --git a/RNNotifications/RNNotificationCenter.h b/RNNotifications/RNNotificationCenter.h index df33f6c..06f38cd 100644 --- a/RNNotifications/RNNotificationCenter.h +++ b/RNNotifications/RNNotificationCenter.h @@ -16,7 +16,7 @@ typedef void (^RCTPromiseRejectBlock)(NSString *code, NSString *message, NSError - (void)checkPermissions:(RCTPromiseResolveBlock)resolve; -- (void)sendLocalNotification:(NSDictionary *)notification withId:(NSString *)notificationId; +- (void)postLocalNotification:(NSDictionary *)notification withId:(NSNumber *)notificationId; - (void)cancelLocalNotification:(NSString *)notificationId; diff --git a/RNNotifications/RNNotificationCenter.m b/RNNotifications/RNNotificationCenter.m index 92ef14c..bc75902 100644 --- a/RNNotifications/RNNotificationCenter.m +++ b/RNNotifications/RNNotificationCenter.m @@ -30,7 +30,7 @@ [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:categories]; } -- (void)sendLocalNotification:(NSDictionary *)notification withId:(NSString *)notificationId { +- (void)postLocalNotification:(NSDictionary *)notification withId:(NSNumber *)notificationId { UNNotificationRequest* localNotification = [RCTConvert UNNotificationRequest:notification withId:notificationId]; [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:localNotification withCompletionHandler:nil]; } diff --git a/RNNotifications/RNNotificationEventHandler.m b/RNNotifications/RNNotificationEventHandler.m index edc4fd4..1075d42 100644 --- a/RNNotifications/RNNotificationEventHandler.m +++ b/RNNotifications/RNNotificationEventHandler.m @@ -25,12 +25,12 @@ - (void)didReceiveForegroundNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { [_store setPresentationCompletionHandler:completionHandler withCompletionKey:notification.request.identifier]; - [RNEventEmitter sendEvent:RNNotificationReceivedForeground body:[RNNotificationParser parseNotification:notification]]; + [RNEventEmitter sendEvent:RNNotificationReceived body:[RNNotificationParser parseNotification:notification]]; } - (void)didReceiveNotificationResponse:(UNNotificationResponse *)response completionHandler:(void (^)(void))completionHandler { [_store setActionCompletionHandler:completionHandler withCompletionKey:response.notification.request.identifier]; - [RNEventEmitter sendEvent:RNNotificationOpened body:[RNNotificationParser parseNotificationResponse:response]]; + [RNEventEmitter sendEvent:RNNotificationOpened body:[RNNotificationParser parseNotification:response.notification]]; } @end diff --git a/RNNotifications/RNNotificationsTests/RNNotificationEventHandlerTests.m b/RNNotifications/RNNotificationsTests/RNNotificationEventHandlerTests.m index 1bdaca9..c2c3039 100644 --- a/RNNotifications/RNNotificationsTests/RNNotificationEventHandlerTests.m +++ b/RNNotifications/RNNotificationsTests/RNNotificationEventHandlerTests.m @@ -60,9 +60,9 @@ UNNotification* notification = [self createNotificationWithIdentifier:@"id" andUserInfo:@{@"extraKey": @"extraValue"}]; void (^testBlock)(UNNotificationPresentationOptions) = ^void(UNNotificationPresentationOptions options) {}; - [[_mockedNotificationCenter expect] postNotificationName:RNNotificationReceivedForeground object:[OCMArg any] userInfo:[OCMArg checkWithBlock:^BOOL(id obj) { + [[_mockedNotificationCenter expect] postNotificationName:RNNotificationReceived object:[OCMArg any] userInfo:[OCMArg checkWithBlock:^BOOL(id obj) { return ([[obj valueForKey:@"identifier"] isEqualToString:@"id"] && - [[[obj valueForKey:@"data"] valueForKey:@"extraKey"] isEqualToString:@"extraValue"]); + [[obj valueForKey:@"extraKey"] isEqualToString:@"extraValue"]); }]]; [_uut didReceiveForegroundNotification:notification withCompletionHandler:testBlock]; [_mockedNotificationCenter verify]; diff --git a/android/app/src/main/java/com/wix/reactnativenotifications/Defs.java b/android/app/src/main/java/com/wix/reactnativenotifications/Defs.java index ec7f72a..5256baa 100644 --- a/android/app/src/main/java/com/wix/reactnativenotifications/Defs.java +++ b/android/app/src/main/java/com/wix/reactnativenotifications/Defs.java @@ -6,6 +6,5 @@ public interface Defs { String TOKEN_RECEIVED_EVENT_NAME = "remoteNotificationsRegistered"; String NOTIFICATION_RECEIVED_EVENT_NAME = "notificationReceived"; - String NOTIFICATION_RECEIVED_FOREGROUND_EVENT_NAME = "notificationReceivedInForeground"; String NOTIFICATION_OPENED_EVENT_NAME = "notificationOpened"; } diff --git a/android/app/src/main/java/com/wix/reactnativenotifications/RNNotificationsModule.java b/android/app/src/main/java/com/wix/reactnativenotifications/RNNotificationsModule.java index 61dddec..c64c75e 100644 --- a/android/app/src/main/java/com/wix/reactnativenotifications/RNNotificationsModule.java +++ b/android/app/src/main/java/com/wix/reactnativenotifications/RNNotificationsModule.java @@ -14,6 +14,7 @@ import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.wix.reactnativenotifications.core.AppLifecycleFacadeHolder; import com.wix.reactnativenotifications.core.InitialNotificationHolder; @@ -41,7 +42,7 @@ public class RNNotificationsModule extends ReactContextBaseJavaModule implements @Override public String getName() { - return "WixRNNotifications"; + return "RNBridgeModule"; } @Override @@ -106,6 +107,11 @@ public class RNNotificationsModule extends ReactContextBaseJavaModule implements notificationsDrawer.onNotificationClearRequest(notificationId); } + @ReactMethod + public void setCategories(ReadableArray categories) { + + } + @ReactMethod public void isRegisteredForRemoteNotifications(Promise promise) { boolean hasPermission = NotificationManagerCompat.from(getReactApplicationContext()).areNotificationsEnabled(); diff --git a/android/app/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java b/android/app/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java index 5e4e3d2..91fd8cc 100644 --- a/android/app/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java +++ b/android/app/src/main/java/com/wix/reactnativenotifications/core/notification/PushNotification.java @@ -23,7 +23,7 @@ import com.wix.reactnativenotifications.core.ProxyService; import static com.wix.reactnativenotifications.Defs.NOTIFICATION_OPENED_EVENT_NAME; import static com.wix.reactnativenotifications.Defs.NOTIFICATION_RECEIVED_EVENT_NAME; -import static com.wix.reactnativenotifications.Defs.NOTIFICATION_RECEIVED_FOREGROUND_EVENT_NAME; + public class PushNotification implements IPushNotification { @@ -64,9 +64,6 @@ public class PushNotification implements IPushNotification { public void onReceived() throws InvalidNotificationException { postNotification(null); notifyReceivedToJS(); - if (mAppLifecycleFacade.isAppVisible()) { - notifiyReceivedForegroundNotificationToJS(); - } } @Override @@ -192,10 +189,6 @@ public class PushNotification implements IPushNotification { mJsIOHelper.sendEventToJS(NOTIFICATION_RECEIVED_EVENT_NAME, mNotificationProps.asBundle(), mAppLifecycleFacade.getRunningReactContext()); } - private void notifiyReceivedForegroundNotificationToJS() { - mJsIOHelper.sendEventToJS(NOTIFICATION_RECEIVED_FOREGROUND_EVENT_NAME, mNotificationProps.asBundle(), mAppLifecycleFacade.getRunningReactContext()); - } - private void notifyOpenedToJS() { mJsIOHelper.sendEventToJS(NOTIFICATION_OPENED_EVENT_NAME, mNotificationProps.asBundle(), mAppLifecycleFacade.getRunningReactContext()); } diff --git a/example/android/myapplication/build.gradle b/example/android/myapplication/build.gradle index b354d5a..5c8cbee 100644 --- a/example/android/myapplication/build.gradle +++ b/example/android/myapplication/build.gradle @@ -3,7 +3,7 @@ apply plugin: "com.android.application" project.ext.react = [ root : "../../../", entryFile: "index.js", - bundleAssetName: "index.android.bundle", + bundleAssetName: "index.bundle", bundleInAlpha: true, bundleInBeta: true ] diff --git a/example/android/myapplication/src/main/java/com/wix/reactnativenotifications/app/MainActivity.java b/example/android/myapplication/src/main/java/com/wix/reactnativenotifications/app/MainActivity.java index 4459a6a..0aa9149 100644 --- a/example/android/myapplication/src/main/java/com/wix/reactnativenotifications/app/MainActivity.java +++ b/example/android/myapplication/src/main/java/com/wix/reactnativenotifications/app/MainActivity.java @@ -35,6 +35,6 @@ public class MainActivity extends ReactActivity { } private void startReactApplication() { - mReactRootView.startReactApplication(getReactInstanceManager(), "WixRNNotifications", null); + mReactRootView.startReactApplication(getReactInstanceManager(), "NotificationsExampleApp", null); } } diff --git a/example/index.android.js b/example/index.android.js deleted file mode 100644 index 5c7faaf..0000000 --- a/example/index.android.js +++ /dev/null @@ -1,168 +0,0 @@ -'use strict'; - -import React, {Component} from 'react'; -import { - AppRegistry, - StyleSheet, - Text, - View, - Button, - TouchableHighlight -} from 'react-native'; - -import {NotificationsAndroid, PendingNotifications} from 'react-native-notifications'; - -let mainScreen; - -function onPushRegistered() { - if (mainScreen) { - mainScreen.onPushRegistered(); - } -} - -function onNotificationOpened(notification) { - if (mainScreen) { - mainScreen.onNotificationOpened(notification) - } -} - -function onNotificationReceived(notification) { - if (mainScreen) { - mainScreen.onNotificationReceived(notification) - } -} - -// It's highly recommended to keep listeners registration at global scope rather than at screen-scope seeing that -// component mount and unmount lifecycle tends to be asymmetric! -NotificationsAndroid.setRegistrationTokenUpdateListener(onPushRegistered); -NotificationsAndroid.setNotificationOpenedListener(onNotificationOpened); -NotificationsAndroid.setNotificationReceivedListener(onNotificationReceived); - -const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'center', - }, - titleText: { - fontSize: 24, - textAlign: 'center', - margin: 10, - }, - bodyText: { - fontSize: 18, - textAlign: 'center', - margin: 10, - }, - mainButtonText: { - fontSize: 25, - fontStyle: 'italic', - fontWeight: 'bold', - textAlign: 'center', - margin: 10, - }, - plainButtonText: { - fontSize: 18, - fontStyle: 'italic', - textAlign: 'center', - margin: 10, - }, -}); - -class MainComponent extends Component { - - constructor(props) { - super(props); - - this.onPostNotification = this.onPostNotification.bind(this); - this.onCancelNotification = this.onCancelNotification.bind(this); - - this.state = { - elapsed: 0, - lastNotification: undefined - }; - - console.log('ReactScreen', 'ReactScreen'); - mainScreen = this; - - setInterval(this.onTick.bind(this), 1000); - } - - componentDidMount() { - console.log('ReactScreen', 'componentDidMount'); - PendingNotifications.getInitialNotification() - .then((notification) => {console.log("getInitialNotification:", notification); this.setState({initialNotification: (notification ? notification.getData() : undefined)});}) - .catch((err) => console.error("getInitialNotifiation failed", err)); - } - - componentWillUnmount() { - console.log('ReactScreen', 'componentWillUnmount'); - } - - onTick() { - this.setState({elapsed: this.state.elapsed + 1}); - } - - onPostNotification() { - this.lastNotificationId = NotificationsAndroid.localNotification({title: "Local notification", body: "This notification was generated by the app!"}); - } - - onCancelNotification() { - if (this.lastNotificationId) { - NotificationsAndroid.cancelLocalNotification(this.lastNotificationId); - this.lastNotificationId = undefined; - } - } - - render() { - return ( - - Wix React Native Notifications - {this.state.initialNotification ? 'Opened from notification' : ''} - Last notification: {this.state.lastNotification ? '\n'+this.state.lastNotification.body + ` (opened at ''${this.state.notificationRxTime})` : "N/A"} - Time elapsed: {this.state.elapsed} - {"\n\n"} - this.onPostNotification()}> - Try Me! - - this.onCancelNotification()}> - Undo last - - this.onCheckPermissions()}> - Check permissions - -