diff --git a/Apps/APN/ios/AppDelegate.mm b/Apps/APN/ios/AppDelegate.mm index f654d00b..e21459d2 100644 --- a/Apps/APN/ios/AppDelegate.mm +++ b/Apps/APN/ios/AppDelegate.mm @@ -8,6 +8,7 @@ #import #import #import +#import "RNNotifications.h" #if RCT_NEW_ARCH_ENABLED #import @@ -76,7 +77,9 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; - [pnHandlerObj setupCustomerIOClickHandling:self]; + [pnHandlerObj setupCustomerIOClickHandling]; + + [RNNotifications startMonitorNotifications]; return YES; } @@ -156,6 +159,8 @@ - (void)application:(UIApplication *)application didRegisterForRemoteNotificatio { // Register device to receive push notifications with device token [pnHandlerObj application:application deviceToken:deviceToken]; + + [RNNotifications didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; } // Required for the notification event. You must call the completion handler after handling the remote notification. @@ -163,28 +168,16 @@ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(N fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; + + [RNNotifications didReceiveBackgroundNotification:userInfo withCompletionHandler:completionHandler]; } // Required for the registrationError event. - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { [pnHandlerObj application:application error:error]; -} -// Required for localNotification event -- (void)userNotificationCenter:(UNUserNotificationCenter *)center -didReceiveNotificationResponse:(UNNotificationResponse *)response - withCompletionHandler:(void (^)(void))completionHandler -{ - [pnHandlerObj userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler]; - - [RNCPushNotificationIOS didReceiveNotificationResponse:response]; -} - -//Called when a notification is delivered to a foreground app. --(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler -{ - completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionList | UNNotificationPresentationOptionBanner | UNNotificationPresentationOptionBadge); + [RNNotifications didFailToRegisterForRemoteNotificationsWithError:error]; } // Deep linking diff --git a/Apps/APN/ios/MyAppPushNotificationsHandler.swift b/Apps/APN/ios/MyAppPushNotificationsHandler.swift index d61d56d9..acd4bd8e 100644 --- a/Apps/APN/ios/MyAppPushNotificationsHandler.swift +++ b/Apps/APN/ios/MyAppPushNotificationsHandler.swift @@ -1,15 +1,21 @@ import Foundation import CioMessagingPushAPN -import UserNotifications import CioTracking +/** + * This file was created based on the Customer.io React Native SDK documentation for setting up push notifications in your app. + * + * See the documentation to learn how to add this file to your app: + * https://customer.io/docs/sdk/react-native/push-notifications/push/#integrate-push-capabilities-in-your-app + */ + @objc public class MyAppPushNotificationsHandler : NSObject { public override init() {} - @objc(setupCustomerIOClickHandling:) - public func setupCustomerIOClickHandling(withNotificationDelegate notificationDelegate: UNUserNotificationCenterDelegate) { + @objc(setupCustomerIOClickHandling) + public func setupCustomerIOClickHandling() { // This line of code is required in order for the Customer.io SDK to handle push notification click events. // We are working on removing this requirement in a future release. // Remember to modify the siteId and apiKey with your own values. @@ -17,9 +23,7 @@ public class MyAppPushNotificationsHandler : NSObject { config.autoTrackDeviceAttributes = true config.logLevel = .debug } - - let center = UNUserNotificationCenter.current() - center.delegate = notificationDelegate + MessagingPushAPN.initialize(configOptions: nil) } @objc(application:deviceToken:) @@ -31,16 +35,4 @@ public class MyAppPushNotificationsHandler : NSObject { public func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { MessagingPush.shared.application(application, didFailToRegisterForRemoteNotificationsWithError: error) } - - @objc(userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:) - public func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { - let handled = MessagingPush.shared.userNotificationCenter(center, didReceive: response, - withCompletionHandler: completionHandler) - - // If the Customer.io SDK does not handle the push, it's up to you to handle it and call the - // completion handler. If the SDK did handle it, it called the completion handler for you. - if !handled { - completionHandler() - } - } } diff --git a/Apps/APN/ios/Podfile.lock b/Apps/APN/ios/Podfile.lock index ef801bda..a5becb33 100644 --- a/Apps/APN/ios/Podfile.lock +++ b/Apps/APN/ios/Podfile.lock @@ -1,39 +1,39 @@ PODS: - boost (1.76.0) - - customerio-reactnative (3.2.0): - - customerio-reactnative/nopush (= 3.2.0) - - CustomerIO/MessagingInApp (= 2.8.4) - - CustomerIO/Tracking (= 2.8.4) + - customerio-reactnative (3.4.0): + - customerio-reactnative/nopush (= 3.4.0) + - CustomerIO/MessagingInApp (= 2.11.0) + - CustomerIO/Tracking (= 2.11.0) - React-Core - - customerio-reactnative-richpush/apn (3.2.0): - - CustomerIO/MessagingPushAPN (= 2.8.4) - - customerio-reactnative/apn (3.2.0): - - CustomerIO/MessagingInApp (= 2.8.4) - - CustomerIO/MessagingPushAPN (= 2.8.4) - - CustomerIO/Tracking (= 2.8.4) + - customerio-reactnative-richpush/apn (3.4.0): + - CustomerIO/MessagingPushAPN (= 2.11.0) + - customerio-reactnative/apn (3.4.0): + - CustomerIO/MessagingInApp (= 2.11.0) + - CustomerIO/MessagingPushAPN (= 2.11.0) + - CustomerIO/Tracking (= 2.11.0) - React-Core - - customerio-reactnative/nopush (3.2.0): - - CustomerIO/MessagingInApp (= 2.8.4) - - CustomerIO/MessagingPush (= 2.8.4) - - CustomerIO/Tracking (= 2.8.4) + - customerio-reactnative/nopush (3.4.0): + - CustomerIO/MessagingInApp (= 2.11.0) + - CustomerIO/MessagingPush (= 2.11.0) + - CustomerIO/Tracking (= 2.11.0) - React-Core - - CustomerIO/MessagingInApp (2.8.4): - - CustomerIOMessagingInApp (= 2.8.4) - - CustomerIO/MessagingPush (2.8.4): - - CustomerIOMessagingPush (= 2.8.4) - - CustomerIO/MessagingPushAPN (2.8.4): - - CustomerIOMessagingPushAPN (= 2.8.4) - - CustomerIO/Tracking (2.8.4): - - CustomerIOTracking (= 2.8.4) - - CustomerIOCommon (2.8.4) - - CustomerIOMessagingInApp (2.8.4): - - CustomerIOTracking (= 2.8.4) - - CustomerIOMessagingPush (2.8.4): - - CustomerIOTracking (= 2.8.4) - - CustomerIOMessagingPushAPN (2.8.4): - - CustomerIOMessagingPush (= 2.8.4) - - CustomerIOTracking (2.8.4): - - CustomerIOCommon (= 2.8.4) + - CustomerIO/MessagingInApp (2.11.0): + - CustomerIOMessagingInApp (= 2.11.0) + - CustomerIO/MessagingPush (2.11.0): + - CustomerIOMessagingPush (= 2.11.0) + - CustomerIO/MessagingPushAPN (2.11.0): + - CustomerIOMessagingPushAPN (= 2.11.0) + - CustomerIO/Tracking (2.11.0): + - CustomerIOTracking (= 2.11.0) + - CustomerIOCommon (2.11.0) + - CustomerIOMessagingInApp (2.11.0): + - CustomerIOTracking (= 2.11.0) + - CustomerIOMessagingPush (2.11.0): + - CustomerIOTracking (= 2.11.0) + - CustomerIOMessagingPushAPN (2.11.0): + - CustomerIOMessagingPush (= 2.11.0) + - CustomerIOTracking (2.11.0): + - CustomerIOCommon (= 2.11.0) - DoubleConversion (1.1.6) - FBLazyVector (0.72.4) - FBReactNativeSpec (0.72.4): @@ -349,6 +349,8 @@ PODS: - React-jsinspector (0.72.4) - React-logger (0.72.4): - glog + - react-native-notifications (5.1.0): + - React-Core - react-native-safe-area-context (4.7.1): - React-Core - React-NativeModulesApple (0.72.4): @@ -532,6 +534,7 @@ DEPENDENCIES: - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - React-logger (from `../node_modules/react-native/ReactCommon/logger`) + - react-native-notifications (from `../node_modules/react-native-notifications`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) @@ -620,6 +623,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/jsinspector" React-logger: :path: "../node_modules/react-native/ReactCommon/logger" + react-native-notifications: + :path: "../node_modules/react-native-notifications" react-native-safe-area-context: :path: "../node_modules/react-native-safe-area-context" React-NativeModulesApple: @@ -677,14 +682,14 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost: 57d2868c099736d80fcd648bf211b4431e51a558 - CustomerIO: 4a04f63c9951bced3f2160397e811451cba0de36 - customerio-reactnative: 57a15506e537c89802847b819442ab4426de68eb - customerio-reactnative-richpush: 3866204a12a94ce8eaa6630ab39f069dea970b36 - CustomerIOCommon: 65752b4280cd24edf8091eba59cae04347999fe1 - CustomerIOMessagingInApp: ce4944ec4c9d1dd0d30ea7a0c6aee7137609d7e3 - CustomerIOMessagingPush: 6a21e2bd5bb4a6b483671e7703dc011a4deb8178 - CustomerIOMessagingPushAPN: 93e371ee9e5208497320bec6325e715db0a8b3ab - CustomerIOTracking: 5eab210defdf8950e0708713f7d95b35b779e056 + CustomerIO: 157786b8d83f792f73fea0455389445e80e8f582 + customerio-reactnative: 84e011604b93bf59f3d52e70e8444f0d0f8add12 + customerio-reactnative-richpush: f875b19d8f750810946e3705ef2a435690ae61ff + CustomerIOCommon: 2f1537b82af71a058b502885ef2604506af15bb4 + CustomerIOMessagingInApp: a78f32bc57d6baea2be4c7c7491bf733fb7e0596 + CustomerIOMessagingPush: c13903c4256d6d236d3b6bd29b77672b3908e788 + CustomerIOMessagingPushAPN: 13b08111e6901630017dc66871ead3d44d1b2f80 + CustomerIOTracking: 51dd017df4796203242032b6ffafbc8a9a740fb2 DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 FBLazyVector: 5d4a3b7f411219a45a6d952f77d2c0a6c9989da5 FBReactNativeSpec: 3fc2d478e1c4b08276f9dd9128f80ec6d5d85c1f @@ -707,6 +712,7 @@ SPEC CHECKSUMS: React-jsiexecutor: c7f826e40fa9cab5d37cab6130b1af237332b594 React-jsinspector: aaed4cf551c4a1c98092436518c2d267b13a673f React-logger: da1ebe05ae06eb6db4b162202faeafac4b435e77 + react-native-notifications: 4601a5a8db4ced6ae7cfc43b44d35fe437ac50c4 react-native-safe-area-context: 9697629f7b2cda43cf52169bb7e0767d330648c2 React-NativeModulesApple: edb5ace14f73f4969df6e7b1f3e41bef0012740f React-perflogger: 496a1a3dc6737f964107cb3ddae7f9e265ddda58 @@ -738,4 +744,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: dd15e298a538ff617275f2a8acfe9f2e3d78fbbf -COCOAPODS: 1.12.1 +COCOAPODS: 1.14.3 diff --git a/Apps/APN/package.json b/Apps/APN/package.json index 90e809de..c7956810 100644 --- a/Apps/APN/package.json +++ b/Apps/APN/package.json @@ -29,6 +29,7 @@ "react-native": "0.72.4", "react-native-device-info": "^10.7.0", "react-native-gesture-handler": "^2.12.1", + "react-native-notifications": "^5.1.0", "react-native-reanimated": "3.2.0", "react-native-safe-area-context": "^4.2.5", "react-native-screens": "~3.24.0", diff --git a/Apps/APN/src/screens/Dashboard.js b/Apps/APN/src/screens/Dashboard.js index c73b521e..db5534ac 100644 --- a/Apps/APN/src/screens/Dashboard.js +++ b/Apps/APN/src/screens/Dashboard.js @@ -23,6 +23,8 @@ import { useUserStateContext } from '../state/userState'; import { generateRandomNumber } from '../utils/helpers'; import { navigateToScreen } from '../utils/navigation'; import Prompts from '../utils/prompts'; +import { Notifications } from 'react-native-notifications'; +import { CustomerIO } from 'customerio-reactnative'; const pushPermissionAlertTitle = 'Push Permission'; @@ -138,6 +140,15 @@ const Dashboard = ({ navigation }) => { handlePushPermissionCheck(); break; + case ActionItem.SHOW_LOCAL_PUSH: + // How we are able to test behavior of pushes sent by other SDKs, not CIO. + // Have 3rd party SDK create a push. We expect the SDK is able to handle this push that it owns. + Notifications.postLocalNotification({ + body: 'Try clicking on me. The SDK that sent this should also be able to handle it.', + title: 'Local push not sent by Customer.io', + }); + break; + case ActionItem.SIGN_OUT: onUserStateChanged(null); break; @@ -150,6 +161,32 @@ const Dashboard = ({ navigation }) => { } }; + // Setup 3rd party SDK, react-native-notifications + // We install this SDK into sample app to make sure the CIO SDK behaves as expected when there is another SDK installed that handles push notifications. + // + // Important to test that 3rd party SDK is able to decide if a push is shown or not while app is in foreground for non-CIO sent pushes. + Notifications.events().registerNotificationReceivedForeground( + (notification: Notification, completion) => { + console.log( + `Non-Customer.io notification received in foreground: ${notification.title} : ${notification.body}` + ); + + completion({ alert: true, sound: true, badge: true }); + } + ); + // Important to test that 3rd party SDK is able to receive a callback when a push notification is clicked for non-CIO sent pushes. + Notifications.events().registerNotificationOpened( + (notification: Notification, completion) => { + console.log( + `Non-Customer.io notification opened: ${notification.payload}` + ); + + CustomerIO.track('push clicked', { push: notification.payload }); + + completion(); + } + ); + return ( @@ -218,6 +255,11 @@ const ActionItem = { contentDesc: 'Show Push Prompt Button', targetScreen: null, }, + SHOW_LOCAL_PUSH: { + text: 'Show Local Push', + contentDesc: 'Show Local Push Button', + targetScreen: null, + }, SIGN_OUT: { text: 'Log Out', contentDesc: 'Log Out Button',