customerio / customerio-expo-plugin

MIT License
11 stars 9 forks source link

CIOAppPushNotificationsHandler unknown in latest version v1.0.0-beta.14 #125

Closed Kerumen closed 9 months ago

Kerumen commented 9 months ago

I upgraded to v1.0.0-beta.14 and I'm facing errors when building my app:

  20 | 
> 21 | CIOAppPushNotificationsHandler* pnHandlerObj = [[CIOAppPushNotificationsHandler alloc] init];
     | ^ unknown type name 'CIOAppPushNotificationsHandler'
  22 | 
  23 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  24 | {
  20 | 
> 21 | CIOAppPushNotificationsHandler* pnHandlerObj = [[CIOAppPushNotificationsHandler alloc] init];
     |                                                  ^ use of undeclared identifier 'CIOAppPushNotificationsHandler'
  22 | 
  23 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  24 | {
Here is the content of my AppDelegate.mm ```objective-c #if __has_include() #import #endif // Add swift bridge imports #import #import #import "AppDelegate.h" #import #import @implementation AppDelegate CIOAppPushNotificationsHandler* pnHandlerObj = [[CIOAppPushNotificationsHandler alloc] init]; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.moduleName = @"main"; // You can add your custom initial props in the dictionary below. // They will be passed down to the ViewController used by React Native. self.initialProps = @{}; [pnHandlerObj initializeCioSdk]; // Code to make the CIO SDK compatible with expo-notifications package. // // The CIO SDK and expo-notifications both need to handle when a push gets clicked. However, iOS only allows one click handler to be set per app. // To get around this limitation, we set the CIO SDK as the click handler. The CIO SDK sets itself up so that when another SDK or host iOS app // sets itself as the click handler, the CIO SDK will still be able to handle when the push gets clicked, even though it's not the designated // click handler in iOS at runtime. // // This should work for most SDKs. However, expo-notifications is unique in it's implementation. It will not setup push click handling it if detects // that another SDK or host iOS app has already set itself as the click handler: // https://github.com/expo/expo/blob/1b29637bec0b9888e8bc8c310476293a3e2d9786/packages/expo-notifications/ios/EXNotifications/Notifications/EXNotificationCenterDelegate.m#L31-L37 // ...to get around this, we must manually set it as the click handler after the CIO SDK. That's what this code block does. // // Note: Initialize the native iOS SDK and setup SDK push click handling before running this code. # if __has_include() // Creating a new instance, as the comments in expo-notifications suggests, does not work. With this code, if you send a CIO push to device and click on it, // no push metrics reporting will occur. // EXNotificationCenterDelegate *notificationCenterDelegate = [[EXNotificationCenterDelegate alloc] init]; // ...instead, get the singleton reference from Expo. id notificationCenterDelegate = (id) [EXModuleRegistryProvider getSingletonModuleForClass:[EXNotificationCenterDelegate class]]; UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = notificationCenterDelegate; # endif return [super application:application didFinishLaunchingWithOptions:launchOptions]; } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@".expo/.virtual-metro-entry"]; #else return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif } // Linking API - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options { return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options]; } // Universal Links - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray> * _Nullable))restorationHandler { BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler]; return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result; } // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; return [pnHandlerObj application:application deviceToken:deviceToken]; } // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { [super application:application didFailToRegisterForRemoteNotificationsWithError:error]; [pnHandlerObj application:application error:error]; } // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { return [super application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; } @end ```

Previous version (v1.0.0-beta.13 / v3.3.2) was working fine. It seems related to the latest change in the iOS SDK because CIOAppPushNotificationsHandler is not found now and it was before, without any header include change. I don't know enough Swift to debug though.


app.config.ts:

[
  'customerio-expo-plugin',
  {
    android: {
      googleServicesFile: './google-services.json',
    },
    ios: {
      pushNotification: {
        useRichPush: false,
      },
    },
  },
],

Versions:

"customerio-expo-plugin": "^1.0.0-beta.14",
"customerio-reactnative": "^3.4.0",
levibostian commented 9 months ago

Sorry to hear you're experiencing this issue, @Kerumen. Let me see if I can help.

Thanks for providing those details about your environment.

From our internal testing, we have not been able to reproduce this error. Could you perform a expo prebuild --clean and try again? See if the error persists?

Kerumen commented 9 months ago

Thanks for your reply @levibostian!

Even with expo prebuild --clean I still have the issue:

Screenshot 2024-02-13 at 16 38 02

Kerumen commented 9 months ago

Ok, I've found something. When I run expo prebuild I have this warning now:

TypeError: Cannot read properties of undefined (reading 'siteId')

If I set the env field in the app.config.ts, everything works fine.

ios: {
  pushNotification: {
    useRichPush: false,
    env: {
      siteId: "<siteId>",
      apiKey: "<apiKey>",
      region: "<region>"
    }
  }
}

However, the docs says: This field should be filled when enabling rich push. We are not using rich push for now, it should work without the env field right?

levibostian commented 9 months ago

Ah, great observation. Especially big thank you for pointing out this section of the docs.

That section of the docs is not correct. I'll make that update today. The ios.pushNotifications.env object may have been optional in the past, but it is required in the latest versions. No matter if push notifications are enabled or not in your app, if this information is not provided, you will not be able to send any data to Customer.io such as tracking an event.

By providing this env object, are you able to successfully compile your app now?

Kerumen commented 9 months ago

Yes everything works fine now! Thanks for the fast reply 🙂