由于项目的业务需求,需要将原生的项目向React Native重构。原生的Android和iOS项目处于正常迭代的情况,React Native的重构版本已经初步完成一个基础版本,现在需要在这个基础版本上,进行原生端的接入工作。目标是在原生项目里的某几个页面,替换为React Native页面。
以下是记录本次接入遇到的问题
iOS端
下载原生项目
从代码仓库中下载原生项目并执行pod install
成功运行在手机上。
集成到React Native项目中
将React Native项目中的
ios
文件夹删除,并把原生的iOS项目拖入文件夹中修改文件夹名称为ios
修改podfile文件
React Native项目以及iOS原生项目都是用了cocospod作为库管理工具,所以需要做一个手动的合并操作,以下是合并之后的podfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
# Uncomment the next line to define a global platform for your project
platform :ios, '10.0'
target 'Name' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
# use_frameworks!
config = use_native_modules!
use_react_native!(
:path => config[:reactNativePath],
# to enable hermes on iOS, change `false` to `true` and then install pods
:hermes_enabled => true
)
pod 'Bugly'
pod 'YYText'
use_flipper!('Flipper' => '0.75.1', 'Flipper-Folly' => '2.5.3', 'Flipper-RSocket' => '1.3.1')
post_install do |installer|
react_native_post_install(installer)
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
config.build_settings['ARCHS'] = 'arm64'
end
end
end
end保留了原生项目需要依赖的第三方库,以及React Native所需的库,之后执行
1
$ pod install
运行
第一次运行可能会出现各种不同的问题,这里只记录了本人实际操作过程中遇到的问题以及解决方案
library not found for
在Xcode编译的时候,可能会遇到报这个错误”library not found for -lxxxxxx”。这是由于Xcode找不到React Native所依赖的库,但是这个需要依赖的库可以在Pods中找到,那么只需要在设置中给Xcode指向这个库的位置。
在Build Setting
—>Library Search Paths
添加找不到的这个库的地址,如添加:
1 | "${PODS_CONFIGURATION_BUILD_DIR}/Yoga" |
“associated type descriptor for Swift.ExpressibleByFloatLiteral.FloatLiteralType”, referenced from:
这是一个有些摸不到头脑的问题,因为这个项目里根本就没有Swift写的代码,一时之间不知道问题所在,经过一番谷歌,找到了解决方案如下:
只需要在项目里新建一个Swift文件,里面什么都不用写,再次编译就没有这个问题了。
1 | File -> New -> File |
No bundle URL present
项目这个时候已经正常编译成功了,但是一运行App直接就得了红屏报错。这个是React Native常见的错误,即App访问不到bundle文件,但是又有一些不同:
- App并没有试图向8081端口请求bundle,App上方没有一个进度条,直接就出现这个错误。
- 电脑上8081端口没有自动启动
- 手动启动8081端口之后,App没有响应,node服务也显示没有连接到App
根据8081端口没有自动启动,找到了Build Phases
配置项,这里是Xcode在编译时候会执行的一些操作,和之前的React Naitve项目中的ios工程做了比较。缺少了一些shell脚本:Start Packager
和Bundle React Native code and images
两个脚本,从原有项目拷贝过来即可。
error opening input file ‘x/x-Bridging-Header.h’
在Xcode
—>target
—>Objective-C Bridging Header
中修改为正确的的地址,或者不存在这个文件的话,直接清空即可
Android
下载原生项目
从代码仓库中下载原生项目并成功编译。
集成到React Native项目中
将React Native项目中的
android
文件夹删除,并把原生的Android项目拖入文件夹中修改文件夹名称为android
修改app/build.gradle
在
dependencies
中添加React Native所需要的依赖库1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37dependencies {
implementation "com.android.support:appcompat-v7:27.1.1"
...
原生项目依赖
...
implementation "com.facebook.react:react-native:+" // From node_modules
/* Filpper相关 */
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
exclude group:'com.facebook.fbjni'
}
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
exclude group:'com.squareup.okhttp3', module:'okhttp'
}
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
}
/* Js引擎 Hermes或者是Jsc */
if (enableHermes) {
def hermesPath = "../../node_modules/hermes-engine/android/";
debugImplementation files(hermesPath + "hermes-debug.aar")
releaseImplementation files(hermesPath + "hermes-release.aar")
} else {
implementation jscFlavor
}
...
React Native项目中其他依赖
...
}由于React Native项目中需要开启Hermes引擎,还需要将相关的配置添加到
build.gradle
文件中1
2
3
4
5project.ext.react = [
enableHermes: true,
]
def enableHermes = project.ext.react.get("enableHermes", false);修改build.gradle
在项目的
build.gradle
文件中为 React Native 和 JSC 引擎添加 maven 源的路径,必须写在 “allprojects” 代码块中1
2
3
4
5
6
7
8
9
10
11
12
13
14allprojects {
repositories {
maven {
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
maven {
// Android JSC is installed from npm
url("$rootDir/../node_modules/jsc-android/dist")
}
...
}
...
}启用原生模块的自动链接
在
setting.gradle
中添加1
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
在
app/build.gradle
的最底部添加1
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
运行
Error:Failed to open zip file. Gradle’s dependency cache may be corrupt (this sometimes occurs after a network connection timeout.)
这是由于网络原因下载Gradle文件的时候,没有下载成功。由于没有下载完成的文件存在,再次点击下载依旧会报同样的错误。
找到这个没下载成功的文件,删除并重新下载即可,在
1 | ~/.gradle/wrapper/dists |
找到相应版本的文件,删除即可
Caused by: groovy.lang.MissingPropertyException: Could not get unknown property ‘mergeResourcesProvider’ for object of type com.android.build.gradle.internal.api.ApplicationVariantImpl.
修改了distributionUrl
的版本以及android/build.gradle
文件,改为了以下的版本
1 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip |
1 | com.android.tools.build:gradle:3.3.0 |