iOS原生项目和React Native交互

2020-12-05  本文已影响0人  玉思盈蝶

一、不太成功的实现

package.json文件:
{
  "name": "myRactNative",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint ."
  },
  "dependencies": {
    "react": "16.3.0",
    "react-native": "^0.63.4"
  },
  "devDependencies": {
    "@babel/core": "^7.8.7",
    "@babel/runtime": "^7.8.7",
    "@react-native-community/eslint-config": "^0.0.7",
    "babel-jest": "^25.1.0",
    "eslint": "^6.8.0",
    "jest": "^25.1.0",
    "metro-react-native-babel-preset": "^0.58.0",
    "react-test-renderer": "16.9.0"
  },
  "jest": {
    "preset": "react-native"
  }
}

Profile文件:

platform :ios, '10.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

target 'ReactNativeIOSDemo' do
  # Pods for ReactNativeIOSDemo
  pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
  pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
  pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
  pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
  pod 'React', :path => '../node_modules/react-native/'
  pod 'React-Core', :path => '../node_modules/react-native/'
  pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
  pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
  pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
  pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
  pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
  pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
  pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
  pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
  pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
  pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
  pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
  pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'

  pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
  pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
  pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
  pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
  #pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon"
  #pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
pod 'React-callinvoker', :path => "../node_modules/react-native/ReactCommon/callinvoker"
pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
  pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'

  pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
  pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
  pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'

  use_native_modules!
end

重点就是以上两个文件配置了,实话实说踩了好多坑啊,还好最后解决了,项目也跑起来了,但是。。。。。。RN的页面怎么也不显示。。。。

最后,我用命令脚手架创建的RN的项目,再在iOS项目里写和RN的传值,完美的实现。

二、成功的实现:

创建RN项目;
运行js代码; npm start
iOS原生给RN传值;

具体iOS传值代码如下:
//
//  ViewController.m
//  rnDemo
//
//  Created by 彭思 on 2020/12/4.
//

#import "ViewController.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>

#ifdef FB_SONARKIT_ENABLED
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>

static void InitializeFlipper(UIApplication *application) {
  FlipperClient *client = [FlipperClient sharedClient];
  SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
  [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
  [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
  [client addPlugin:[FlipperKitReactPlugin new]];
  [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
  [client start];
}
#endif

#import "ViewController1.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
  self.view.backgroundColor = [UIColor redColor];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
  NSArray *imageList = @[@"http://foo.com/bar1.png",
                         @"http://foo.com/bar2.png"];

  NSDictionary *props = @{@"urls" : imageList};
  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:nil];
  
  // 没有打包main.jsbundle的代码
//  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
//                                                     moduleName:@"rnDemo"
//                                              initialProperties:props];
  
  // 使用main.jsbundle打包
  NSURL *jsCodeLocation2 = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
  RCTRootView *rootView = [[RCTRootView alloc]initWithBundleURL:jsCodeLocation2 moduleName:@"rnDemo" initialProperties:props launchOptions:nil];

  ViewController1 *vc = [[ViewController1 alloc]init];
  vc.view = rootView;
  [self presentViewController:vc animated:YES completion:nil];
}


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

@end

RN代码取iOS原生传过去的值:

export default class App extends React.Component {
  renderImage(imgURI) {
    return (
      <Text>{imgURI}</Text>
    );
  }
  render() {
    return (
      <View>
        {this.props.urls.map(this.renderImage)}
      </View>
    );
  }
}

RN页面正常跳转,传递的值正常显示。

参考链接:

Swift原生项目中集成RN的踩坑笔记

https://blog.csdn.net/ql_procareer/article/details/106101604

官网:和原生端的通信

https://reactnative.cn/docs/communication-ios/

RN和iOS原生交互

https://www.jianshu.com/p/2fbc070410be

React Native与iOS原生交互(纯干货)

https://www.jianshu.com/p/44b65cbd63b4?utm_campaign=hugo

React Native 向iOS项目中添加React Native支持

https://www.pianshen.com/article/97721371419/

百度查问题的时候看到了我几年前的博客,哈哈。

http://www.mamicode.com/info-detail-1857660.html

PS:RN真的好坑啊,环境真的也是搞得想死。。。。。。

遇到的一些问题:

image.png image.png

确实最后是版本不一致导致的,修改版本一致解决。

image.png

这个是修改profile解决的。

不想说了,反正就是很坑~~~

上一篇下一篇

猜你喜欢

热点阅读