iOS开发 React Native与iOS交互汇总
RN简介
React Native 是一个使用React和应用平台的原生功能来构建 Android 和 iOS 应用的开源框架。起源于faceBbook内部,2013开源。
React Native 组件就是对原生视图的封装,因此使用 React Native 编写的应用外观、感觉和性能与其他任何原生应用一样。
RN坏境搭建
iOS必须安装的依赖有:Node、Watchman、Xcode 和 CocoaPods。
可以参考RN官网:https://reactnative.cn/docs/environment-setup
iOS 调用React Native
1,打开一个React Native页面
比如react-native init RNInteractionWithiOS 创建一个应用之后就会自动在 RNInteractionWithiOS->ios->RNInteractionWithiOS->AppDelegate.m
中生成打开一个React Native页面的代码。核心代码如下:
- NSURL *jsCodeLocation;
- jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
- RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
- moduleName:@"RNInteractionWithiOS"
- initialProperties:nil
- launchOptions:launchOptions];
- rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
- self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
- UIViewController *rootViewController = [UIViewController new];
- rootViewController.view = rootView;
- self.window.rootViewController = rootViewController;
- [self.window makeKeyAndVisible];
iOS调用RN(分是否传参数)
RN核心代码
- componentWillMount() {
- DeviceEventEmitter.addListener('EventInit', (msg) => {
- let receive = "EventInit: " + msg;
- console.log(receive);
- this.setState({notice: receive});
- });
- DeviceEventEmitter.addListener('EventLogin', (msg) => {
- let receive = "EventLogin: " + msg;
- console.log(receive);
- this.setState({notice: receive});
- });
- }
- 创建的iOS交互类要引用
#import<React/RCTBridgeModule.h>
和#import <React/RCTEventEmitter.h>
,继承RCTEventEmitter
,并遵守RCTBridgeModule
- 很关键的:交互类要设置
bridge
为当前RCTRootView的bridge
,[[ReactInteraction shareInstance] setValue:rnView.bridge forKey:@"bridge"];
ReactInteraction.h文件
- #import <Foundation/Foundation.h>
- #import <React/RCTBridgeModule.h>
- #import <React/RCTEventEmitter.h>
- @interface ReactInteraction : RCTEventEmitter <RCTBridgeModule>
- + (instancetype)shareInstance;
- - (void)init:(NSString *)parameter;
- - (void)login;
- @end
ReactInteraction.m文件
- #import "ReactInteraction.h"
- #define INIT @"EventInit"
- #define LOGIN @"EventLogin"
- @implementation ReactInteraction
- static ReactInteraction *instance = nil;
- RCT_EXPORT_MODULE();
- + (instancetype)shareInstance {
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- instance = [[self alloc] init];
- });
- return instance;
- }
- - (NSArray<NSString *> *)supportedEvents
- {
- return @[INIT,LOGIN];
- }
- RCT_EXPORT_METHOD(init:(NSString *)msg) {
- [self.bridge enqueueJSCall:@"RCTDeviceEventEmitter"
- method:@"emit"
- args:@[INIT, msg]
- completion:NULL];
- }
- RCT_EXPORT_METHOD(login) {
- [self.bridge enqueueJSCall:@"RCTDeviceEventEmitter"
- method:@"emit"
- args:@[LOGIN]
- completion:NULL];
- }
- @end
React Native调用iOS
RN核心代码:
- import {NativeModules} from 'react-native';
- const NativeInteraction = NativeModules.NativeInteraction;
- OS核心代码:
- 注意点1:
RCT_EXPORT_METHOD
与RCT_REMAP_METHOD
宏定义的使用区别(个人总结,有不对请指正)RCT_EXPORT_METHOD
:用于仅有一个参数或回调-
RCT_REMAP_METHOD
:用于有多个参数或(和)多个回调
(了解更多可以看RN宏定义源码1
,下面贴出关键两句)
- 注意点2:iOS回调方式有两种
callback(@[jsonString]); ((RCTPromiseResolveBlock)resolver)
- Promise方式:
_resolveBlock(@[jsonString]); ((RCTResponseSenderBlock)callback)
(了解更多看RN源码2
)
- 注意点1:
源码1:
- #define RCT_REMAP_METHOD(js_name, method) \
- _RCT_EXTERN_REMAP_METHOD(js_name, method, NO) \
- - (void)method RCT_DYNAMIC;
- #define RCT_EXPORT_METHOD(method) \
- RCT_REMAP_METHOD(, method)
源码2
- RCT_EXPORT_METHOD(navigate:(NSString*)page parameter:(NSDictionary *)dic callback:(RCTResponseSenderBlock )callback){
- //主线程处理UI事件
- dispatch_async(dispatch_get_main_queue(), ^{
- //跳转类型
- if ([page isEqualToString:@"ShoppingMall"]){
- //九九老年商城
- WeiMengWebVC *weiMengWebVC = [[WeiMengWebVC alloc] init];
- [dic setValue:@"1" forKey:@"type"];
- weiMengWebVC.dic = dic;
- [[UIViewController topViewController].navigationController pushViewController:weiMengWebVC animated:YES];
- }
- }
- typedef void (^RCTResponseSenderBlock)(NSArray *response);
- typedef void (^RCTResponseErrorBlock)(NSError *error);
- typedef void (^RCTPromiseResolveBlock)(id result);
- typedef void (^RCTPromiseRejectBlock)(NSString *code, NSString *message, NSError *error