嘗試將 React Native 與現有 Java/Objective-C Native APP 做配合溝通的簡單範例。
# install react-native dependencies, cd rn/
yarn
# run react-native
yarn run start
# Android Studio open Android project and run Simulators
# ios install pods, Xcode open project and run Simulators
-
Integrating React Native into an Existing App (Android)可以學習到
-
RN Component initial Props: ReactMainActivity
- 建立繼承 ReactContextBaseJavaModule 的 class,並加入方法:
# /android/app/src/main/java/com/example/duncan_du/android/ReactEventManager.java
public class ReactEventManager extends ReactContextBaseJavaModule {
public ReactEventManager(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "ReactEventManager";
}
@ReactMethod
public void showNativeAlert(String message) {
Toast.makeText(getReactApplicationContext(), message, Toast.LENGTH_LONG).show();
// send event to RN
this.getReactApplicationContext()
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("eventToRN","connecting RN.....");
}
}
- 建立繼承 ReactPackage 的 class,並將剛建立的 ReactEventManager 加入:
# /android/app/src/main/java/com/example/duncan_du/android/AnExampleReactPackage.java
public class AnExampleReactPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new ReactEventManager(reactContext));
return modules;
}
}
- MainApplication 中加入 ReactPackage 的引用:
# /android/app/src/main/java/com/example/duncan_du/android/MainApplication.java
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new AnExampleReactPackage()
);
}
# /ios/ios/ViewController.m
- (IBAction)addRNViewPressed:(id)sender {
NSURL *jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.bundle?platform=ios"];
RCTRootView *rootView =
[[RCTRootView alloc] initWithBundleURL: jsCodeLocation
moduleName: @"RNExistingApp"
initialProperties:
@{
@"message" : @"Hello, I'm come from iOS"
}
launchOptions: nil];
UIViewController *vc = [[UIViewController alloc] init];
vc.view = rootView;
[self presentViewController:vc animated:YES completion:nil];
}
- 建立 .h & .m 檔案,加入發法與曾聽事件
# /ios/ios/ReactEventManager.h
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
@interface ReactEventManager : RCTEventEmitter <RCTBridgeModule>
@end
# /ios/ios/ReactEventManager.m
#import "ReactEventManager.h"
#import <React/RCTLog.h>
@implementation ReactEventManager
RCT_EXPORT_MODULE();
- (NSArray<NSString *> *)supportedEvents
{
return @[@"eventToRN"];
}
RCT_EXPORT_METHOD(showNativeAlert:(NSString *)message)
{
RCTLogInfo(@"from RN Message %@", message);
[self sendEventWithName:@"eventToRN" body:@"test RN integration with existing app"];
UIViewController *presentingController = RCTPresentedViewController();
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Alert" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
[alertController addAction:ok];
[presentingController presentViewController:alertController animated:YES completion: nil];
}
@end
- 使用 React-Native 的 NativeModules & NativeEventEmitter 和 Native 做溝通:
# rn/App.js
import {
NativeModules,
NativeEventEmitter,
} from 'react-native';
const { ReactEventManager } = NativeModules;
# onPress Method
ReactEventManager.show('From React Native: Awesome!');
# Event AddListener
componentDidMount() {
const ManagerEvent = new NativeEventEmitter(ReactEventManager);
this._subscription = ManagerEvent.addListener('eventToRN', (info) => {
this.setState({ nativeEventInfo: info });
});
}
componentWillUnmount() {
this._subscription.remove();
}