From ed9a92c3bb90fc168870fb1b7ea17d2e87253c92 Mon Sep 17 00:00:00 2001 From: Ajay Subramanya <118314354+ajaysubra@users.noreply.github.com> Date: Thu, 15 Feb 2024 12:11:52 -0600 Subject: [PATCH] Implemented deep links to call react native in example iOS app (#104) * 0.1.1 * implemented deep linking calls to react native * removed unused method * removed package lock * added deep linking hanlder --- .../AppDelegate.mm | 27 ++++++++++++++----- .../PushNotificationsHelper.swift | 23 +++++++--------- example/src/App.tsx | 12 +++++++++ 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/example/ios/KlaviyoReactNativeSdkExample/AppDelegate.mm b/example/ios/KlaviyoReactNativeSdkExample/AppDelegate.mm index 60c5e90..7b66561 100644 --- a/example/ios/KlaviyoReactNativeSdkExample/AppDelegate.mm +++ b/example/ios/KlaviyoReactNativeSdkExample/AppDelegate.mm @@ -1,6 +1,8 @@ #import "AppDelegate.h" #import +#import + @implementation AppDelegate @@ -31,9 +33,8 @@ - (void)application:(UIApplication *)application didRegisterForRemoteNotificatio [PushNotificationsHelper setPushTokenWithToken:deviceToken]; if (isDebug) { - NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]]; - token = [token stringByReplacingOccurrencesOfString:@" " withString:@""]; - NSLog(@"Device Token: %@", token); + NSString *token = [self stringFromDeviceToken:deviceToken]; + NSLog(@"Device Token: %@", token); } } @@ -50,7 +51,11 @@ - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotif - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler { // Installation Step 10: call `handleReceivingPushWithResponse` method and pass in the below arguments. Note that handleReceivingPushWithResponse calls our SDK and is // something that has to be implemented in your app as well. - [PushNotificationsHelper handleReceivingPushWithResponse:response completionHandler:completionHandler]; + // furthur, if you want to intercept urls instead of them being routed to the system and system calling `application:openURL:options:` you can implement the `deepLinkHandler` below + [PushNotificationsHelper handleReceivingPushWithResponse:response completionHandler:completionHandler deepLinkHandler:^(NSURL * _Nonnull url) { + NSLog(@"URL is %@", url); + [RCTLinkingManager application:UIApplication.sharedApplication openURL: url options: @{}]; + }]; if (isDebug) { UIAlertController *alert = [UIAlertController @@ -90,12 +95,11 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center // Installation Step 13: Implement this method to receive deep link. There are some addition setup steps needed as mentioned in the readme here - // https://github.com/klaviyo/klaviyo-swift-sdk?tab=readme-ov-file#deep-linking -// additionally routing to the right screen in the app based on the url is also something that should be handled +// Calling `RCTLinkingManager` is required for your react native listeners to be called - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { - return [PushNotificationsHelper handleDeepLinksWithUrl:url]; + return [RCTLinkingManager application:app openURL:url options:options]; } - - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { return [self getBundleURL]; @@ -110,4 +114,13 @@ - (NSURL *)getBundleURL #endif } +- (NSString *)stringFromDeviceToken:(NSData *)deviceToken { + const unsigned char *tokenBytes = (const unsigned char *)[deviceToken bytes]; + NSMutableString *token = [NSMutableString stringWithCapacity:([deviceToken length] * 2)]; + for (NSUInteger i = 0; i < [deviceToken length]; i++) { + [token appendFormat:@"%02x", tokenBytes[i]]; + } + return token; +} + @end diff --git a/example/ios/KlaviyoReactNativeSdkExample/PushNotificationsHelper.swift b/example/ios/KlaviyoReactNativeSdkExample/PushNotificationsHelper.swift index 81b5c04..b808f89 100644 --- a/example/ios/KlaviyoReactNativeSdkExample/PushNotificationsHelper.swift +++ b/example/ios/KlaviyoReactNativeSdkExample/PushNotificationsHelper.swift @@ -33,21 +33,18 @@ class PushNotificationsHelper: NSObject { } @objc - static func handleReceivingPush(response: UNNotificationResponse, completionHandler: @escaping () -> Void ) { - let handled = KlaviyoSDK().handle(notificationResponse: response, withCompletionHandler: completionHandler) + static func handleReceivingPush( + response: UNNotificationResponse, + completionHandler: @escaping () -> Void, + deepLinkHandler: ((URL) -> Void)? = nil + ) { + let handled = KlaviyoSDK().handle( + notificationResponse: response, + withCompletionHandler: completionHandler, + deepLinkHandler: deepLinkHandler + ) if !handled { completionHandler() } } - - @objc - static func handleDeepLinks(url: URL) -> Bool { - guard let components = NSURLComponents(url: url, resolvingAgainstBaseURL: true) - else { - print("Invalid deep linking URL") - return false - } - print("components: \(components.debugDescription)") - return true - } } diff --git a/example/src/App.tsx b/example/src/App.tsx index 7c586ff..e5a9d49 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -1,10 +1,22 @@ import * as React from 'react'; +import { useEffect } from 'react'; + import { Button, View } from 'react-native'; import { type AppViewInterface, appViews } from './AppViewInterface'; import { styles } from './Styles'; +import { Linking } from 'react-native'; export default function App() { + useEffect(() => { + Linking.addEventListener('url', ({ url }) => { + console.log('Event Listener: url', url); + }); + Linking.getInitialURL().then((url) => { + console.log('Initial Url: url', url); + }); + }, []); + return ( <>