react-native-branch-deep-linking-attribution icon indicating copy to clipboard operation
react-native-branch-deep-linking-attribution copied to clipboard

IOS no known class method for selector 'initSessionWithLaunchOptions:

Open livindead opened this issue 3 years ago • 5 comments

Describe the bug

After installation on IOS, when trying to compile, the following error appears no known class method for selector 'initSessionWithLaunchOptions: line [RNBranch initSessionWithLaunchOptions:launchOptions];

Steps to reproduce

  1. Install the module
  2. add to AppDelegate.mm [RNBranch initSessionWithLaunchOptions:launchOptions]; NSURL *jsCodeLocation;

Expected behavior

Successful compile

SDK Version

5.5.0

Make and Model

iphone xr

OS

ios

Additional Information/Context

No response

livindead avatar Sep 26 '22 21:09 livindead

@livindead Could you double check that the Branch import is in a valid location? I found the new RN sample AppDelegate had #if RCT_NEW_ARCH_ENABLED and corresponding #endif that is easy to overlook when setting imports.

echo-branch avatar Sep 26 '22 22:09 echo-branch

@livindead Could you double check that the Branch import is in a valid location? I found the new RN sample AppDelegate had #if RCT_NEW_ARCH_ENABLED and corresponding #endif that is easy to overlook when setting imports.

My AppDelegate.mm:


#import "AppDelegate.h"
#import <RNBranch/RNBranch.h>

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTLinkingManager.h>
#import <React/RCTConvert.h>

#import <React/RCTAppSetupUtils.h>


#if RCT_NEW_ARCH_ENABLED

#import <React/CoreModulesPlugins.h>
#import <React/RCTCxxBridgeDelegate.h>
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
#import <React/RCTSurfacePresenter.h>
#import <React/RCTSurfacePresenterBridgeAdapter.h>
#import <ReactCommon/RCTTurboModuleManager.h>

#import <react/config/ReactNativeConfig.h>



@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
  RCTTurboModuleManager *_turboModuleManager;
  RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
  std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
  facebook::react::ContextContainer::Shared _contextContainer;
}
@end
#endif

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  // Uncomment this line to use the test key instead of the live one.
     // [RNBranch useTestInstance];
     [RNBranch initSessionWithLaunchOptions:launchOptions];
     NSURL *jsCodeLocation;
  
  RCTAppSetupPrepareApp(application);

  RCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:launchOptions];
  
 

#if RCT_NEW_ARCH_ENABLED
  _contextContainer = std::make_shared<facebook::react::ContextContainer const>();
  _reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
  _contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
  _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
  bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
#endif

  UIView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:@"main" initialProperties:nil];

  rootView.backgroundColor = [UIColor whiteColor];
  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [self.reactDelegate createRootViewController];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];

  [super application:application didFinishLaunchingWithOptions:launchOptions];

  return YES;
}

- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
{
  // If you'd like to export some custom RCTBridgeModules, add them here!
  return @[];
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}

// Linking API
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
  return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options];
  [RNBranch application:application openURL:url options:options];
  return YES;
}

// Universal Links
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
  BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
  return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result;
  [RNBranch continueUserActivity:userActivity];
  return YES;
}

// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
  return [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}

// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
  return [super application:application didFailToRegisterForRemoteNotificationsWithError: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];
}

#if RCT_NEW_ARCH_ENABLED

#pragma mark - RCTCxxBridgeDelegate

- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
{
  _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
                                                             delegate:self
                                                            jsInvoker:bridge.jsCallInvoker];
  return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
}

#pragma mark RCTTurboModuleManagerDelegate

- (Class)getModuleClassFromName:(const char *)name
{
  return RCTCoreModulesClassProvider(name);
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
                                                      jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
{
  return nullptr;
}

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
                                                     initParams:
                                                         (const facebook::react::ObjCTurboModule::InitParams &)params
{
  return nullptr;
}

openURL- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
{
  return RCTAppSetupDefaultModuleFromClass(moduleClass);
}

#endif

@end

livindead avatar Sep 27 '22 15:09 livindead

@livindead That looks reasonable to me. Maybe you have some stuff cached, could try a heavy handed clear of caches.

  1. Remove ios/Pods and ios/Podfile.lock
  2. Remove node_modules and the lock file
  3. run npm install
  4. run pod install from the ios folder

Something to watch out for, I've had issues using a mix of yarn and npm.

echo-branch avatar Sep 27 '22 18:09 echo-branch

@livindead I just spent some time debugging this issue as well and think I've fixed it. The docs don't specify but it looks like that line also needs isReferrable. Try updating the line to this and see if it works for you: RNBranch.initSession(launchOptions: launchOptions, isReferrable: false)

AdamTyler avatar Sep 29 '22 17:09 AdamTyler

Just finished implementing branch on a project sitting on RN 0.63.0

Got it working on branch 5.5.0 after facing the same issue with initSessionWithLaunchOptions

my steps to solve it: a) pod deintegrate && pod install && pod update b) I did what @AdamTyler above said, but I had to dig and suffer to write that in Obj-C [RNBranch initSessionWithLaunchOptions:launchOptions isReferrable:YES]; c) I made sure that Branch is initialized only after the #ifdef block inside the didFinishLaunchingWithOptions

// ...
InitializeFlipper(application);
#endif

  // RNBranch implementation
  // Uncomment this line to use the test key instead of the live one.
  [RNBranch useTestInstance];
  [RNBranch initSessionWithLaunchOptions:launchOptions isReferrable:YES]; 
// ...

I don't know about that last step importance, done b and c together before attempting a yarn run ios command but it's working now

Joaojuby avatar Oct 07 '22 13:10 Joaojuby