1
votes

I cannot make a react-native app push new controllers from an iOS native framework. I'm trying to wrap it up into a react-native library, and I managed to make the base view be displayed, but when I interact with it, new screens won't be pushed. Is it possible to navigate between native screens located into the native framework?

I wrapped the framework into a react-native library successfully, using react-native-create-library. I am able to display the base view, and when clicking on buttons that present views on the same screen (such a datepicker) it works fine. But when I click on a button that should pushes a new view controller, it won't react.

I'm testing it into a dummy brand-new react-native app, and changed the AppDelegate.m to use a UINaVigationController instead of the default UIViewController, as follows:

UIViewController *rootViewController = [UIViewController new];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];

[[RNHellLib sharedInstance] configureSDK: navigationController];

Then in my library I'm doing this:

- (dispatch_queue_t)methodQueue
{
    return dispatch_get_main_queue();
}

RCT_EXPORT_MODULE(RNSearchBox)
RCT_EXPORT_VIEW_PROPERTY(rootController, UIViewController)

SearchBox *mySearchBox;

- (UIView *)view {
    return mySearchBox;
}

+ (instancetype)sharedInstance {
    static RNHellLib *sharedInstance = nil;
    static dispatch_once_t onceToken = 0;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[RNHellLib alloc] init];

    });
    return sharedInstance;
}

- (void) configureSDK: (UINavigationController *)rootController {
    mySearchBox = [[SearchBox alloc] init];
    mySearchBox.rootController = rootController;
}

On the SDK side, I'm pushing new view controllers using viewController.show(viewControllerToBePushed, sender), and also tried with viewController.present(viewControllerToBePushed, animation: true), but screens don't change either way.

I've read tones of docs and tutorials that use react-navigation or similar libraries to navigate between react-native screens, and also between existing (and known) swift views built up into the same app. But this means that the reat-native side has to know in advance the views that we display when interacting with the elements, instead of letting the framework work as a "black-box" on it's own.

Is it possible? Can it work as a "black-box" as does work in other native apps? Or I will need to compulsorily expose all view controllers and trigger them manually from JSX?

1

1 Answers

0
votes

I haven't implemented it by myself but it works fine for me in the following library https://github.com/troublediehard/react-native-braintree-xplat

shortly

// RCTBraintree.h

@interface RCTBraintree : UIViewController <RCTBridgeModule, ...>

@property (nonatomic, strong) UIViewController *reactRoot;
...

@end


//  RCTBraintree.m

#import "RCTBraintree.h"

@implementation RCTBraintree

...


RCT_EXPORT_METHOD(showApplePayViewController:(NSDictionary *)options callback:(RCTResponseSenderBlock)callback)
{
    dispatch_async(dispatch_get_main_queue(), ^{
        ...

        PKPaymentAuthorizationViewController *viewController = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:paymentRequest];
        viewController.delegate = self;

        [self.reactRoot presentViewController:viewController animated:YES completion:nil];
    });
}

...

- (UIViewController*)reactRoot {
    UIViewController *root  = [UIApplication sharedApplication].keyWindow.rootViewController;
    UIViewController *maybeModal = root.presentedViewController;

    UIViewController *modalRoot = root;

    if (maybeModal != nil) {
        modalRoot = maybeModal;
    }

    return modalRoot;
}

...

@end