0.5.0 • Published 6 years ago

react-native-router-bridge v0.5.0

Weekly downloads
2
License
Apache-2.0
Repository
github
Last release
6 years ago

react-native-router-bridge

react-native-router-bridge is a small module which bridges the navigation world between native and React Native.

DISCLAIMER

This project is currently in beta.

Core APIs are subject to change. We encourage people to try this library out and provide us feedback as we get it to a stable state.

Getting started

$ npm install react-native-router-bridge --save

Mostly automatic installation

$ react-native link react-native-router-bridge

Manual installation

iOS

  1. In XCode, in the project navigator, right click LibrariesAdd Files to [your project's name]
  2. Go to node_modulesreact-native-router-bridge and add MSRReactNativeRouterBridge.xcodeproj
  3. In XCode, in the project navigator, select your project. Add libMSRReactNativeRouterBridge.a to your project's Build PhasesLink Binary With Libraries
  4. Run your project (Cmd+R)<

Android

  1. Open up android/app/src/main/java/[...]/MainActivity.java
  • Add import net.mischneider.MSRReactNativeRouterBridgePackage; to the imports at the top of the file
  • Add new MSRReactNativeRouterBridgePackage() to the list returned by the getPackages() method
  1. Append the following lines to android/settings.gradle:
    include ':react-native-router-bridge'
    project(':react-native-router-bridge').projectDir = new File(rootProject.projectDir, 	'../node_modules/react-native-react-native-router-bridge/android')
  2. Insert the following lines inside the dependencies block in android/app/build.gradle:
      compile project(':react-native-router-bridge')

Usage

On iOS you have to respond to the callbacks via registering the following blocks on the MSRReactNativeRouterBridge singleton:

/**
 * React native router bridge is a native component that goal is to bridge the react native and the native
 * navigation world by providing a very small API.
 
 * React native route bridge provides a way to opening routes based on URLs for navigation. To be able to handle routes,
 * the native side need to register certain handler that get's called if the react native side would like to navigate.
 * to a new route or the native API is called directly via openURL:initialProperties:modally:
 * Specifically the handlers are:
 * - Pushing a new view controller on top of the stack for a given URL
 * - Pop the current view controller from the stack
 * - Show a new view controller modally for a given URL
 * - Dismiss a current modally showing view controller
 * - Show a new react native view controller for a given URL and also if modally or not
 * In this callback methods you can decide how you wanna handle the given URL. You could check if the router bridge
 * can handle the passed in URL and dispatch it further for handling this URL or just forward it to some other
 * internal native routing framework to handle the URL.
 */
- (void)setupRouterBridge
{
  MSRReactNativeRouterBridge *routerBridge = [MSRReactNativeRouterBridge sharedRouterBridge];
  __weak MSRReactNativeRouterBridge *weakRouterBridge = routerBridge;
  
  // Define how to push a view controller. The router bridge got a request to push a new view controller on the stack.
  // It's possible to handle the url you would like to. You can check the router bridge first if it supports what we
  // do in this case or forward it to your internal routing system to handle this.
  routerBridge.pushViewController = ^(UIViewController * _Nonnull fromViewController, NSString * _Nonnull url, MSRRouterBridgeOptionsType * _Nullable options) {
    NSLog(@"Push View Controller with url: %@, options: %@", url, options);
  };
  
  // Define how to pop the current view controller from the current navigation stack. The router brige got a request to
  // pop the current view controller from the stack and the native side need to react.
  routerBridge.popViewController = ^(UIViewController * _Nonnull fromViewController) {
    NSLog(@"Pop View Controller");
  };

  
  // Define how to show a modal view controller. The router bridge got a request to show a view controller modally.
  // It's possible to handle the url you would like to. You can check the router bridge first if it supports what we
  // do in this case or forward it to your internal routing system to handle this.
  routerBridge.showModalViewController = ^(UIViewController * _Nonnull fromViewController, NSString * _Nonnull url, MSRRouterBridgeOptionsType * _Nullable options) {
    NSLog(@"Show Modal View Controller with url: %@, options: %@", url, options);
  };
  
  // Define how to dismiss the current modal view controller.
  routerBridge.dismissModalViewController = ^(UIViewController * _Nonnull fromViewController) {
    NSLog(@"Dismiss Modal View Controller");
  };
  
  
  // Define how a react view controller should show up. This method is called if the router bridge got a request to
  // to open an url that was registered and associated with a module name from the React Native side beforehand.
  // Therefore the router bridge know's it needs to dispatch the request to this method with the associated module
  // and passed in properties. On the native side we are deciding how to handle this request.
  routerBridge.showReactViewController = ^BOOL(NSString * _Nonnull module, MSRRouterBridgePropType * _Nullable properties, BOOL modally) {
    NSLog(@"Show React View Controller with url: %@, options: %@, modally: %d", module, properties, modally);
    
    // We let the router bridge know if the native side was able to handle the request to show the react native
    // controller or not.
    return YES;
  };
}

On Android you can respond to the callbacks via the following callbacks on the MSRReactNativeRouterBridge singleton:

public void setupRouterBridge() {
  // Grab the MSRReactNativeRouterBridge singletong and register the callbacks
  final MSRReactNativeRouterBridge routerBridge = MSRReactNativeRouterBridge.getInstance();

  routerBridge.setOnPushComponentCallback(new MSRReactNativeRouterBridge.OnPushComponentCallback() {
    @Override
    public void onPushComponent(View fromView, String route, @Nullable ReadableMap options) {
      Log.d(TAG, "onPushComponentCallback, fromView: " + fromView.toString() + ", route: " + route + ", options: " + options);
    }
  });

  routerBridge.setOnPopComponentCallback(new MSRReactNativeRouterBridge.OnPopComponentCallback() {
    @Override
    public void onPopComponent(View fromView) {
      Log.d(TAG, "onPopComponentCallback, fromView: " + fromView.toString());
    }
  });

  routerBridge.setOnShowModalComponentCallback(new MSRReactNativeRouterBridge.OnShowModalComponentCallback() {
    @Override
    public void onShowModalComponent(View fromView, String route, @Nullable ReadableMap options) {
      Log.d(TAG, "onShowModalComponent, fromView: " + fromView.toString() + ", route: " + route + ", options: " + options);
    }
  });

  routerBridge.setOnDismissModalComponentCallback(new MSRReactNativeRouterBridge.OnDismissModalComponentCallback() {
    @Override
    public void onDismissModalComponent(View fromView) {
      Log.d(TAG, "onDismissModalComponentCallback, fromView: " + fromView.toString());
    }
  });

  routerBridge.setOnShowReactComponentCallback(new MSRReactNativeRouterBridge.OnShowReactComponentCallback() {
    @Override
    public boolean onShowReactComponent(String moduleName, @Nullable HashMap options, boolean modally) {
      Log.d(TAG, "onShowReactComponent, moduleName: " + moduleName + ", options: " + options + ", modally: " + modally);
    }
  });
}

Within React Native you can use the router bridge the following way to push or present modally view controllers:

import RouterBridge from 'react-native-router-bridge';

_onPushNativeViewController = () => {
  // Push a native view controller based on url and pass some optional options
  RouterBridge.push(this, 'routerbridge://some-other-path', { key: 'value' });
};

_onPopNativeViewControlelr = () => {
  // Pop a native view controller
  RouterBridge.pop(this);
}

_onShowNativeModalViewController = () => {
  // Show a native modal based on url
  RouterBridge.showModal(this, 'routerbridge://some-other-path');
};

_onDismissModalViewController = () => {
  // Dismiss a current modally presented view controller
  RouterBridge.dismissModel(this);	
}

_onPushReactViewController = () => {
  // Push a react native view controller based on the url and pass some optional options
  // 'Example' is the module name that should be rendered within the view controller
  RouterBridge.push(
    this,
    'routerbridge://react-native/Example'
  );
};

_onShowReactViewController = () => {
  // Show a react modal based on url and pass some optional options
  // 'Example' is the module name that should be rendered within the view controller
  RouterBridge.showModal(
    this,
    'routerbridge://react-native/Example'
  );
};

Interop with React Navigation (Experimental)

react-native-router-bridge has out of the box interop support with react-navigation, the most common used JavaScript only React Native navigation library. This allows you to build a flow within a React Native view that uses React Navigation for navigation within the React Native layer, but is managed by a native view controller and get’s pushed or showed modally regularly within the native navigation stack. This for example would allow you to build a self contained flows like onboarding that plays nicely with the native navigation infrastructure. The Example-ReactNavigation example in this repository should show an interaction between a native application and a view controller that is managing a React Native component that uses React Navigation.

License

Copyright 2018 Michael Schneider

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.