ReactNative集成到已有iOS项目

最近在维护一个项目,需要引入ReactNative开发新UI。记录一下过程,表示我搞过。V

需要安装node环境

brew install node
npm install -g yarn

接着创建一个目录用来保存工程文件,并在目录项目下面创建一个package.json文件

mkdir demo
cd demo
npm init

加下来安装react native必须的库, 0.71.7版本是支持xcode14.2的,大于这个版本就需要xcode14.3了,我的电脑是MBP 2015 Mid,只能升级到xcode14.2,所以也只能用这个react-native版本。

yarn add react-native@0.71.7
yarn add react@18.2.0

react native部分就准备好了,接下来我们配置iOS部分,首先在demo目录下创建一个ios目录,把iOS源码copy到这个ios目录里面。接下来需要cocoapods的配置,编辑Podfile,在里面添加
require_relative ‘…/node_modules/react-native/scripts/react_native_pods’
require_relative '…/node_modules/@react-native-community/cli-platform-ios/native_modules’与use_react_native!。下面是一个Sample

# Uncomment the next line to define a global platform for your project
# platform :ios, '13.0'

require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

target 'App' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!
  use_react_native!

  # Pods for App

end

接下来

pod install

这下工程准备好了。

native加载react native页面

接下来我们用react native来写一个页面。再demo目录创建一个index.js文件,内容如下

import React from 'react';
import {AppRegistry, StyleSheet, Text, View} from 'react-native';

const RNHighScores = ({scores}) => {
  const contents = scores.map(score => (
    <Text key={score.name}>
      {score.name}:{score.value}
      {'\n'}
    </Text>
  ));
  return (
    <View style={styles.container}>
      <Text style={styles.highScoresTitle}>
        2048 High Scores!
      </Text>
      <Text style={styles.scores}>{contents}</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#FFFFFF',
  },
  highScoresTitle: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  scores: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

// Module name
AppRegistry.registerComponent('RNHighScores', () => RNHighScores);

这是react native开发的页面, 注册的组件名是RNHighScores。接下来我们再iOS native端来显示这个页面。
创建一个UIViewController.

//
//  MyRNViewController.swift
//  App
//
//  Created by Haven Tang on 2024/5/27.
//  https://reactnative.dev/docs/0.73/integration-with-existing-apps
//  https://www.youtube.com/watch?v=3wftC30CN2I
//  https://nishabe.medium.com/how-to-integrate-react-native-code-with-an-existing-ios-app-655c61a65b8c
// https://fbflipper.com/docs/getting-started/ios-native/
// https://fbflipper.com/docs/getting-started/react-native/


import UIKit
import React

class MyRNViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }
    
    override func loadView() {
        loadReactView()
    }
    
    func loadReactView() {
        let bundleUrl = URL(string: "http://localhost:8081/index.bundle?platform=ios")
        let mockData: NSDictionary = ["scores":
            [
                ["name":"Alex", "value":"42"],
                ["name":"Joel", "value":"10"]
            ]
        ]
        let rootView = RCTRootView(bundleUrl: bundleUrl, moduleName: "RNHighScores", initialProperties: mockData as [NSObject : AnyObject], launchOptions: nil)
        self.view = rootView
    }
}

显示这个view

@IBAction func showRNScoresView(_ sender: Any) {
        let vc = MyRNViewController()
        
        self.present(vc, animated: true)
    }

接下来运行App验证一下, 这儿我们使用的Metro bundler是本地http://localhost的一个服务,需要网络访问,所以记得再plist中开启运行http访问网络。

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>localhost</key>
        <dict>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

开启react native的Metro bundler server

npm start

运行App,点击xcode运行,或者命令行运行App

# From the root of your project
$ npx react-native run-ios

如果发布App的时候,我们需要将Metro bundler打包到App bundle里面。再package.json的scripts里面加上

"bundle-ios": "react-native bundle --entry-file index.js --bundle-output ./ios/bundle/main.jsbundle --platform ios --assets-dest ./ios/bundle --dev false",
"bundle-android": "react-native bundle --entry-file index.js --bundle-output ./android/app/src/main/assets/main.bundle --platform android --assets-dest ./android/app/src/main/res --dev false",

运行下面命令打包ios bundle

yarn bundle-ios

查看ios/bundle目录下文件,将其拖入xcode工程,这样就可以直接加载bundle中的资源了。
对应的bundleUrl需要调整一下:

let bundleUrl = NSBundle(URLForResource: "main" withExtension:"jsbundle")

react native加载native页面

要实现React native直接使用Native中的页面,可以使用React Native 的Native Component技术。后续会被Fabric 原生组件 替代。

源码下载

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值