ios icon indicating copy to clipboard operation
ios copied to clipboard

No such module 'RNCPushNotificationIOS'

Open brytoz opened this issue 9 months ago • 16 comments

Using react version 0.78.1, After installing and setting up the Appdelegate.swift files (as there is not Appdelegate.h or .mm for the new react version) it keeps telling me No such module 'RNCPushNotificationIOS' when trying to build. Please note i have done some manual inclusion as seen from other links, but the error persist. i have done some modifications in my podfile, added libRNCPushNotificationIOS.a in my xcode but it persist, how do i fix this

brytoz avatar Mar 29 '25 00:03 brytoz

@brytoz I am facing same issue. Did you find the solution?

harooniqbal1993 avatar Apr 10 '25 08:04 harooniqbal1993

@brytoz I have the same problem do u resolve it ?

ducnham86 avatar Apr 16 '25 07:04 ducnham86

Insert the include in your projects bridge header file

Image

ashishAmz avatar Apr 16 '25 13:04 ashishAmz

Here is the fix

🛠️ Steps to Create and Link a Bridging Header in Xcode for React Native iOS Integration


✅ 1. Create a Bridging Header File

  1. In Xcode, right-click the ios/YourProjectName folder.
  2. Choose New File > Header File.
  3. Name it YourProjectName-Header.h
  4. Click Create.

✅ 2. Add Required Imports

Inside YourProjectName-Header.h, add:

#ifndef YourProjectName_Header_h
#define YourProjectName_Header_h

#import <React/RCTBundleURLProvider.h>
#import <React/RCTBridgeDelegate.h>
#import <UserNotifications/UNUserNotificationCenter.h>
#import <RNCPushNotificationIOS/RNCPushNotificationIOS.h>

#endif /* YourProjectName_Header_h */

✅ 3. Link Bridging Header in Build Settings

In Xcode, select your main app target

Go to Build Settings.

In the search bar at the top, type Objective-C Bridging Header.

You should see the Objective-C Bridging Header option under the Swift Compiler - General section.

Set the path relative to the project root, for example:

css ios/YourProjectName/YourProjectName-Header.h Example: ios/YourProject/YourProject-Header.h

Image

This tells Xcode where to find the YourProjectName-Header.h file (which contains the necessary imports). Ensure that the path is relative to the root directory of your project.

✅ 4. Clean & Build the Project

Clean the project: Cmd + Shift + K

Rebuild: Cmd + B or run the app


###✅ 5. Verify Successful Integration If everything is set up correctly, Xcode should no longer throw the expected '>' or failed to emit precompiled header errors.

💡 Tip If you're still facing issues, try deleting the DerivedData folder: rm -rf ~/Library/Developer/Xcode/DerivedData Then restart Xcode and build again.

farhan-pathan-us avatar Apr 24 '25 09:04 farhan-pathan-us

I tried everything you mentioned @farhan-pathan-us, but it didn't work. Any other thing I could try? Just FYI, this is my bridging header:

#ifndef mycompany_Bridging_Header_h
#define mycompany_Bridging_Header_h

#import "React/RCTBridgeModule.h"
#import "RNCConfig.h"
#import "RCTThreatMetrixModule.h"
#import "MobilePush.h"
#import <UserNotifications/UNUserNotificationCenter.h>
#import <RNCPushNotificationIOS/RNCPushNotificationIOS.h>

#endif /* mycompany_Bridging_Header_h */

I did added the config on the Objective-C Bridging Header in my build settings, and none of that worked for me. I'm running out of options. This is my stack:

"@react-native-community/push-notification-ios": "^1.11.0",
"react-native": "^0.79.2",

This is my AppDelegate.swift:

import UIKit
import UserNotifications
import React
import FBSDKCoreKit
import FirebaseCore
import RNCPushNotificationIOS
import CodePush
import Adyen
import MarketingCloudSDK
import SFMCSDK

@main
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, SFMCSdkURLHandlingDelegate {
    var window: UIWindow?
    var reactNativeDelegate: ReactNativeDelegate?
    var reactNativeFactory: RCTReactNativeFactory?
    var authorizationFlowManagerDelegate: RNAppAuthAuthorizationFlowManagerDelegate?

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
    ) -> Bool {
        // Firebase Debug
        if let isFirebaseDebugEnabled = RNCConfig.env(for: "FIREBASE_DEBUG_ENABLED") as? String, isFirebaseDebugEnabled == "1" {
            print("Firebase debug enabled.")
            ProcessInfo.processInfo.setValue(ProcessInfo.processInfo.arguments + ["-FIRAnalyticsDebugEnabled", "-FIRDebugEnabled"], forKey: "arguments")
        }

        // Firebase Configuration
        FirebaseApp.configure()

        // SFMC (Salesforce Marketing Cloud) Configuration
        let MCAppID = RNCConfig.env(for: "SALESFORCES_APPLICATION_ID") as? String ?? ""
        let MCAccessToken = RNCConfig.env(for: "SALESFORCES_ACCESS_TOKEN") as? String ?? ""
        let MCAppServerUrl = RNCConfig.env(for: "SALESFORCES_APP_SERVER_URL") as? String ?? ""
        let MCMid = RNCConfig.env(for: "SALESFORCES_APP_MID") as? String ?? ""

        let pushConfigBuilder = PushConfigBuilder(appId: MCAppID)
        pushConfigBuilder.setAccessToken(MCAccessToken)
        pushConfigBuilder.setMarketingCloudServerUrl(URL(string: MCAppServerUrl))
        pushConfigBuilder.setMid(MCMid)
        pushConfigBuilder.setAnalyticsEnabled(true)

        SFMCSdk.setKeychainAccessErrorsAreFatalWithErrorsAreFatal(false)
        SFMCSdk.initializeSdk(
            SFMCSdkConfigBuilder()
                .setPush(with: pushConfigBuilder.build(), onCompletion: { result in
                    if result == .success {
                        DispatchQueue.main.async {
                            UNUserNotificationCenter.current().delegate = self
                            SFMCSdk.mp().setURLHandlingDelegate(self)
                            UIApplication.shared.registerForRemoteNotifications()
                            UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
                                if error == nil, granted {
                                    print("User granted permission")
                                }
                            }
                        }
                    } else {
                        print("SFMC sdk configuration failed.")
                    }
                })
                .build()
        )

        // Facebook SDK
        ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)

        // React Native Setup
        let delegate = ReactNativeDelegate()
        let factory = RCTReactNativeFactory(delegate: delegate)
        delegate.dependencyProvider = RCTAppDependencyProvider()
        reactNativeDelegate = delegate
        reactNativeFactory = factory

        window = UIWindow(frame: UIScreen.main.bounds)
        factory.startReactNative(
            withModuleName: RNCConfig.env(for: "MAIN_COMPONENT_NAME") as? String ?? "groupedynamite",
            in: window,
            launchOptions: launchOptions
        )

        // BootSplash
        if let rootView = window?.rootViewController?.view {
            RNBootSplash.initWithStoryboard(RNCConfig.env(for: "SPLASH_SCREEN") as? String, rootView: rootView)
        }

        // iOS 14 DatePicker style
        if #available(iOS 14, *) {
            UIDatePicker.appearance().preferredDatePickerStyle = .wheels
        }

        return true
    }

    // MARK: - Push Notification Delegates

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        SFMCSdk.mp().setDeviceToken(deviceToken)
        RNCPushNotificationIOS.didRegisterForRemoteNotifications(withDeviceToken: deviceToken)
        NotificationCenter.default.post(name: NSNotification.Name("deviceDidRegister"), object: self)
    }

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        RNCPushNotificationIOS.didFailToRegisterForRemoteNotificationsWithError(error)
        print("didFailToRegisterForRemoteNotificationsWithError = \(error)")
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        SFMCSdk.mp().setNotificationUserInfo(userInfo)
        RNCPushNotificationIOS.didReceiveRemoteNotification(userInfo, fetchCompletionHandler: completionHandler)
        NotificationCenter.default.post(name: NSNotification.Name("enteredOnPushNotification"), object: nil, userInfo: [
            "notificationId": userInfo["_r"] ?? ""
        ])
        completionHandler(.newData)
    }

    func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
        RNCPushNotificationIOS.didReceive(notification)
    }

    // MARK: - UNUserNotificationCenterDelegate

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        SFMCSdk.mp().setNotificationRequest(response.notification.request)
        RNCPushNotificationIOS.didReceive(response)
        completionHandler()
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.sound, .alert, .badge])
    }

    // MARK: - Deep Linking

    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
        let handledFB = ApplicationDelegate.shared.application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
        let handledRCT = RCTLinkingManager.application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
        return ADYRedirectComponent.applicationDidOpen(url) || handledFB || handledRCT
    }

    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
        return RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
    }

    func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        if ApplicationDelegate.shared.application(application, open: url, options: options) {
            return true
        }
        if let delegate = authorizationFlowManagerDelegate, delegate.resumeExternalUserAgentFlow(with: url) {
            return true
        }
        if RCTLinkingManager.application(application, open: url, options: options) {
            return true
        }
        return false
    }

    // MARK: - SFMCSdkURLHandlingDelegate

    func sfmc_handle(_ url: URL, type: String) {
        if UIApplication.shared.canOpenURL(url) {
            UIApplication.shared.open(url, options: [:]) { success in
                if success {
                    print("url \(url) opened successfully")
                } else {
                    print("url \(url) could not be opened")
                }
            }
        }
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        AppEvents.shared.activateApp()
    }
}

// MARK: - React Native Delegate

class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
    override func sourceURL(for bridge: RCTBridge!) -> URL! {
        return self.bundleURL()
    }

    override func bundleURL() -> URL! {
      #if DEBUG
          return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
      #else
          return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
      #endif
    }
}

The error I'm getting:

AppDelegate.swift:6:8: error: no such module 'RNCPushNotificationIOS'
import RNCPushNotificationIOS
       ^

Any help will be much appreciated! Let me know if you need anything else

MarlonAEC avatar May 14 '25 23:05 MarlonAEC

@MarlonAEC As we have added import in bridging-header.h file no need to import it again in Appdelegate.swift. #import <RNCPushNotificationIOS/RNCPushNotificationIOS.h> //Added in Bridging header

Remove this import from Appdelegate.swift import RNCPushNotificationIOS // Remove the import from Appdelegate.swift it will work without this line

farhan-pathan-us avatar May 15 '25 06:05 farhan-pathan-us

hi is this issue still active? I am facing the same issue when upgrading from react-native version 0.71.19 to 0.74

System:
  OS: macOS 15.3.2
  CPU: (8) arm64 Apple M1 Pro
  Memory: 137.14 MB / 16.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 18.18.0
    path: ~/.nvm/versions/node/v18.18.0/bin/node
  Yarn:
    version: 1.22.21
    path: /opt/homebrew/bin/yarn
  npm:
    version: 9.8.1
    path: ~/.nvm/versions/node/v18.18.0/bin/npm
  Watchman:
    version: 2025.04.14.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.16.2
    path: /usr/local/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.2
      - iOS 18.2
      - macOS 15.2
      - tvOS 18.2
      - visionOS 2.2
      - watchOS 11.2
  Android SDK: Not Found
IDEs:
  Android Studio: 2023.2 AI-232.10300.40.2321.11668458
  Xcode:
    version: 16.2/16C5032a
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.15
    path: /Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home/bin/javac
  Ruby:
    version: 2.6.10
    path: /usr/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react: Not Found
  react-native: Not Found
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: false
iOS:
  hermesEnabled: true
  newArchEnabled: false

aryan1306 avatar May 19 '25 07:05 aryan1306

I tried everything you mentioned @farhan-pathan-us, but it didn't work. Any other thing I could try? Just FYI, this is my bridging header:

#ifndef mycompany_Bridging_Header_h
#define mycompany_Bridging_Header_h

#import "React/RCTBridgeModule.h"
#import "RNCConfig.h"
#import "RCTThreatMetrixModule.h"
#import "MobilePush.h"
#import <UserNotifications/UNUserNotificationCenter.h>
#import <RNCPushNotificationIOS/RNCPushNotificationIOS.h>

#endif /* mycompany_Bridging_Header_h */

I did added the config on the Objective-C Bridging Header in my build settings, and none of that worked for me. I'm running out of options. This is my stack:

"@react-native-community/push-notification-ios": "^1.11.0",
"react-native": "^0.79.2",

This is my AppDelegate.swift:

import UIKit
import UserNotifications
import React
import FBSDKCoreKit
import FirebaseCore
import RNCPushNotificationIOS
import CodePush
import Adyen
import MarketingCloudSDK
import SFMCSDK

@main
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, SFMCSdkURLHandlingDelegate {
    var window: UIWindow?
    var reactNativeDelegate: ReactNativeDelegate?
    var reactNativeFactory: RCTReactNativeFactory?
    var authorizationFlowManagerDelegate: RNAppAuthAuthorizationFlowManagerDelegate?

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
    ) -> Bool {
        // Firebase Debug
        if let isFirebaseDebugEnabled = RNCConfig.env(for: "FIREBASE_DEBUG_ENABLED") as? String, isFirebaseDebugEnabled == "1" {
            print("Firebase debug enabled.")
            ProcessInfo.processInfo.setValue(ProcessInfo.processInfo.arguments + ["-FIRAnalyticsDebugEnabled", "-FIRDebugEnabled"], forKey: "arguments")
        }

        // Firebase Configuration
        FirebaseApp.configure()

        // SFMC (Salesforce Marketing Cloud) Configuration
        let MCAppID = RNCConfig.env(for: "SALESFORCES_APPLICATION_ID") as? String ?? ""
        let MCAccessToken = RNCConfig.env(for: "SALESFORCES_ACCESS_TOKEN") as? String ?? ""
        let MCAppServerUrl = RNCConfig.env(for: "SALESFORCES_APP_SERVER_URL") as? String ?? ""
        let MCMid = RNCConfig.env(for: "SALESFORCES_APP_MID") as? String ?? ""

        let pushConfigBuilder = PushConfigBuilder(appId: MCAppID)
        pushConfigBuilder.setAccessToken(MCAccessToken)
        pushConfigBuilder.setMarketingCloudServerUrl(URL(string: MCAppServerUrl))
        pushConfigBuilder.setMid(MCMid)
        pushConfigBuilder.setAnalyticsEnabled(true)

        SFMCSdk.setKeychainAccessErrorsAreFatalWithErrorsAreFatal(false)
        SFMCSdk.initializeSdk(
            SFMCSdkConfigBuilder()
                .setPush(with: pushConfigBuilder.build(), onCompletion: { result in
                    if result == .success {
                        DispatchQueue.main.async {
                            UNUserNotificationCenter.current().delegate = self
                            SFMCSdk.mp().setURLHandlingDelegate(self)
                            UIApplication.shared.registerForRemoteNotifications()
                            UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
                                if error == nil, granted {
                                    print("User granted permission")
                                }
                            }
                        }
                    } else {
                        print("SFMC sdk configuration failed.")
                    }
                })
                .build()
        )

        // Facebook SDK
        ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)

        // React Native Setup
        let delegate = ReactNativeDelegate()
        let factory = RCTReactNativeFactory(delegate: delegate)
        delegate.dependencyProvider = RCTAppDependencyProvider()
        reactNativeDelegate = delegate
        reactNativeFactory = factory

        window = UIWindow(frame: UIScreen.main.bounds)
        factory.startReactNative(
            withModuleName: RNCConfig.env(for: "MAIN_COMPONENT_NAME") as? String ?? "groupedynamite",
            in: window,
            launchOptions: launchOptions
        )

        // BootSplash
        if let rootView = window?.rootViewController?.view {
            RNBootSplash.initWithStoryboard(RNCConfig.env(for: "SPLASH_SCREEN") as? String, rootView: rootView)
        }

        // iOS 14 DatePicker style
        if #available(iOS 14, *) {
            UIDatePicker.appearance().preferredDatePickerStyle = .wheels
        }

        return true
    }

    // MARK: - Push Notification Delegates

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        SFMCSdk.mp().setDeviceToken(deviceToken)
        RNCPushNotificationIOS.didRegisterForRemoteNotifications(withDeviceToken: deviceToken)
        NotificationCenter.default.post(name: NSNotification.Name("deviceDidRegister"), object: self)
    }

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        RNCPushNotificationIOS.didFailToRegisterForRemoteNotificationsWithError(error)
        print("didFailToRegisterForRemoteNotificationsWithError = \(error)")
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        SFMCSdk.mp().setNotificationUserInfo(userInfo)
        RNCPushNotificationIOS.didReceiveRemoteNotification(userInfo, fetchCompletionHandler: completionHandler)
        NotificationCenter.default.post(name: NSNotification.Name("enteredOnPushNotification"), object: nil, userInfo: [
            "notificationId": userInfo["_r"] ?? ""
        ])
        completionHandler(.newData)
    }

    func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
        RNCPushNotificationIOS.didReceive(notification)
    }

    // MARK: - UNUserNotificationCenterDelegate

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        SFMCSdk.mp().setNotificationRequest(response.notification.request)
        RNCPushNotificationIOS.didReceive(response)
        completionHandler()
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.sound, .alert, .badge])
    }

    // MARK: - Deep Linking

    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
        let handledFB = ApplicationDelegate.shared.application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
        let handledRCT = RCTLinkingManager.application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
        return ADYRedirectComponent.applicationDidOpen(url) || handledFB || handledRCT
    }

    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
        return RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
    }

    func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        if ApplicationDelegate.shared.application(application, open: url, options: options) {
            return true
        }
        if let delegate = authorizationFlowManagerDelegate, delegate.resumeExternalUserAgentFlow(with: url) {
            return true
        }
        if RCTLinkingManager.application(application, open: url, options: options) {
            return true
        }
        return false
    }

    // MARK: - SFMCSdkURLHandlingDelegate

    func sfmc_handle(_ url: URL, type: String) {
        if UIApplication.shared.canOpenURL(url) {
            UIApplication.shared.open(url, options: [:]) { success in
                if success {
                    print("url \(url) opened successfully")
                } else {
                    print("url \(url) could not be opened")
                }
            }
        }
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        AppEvents.shared.activateApp()
    }
}

// MARK: - React Native Delegate

class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
    override func sourceURL(for bridge: RCTBridge!) -> URL! {
        return self.bundleURL()
    }

    override func bundleURL() -> URL! {
      #if DEBUG
          return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
      #else
          return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
      #endif
    }
}

The error I'm getting:

AppDelegate.swift:6:8: error: no such module 'RNCPushNotificationIOS'
import RNCPushNotificationIOS
       ^

Any help will be much appreciated! Let me know if you need anything else

Were you able to resolve this? I'm also using Marketing Cloud for push notifications and need to start updating React Native to the latest version. The problem is that Salesforce isn't updating anything.

manuelabarca avatar Jun 18 '25 09:06 manuelabarca

Hey guys, sorry for the late reply, I was able to fix my problem at the end. I rolled back the changes in my AppDelegate.swift. So according to this docs, from react native 0.77+, they changed AppDeleget.mm to AppDelegate.swift, but if you read through those doc,s you will see making this change is NOT required, so you could keep the AppDelegate.mm and all your implementations because there are some libraries that still don't support this change (Marketing Cloud SDK is one of them). So considering that, my AppDelegate.mm configuration for Marketing Cloud looks like this:

#import "AppDelegate.h"
#import "MobilePush.h"
#import <RNCPushNotificationIOS.h>
#import <ReactAppDependencyProvider/RCTAppDependencyProvider.h> //This is required even if you keep AppDelegate.mm

/**
* ....Rest of your code here
**/
- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   self.dependencyProvider = [RCTAppDependencyProvider new];  //********* This line is required in the new implementation

// Rest of your configs and code here

// configure the Marketing Cloud SDK
  NSString *MCAppID = [RNCConfig envFor:@"SALESFORCES_APPLICATION_ID"];
  NSString *MCAccessToken =
      [RNCConfig envFor:@"SALESFORCES_ACCESS_TOKEN"];
  NSString *MCAppServerUrl =
      [RNCConfig envFor:@"SALESFORCES_APP_SERVER_URL"];
  NSString *MCMid =
      [RNCConfig envFor:@"SALESFORCES_APP_MID"];

  PushConfigBuilder *pushConfigBuilder = [[PushConfigBuilder alloc] initWithAppId:MCAppID];
  [pushConfigBuilder setAccessToken:MCAccessToken];
  [pushConfigBuilder setMarketingCloudServerUrl:[NSURL URLWithString:MCAppServerUrl]];
  [pushConfigBuilder setMid:MCMid];
  [pushConfigBuilder setAnalyticsEnabled:YES];
  
  [SFMCSdk setKeychainAccessErrorsAreFatalWithErrorsAreFatal:NO];
    
  [SFMCSdk initializeSdk:[[[SFMCSdkConfigBuilder new] setPushWithConfig:[pushConfigBuilder build] onCompletion:^(SFMCSdkOperationResult result) {
    if (result == SFMCSdkOperationResultSuccess) {
      dispatch_async(dispatch_get_main_queue(), ^{
          // set the UNUserNotificationCenter delegate - the delegate must be set here in
          // didFinishLaunchingWithOptions
          [UNUserNotificationCenter currentNotificationCenter].delegate = self;
          [[SFMCSdk mp] setURLHandlingDelegate:self];
          [[UIApplication sharedApplication] registerForRemoteNotifications];
          
          [[UNUserNotificationCenter currentNotificationCenter]
          requestAuthorizationWithOptions:UNAuthorizationOptionAlert |
          UNAuthorizationOptionSound |
          UNAuthorizationOptionBadge
          completionHandler:^(BOOL granted, NSError *_Nullable error) {
            if (error == nil) {
              if (granted == YES) {
                    NSLog(@"User granted permission");
              }
            }
          }];
        });
    } else {
      //  MarketingCloudSDK sfmc_configure failed
      NSLog(@"SFMC sdk configuration failed.");
    }
  }] build]];


//This function continues here but is not relevant.

Hope that helps, ping me if you need any help, although sometimes it takes me a bit longer to reply because I'm really busy nowadays. Sorry about that!

MarlonAEC avatar Jun 19 '25 00:06 MarlonAEC

Hey guys, sorry for the late reply, I was able to fix my problem at the end. I rolled back the changes in my AppDelegate.swift. So according to this docs, from react native 0.77+, they changed AppDeleget.mm to AppDelegate.swift, but if you read through those doc,s you will see making this change is NOT required, so you could keep the AppDelegate.mm and all your implementations because there are some libraries that still don't support this change (Marketing Cloud SDK is one of them). So considering that, my AppDelegate.mm configuration for Marketing Cloud looks like this:

#import "AppDelegate.h"
#import "MobilePush.h"
#import <RNCPushNotificationIOS.h>
#import <ReactAppDependencyProvider/RCTAppDependencyProvider.h> //This is required even if you keep AppDelegate.mm

/**
* ....Rest of your code here
**/
- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   self.dependencyProvider = [RCTAppDependencyProvider new];  //********* This line is required in the new implementation

// Rest of your configs and code here

// configure the Marketing Cloud SDK
  NSString *MCAppID = [RNCConfig envFor:@"SALESFORCES_APPLICATION_ID"];
  NSString *MCAccessToken =
      [RNCConfig envFor:@"SALESFORCES_ACCESS_TOKEN"];
  NSString *MCAppServerUrl =
      [RNCConfig envFor:@"SALESFORCES_APP_SERVER_URL"];
  NSString *MCMid =
      [RNCConfig envFor:@"SALESFORCES_APP_MID"];

  PushConfigBuilder *pushConfigBuilder = [[PushConfigBuilder alloc] initWithAppId:MCAppID];
  [pushConfigBuilder setAccessToken:MCAccessToken];
  [pushConfigBuilder setMarketingCloudServerUrl:[NSURL URLWithString:MCAppServerUrl]];
  [pushConfigBuilder setMid:MCMid];
  [pushConfigBuilder setAnalyticsEnabled:YES];
  
  [SFMCSdk setKeychainAccessErrorsAreFatalWithErrorsAreFatal:NO];
    
  [SFMCSdk initializeSdk:[[[SFMCSdkConfigBuilder new] setPushWithConfig:[pushConfigBuilder build] onCompletion:^(SFMCSdkOperationResult result) {
    if (result == SFMCSdkOperationResultSuccess) {
      dispatch_async(dispatch_get_main_queue(), ^{
          // set the UNUserNotificationCenter delegate - the delegate must be set here in
          // didFinishLaunchingWithOptions
          [UNUserNotificationCenter currentNotificationCenter].delegate = self;
          [[SFMCSdk mp] setURLHandlingDelegate:self];
          [[UIApplication sharedApplication] registerForRemoteNotifications];
          
          [[UNUserNotificationCenter currentNotificationCenter]
          requestAuthorizationWithOptions:UNAuthorizationOptionAlert |
          UNAuthorizationOptionSound |
          UNAuthorizationOptionBadge
          completionHandler:^(BOOL granted, NSError *_Nullable error) {
            if (error == nil) {
              if (granted == YES) {
                    NSLog(@"User granted permission");
              }
            }
          }];
        });
    } else {
      //  MarketingCloudSDK sfmc_configure failed
      NSLog(@"SFMC sdk configuration failed.");
    }
  }] build]];


//This function continues here but is not relevant.

Hope that helps, ping me if you need any help, although sometimes it takes me a bit longer to reply because I'm really busy nowadays. Sorry about that!

Great, I've been adapting it so far, it says all connected, but I have yet to try sending me notifications, which is the important thing.

And how are you capturing on the JS side the notifications with notifee or react-native-push ? I've been trying to migrate to notifee but I still don't give it a good spin.

export const pushNotificationConfigure = (): void => {
    PushNotification.configure({
        // (required) Called when a remote is received or opened, or local notification is opened
        onNotification(notification) {
            // We need to create this channel for Android
            // Since it's not being created in the onRegister function, we call it here
            PushNotification.createChannel(
                {
                    channelId: NotificationsChannels.offers.id,
                    channelName: NotificationsChannels.offers.name,
                    channelDescription: NotificationsChannels.offers.description,
                    soundName: "default",
                    importance: 4,
                    vibrate: true,
                },
                (created) => {
                    if (__DEV__) {
                        console.log(`Channel created? ${created}`);
                    }
                },
            );

            if (notification?.data?._sid === "SFMC") {
                PushNotification.localNotification({
                    smallIcon: "ic_notification",
                    channelId: NotificationsChannels.offers.id,
                    message: notification.data.alert,
                    title: notification.data.title,
                    bigPictureUrl: notification.data._mediaUrl,
                    data: {
                        _m: notification?.data?._m,
                        url: notification.data._od,
                        mediaUrl: notification.data._mediaUrl,
                        mediaAlt: notification.data._mediaAlt,
                    },
                });
            }

            if (notification.userInteraction) {
                notificationHandler(notification);
            }

            // (required) Called when a remote is received or opened, or local notification is opened
            notification.finish(PushNotificationIOS.FetchResult.NoData);
        },

        // (optional) Called when the user fails to register for remote notifications. Typically occurs when APNS is having issues, or the device is a simulator. (iOS)
        onRegistrationError(err) {
            if (!__DEV__) {
                // We don't use the captureToSentry function that we made because this is a generic error
                // not related to OCAPI and we don't need to notify the user
                Sentry.captureException(err);
                Gleap.sendSilentCrashReportWithExcludeData(`Error to register notifications: ${err}`, "LOW", {
                    screenshot: true,
                    replays: true,
                    metaData: true,
                });
            }
        },

        // IOS ONLY (optional): default: all - Permissions to register.
        permissions: {
            alert: true,
            badge: true,
            sound: true,
        },

        // Should the initial notification be popped automatically
        // default: true
        popInitialNotification: true,

        /**
         * (optional) default: true
         * - Specified if permissions (ios) and token (android and ios) will requested or not,
         * - if not, you must call PushNotificationsHandler.requestPermissions() later
         * - if you are not using remote notification or do not have Firebase installed, use this:
         *     requestPermissions: Platform.OS === 'ios'
         */
        requestPermissions: false,
    });
};
```

manuelabarca avatar Jun 19 '25 07:06 manuelabarca

I'm using notifee in the javascript side yes. It's good so far, at least it has done the job and wasn't a big deal to implement. I cannot complain about it to be honest. Glad things are moving for you! I will keep an eye on the thread pin me here if you have any other questions! regards

MarlonAEC avatar Jun 20 '25 14:06 MarlonAEC

I'm using notifee in the javascript side yes. It's good so far, at least it has done the job and wasn't a big deal to implement. I cannot complain about it to be honest. Glad things are moving for you! I will keep an eye on the thread pin me here if you have any other questions! regards

By any chance could you share your implementation with notifee, I have not been able to migrate correctly, greetings.

manuelabarca avatar Jun 20 '25 15:06 manuelabarca

I managed to resolve my problem and still use swift. I am going to use this https://github.com/react-native-push-notification/ios/issues/451#issuecomment-2983336426 as a reference, as is as close to a fix as possible, without me reposting stuff.

When importing Objective-C packages via the Bridging Header this automatically makes those packages available in the AppDelegate.swift file, so no need to add an import for that package in there, in our case: import RNCPushNotificationIOS.

So once you remove that import, the error disappears. Happy hunting!

florinvasilevilsan avatar Aug 29 '25 14:08 florinvasilevilsan

@florinvasilevilsan Yes, this is a working method. The error is gone. But notifications still do not arrive. Is this problem observed?

Xemach avatar Aug 29 '25 14:08 Xemach

@florinvasilevilsan Yes, this is a working method. The error is gone. But notifications still do not arrive. Is this problem observed?

Sorry, did not get thus far. I am going through a painful react-native upgrade process (when has this been any different?). So far I've only got that error to disappear but still a long way from actually getting this thing to build, due to react-native-navigation https://github.com/wix/react-native-navigation/issues/8026 (still an open issue :( )

florinvasilevilsan avatar Aug 29 '25 14:08 florinvasilevilsan

I'm using notifee in the javascript side yes. It's good so far, at least it has done the job and wasn't a big deal to implement. I cannot complain about it to be honest. Glad things are moving for you! I will keep an eye on the thread pin me here if you have any other questions! regards

By any chance could you share your implementation with notifee, I have not been able to migrate correctly, greetings.

Sorry, I just saw your message. Were you able to figure it out? Do you still need the implementation? Although it was straightforward to implement following the docs, mine doesn't differ too much from the original docs

MarlonAEC avatar Nov 14 '25 15:11 MarlonAEC