文章目录
  1. 1. 一、模板生成
  2. 2. 二、环境配置
    1. 2.1. 2.1 添加项目库
    2. 2.2. 2.2 添加配置
  3. 3. 三、增加代码

本文主要是记录将React Native集成到现有项目的说明步骤及中间遇到的一些坑的记录。

一、模板生成

假如你的PC已经安装好了React Native环境,只需要在命令行执行以下命令即可以生成模板:

1
$react-native init RNDemo

其中RNDemo是项目名称,这里确保与你现在的项目名称一致。

生成好模板后,cd到RNDemo/ios/目录中,将该目录下的所有文件都删除,然后将现有项目所有文件复制到ios目录中。


二、环境配置

2.1 添加项目库

使用xcode打开现有项目,将以下库添加到项目中:

1
2
3
4
5
react-native/React/React.xcodeproj
react-native/Libraries/Network/RCTNetwork.xcodeproj
react-native/Libraries/Text/RCTText.xcodeproj
react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj
react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj

添加方法如下图所示:
xcode配置
在弹出的窗口的右下角点击Add Others...按钮,在弹出的窗口中选择上面相应目录下的.xcodeproj文件,将项目库包含进来。操作完成后,需要再次点击+号,将静态库都包含进来,如下图所示:
xcode添加静态库


2.2 添加配置

如下配置如果已经配置过,则可以跳过。

1)搜索头文件地址配置
头文件搜索路径配置如下所示:
头文件目录搜索路径配置
双击Header Search Path右侧区域即可显示弹出的层,双击其中的行,则进入编辑模式。

其中$(SRCROOT)为当前项目路径,可以理解为.xcodeproj文件所在的路径,../node_modules表示的是与ios同级目录的node_moduels目录。

2)启用HTTP配置
点击项目中的info.plist文件(注意是项目的plist文件,不是Tests中的),在右侧增加如下图所示的配置:
启用HTTP配置
如果没有启用,运行时会提示如下错误:

1
2
App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. 
Temporary exceptions can be configured via your app's Info.plist file.

3)支持C++编译
添加C++编译支持如下图所示:
添加C++编译支持
添加方法与上面添加Header Search Path类似。
如果没有添加-lc++,编译会报如下所示错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Undefined symbols for architecture x86_64:
"std::terminate()", referenced from:
___clang_call_terminate in libReact.a(RCTJSCExecutor.o)
"operator delete[](void*)", referenced from:
-[RCTJSCExecutor dealloc] in libReact.a(RCTJSCExecutor.o)
executeRandomAccessModule(RCTJSCExecutor*, unsigned int, unsigned long, unsigned long) in libReact.a(RCTJSCExecutor.o)
readRAMBundle(std::__1::unique_ptr<__sFILE, int (*)(__sFILE*)>, RandomAccessBundleData&) in libReact.a(RCTJSCExecutor.o)
RandomAccessBundleData::~RandomAccessBundleData() in libReact.a(RCTJSCExecutor.o)
"operator new[](unsigned long)", referenced from:
executeRandomAccessModule(RCTJSCExecutor*, unsigned int, unsigned long, unsigned long) in libReact.a(RCTJSCExecutor.o)
readRAMBundle(std::__1::unique_ptr<__sFILE, int (*)(__sFILE*)>, RandomAccessBundleData&) in libReact.a(RCTJSCExecutor.o)
"___cxa_begin_catch", referenced from:
___clang_call_terminate in libReact.a(RCTJSCExecutor.o)
"___gxx_personality_v0", referenced from:
-[RCTJavaScriptContext initWithJSContext:onThread:] in libReact.a(RCTJSCExecutor.o)
-[RCTJavaScriptContext init] in libReact.a(RCTJSCExecutor.o)
-[RCTJavaScriptContext invalidate] in libReact.a(RCTJSCExecutor.o)
RCTNSErrorFromJSError(RCTJSCWrapper*, OpaqueJSContext const*, OpaqueJSValue const*) in libReact.a(RCTJSCExecutor.o)
+[RCTJSCExecutor runRunLoopThread] in libReact.a(RCTJSCExecutor.o)
-[RCTJSCExecutor init] in libReact.a(RCTJSCExecutor.o)
-[RCTJSCExecutor initWithUseCustomJSCLibrary:] in libReact.a(RCTJSCExecutor.o)
...
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

如果没有添加-ObjC,运行则会报如下错误:

1
2
3
4
[error][tid:com.facebook.react.JavaScript] Native module cannot be null.
[error][tid:com.facebook.react.JavaScript] Requiring module "193", name:InitializeJavaScriptAppEngine, which threw an exception.
RNDemo[13446:1473714] -[RCTRootView reactTag]: unrecognized selector sent to instance 0x7ff670d14de0
RNDemo[13446:1473714] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RCTRootView reactTag]: unrecognized selector sent to instance 0x7ff670d14de0'

可能提示的module Id不一样,导致的原因是一样的。在这里卡了很久:(。


三、增加代码

在已有项目的启动配置位置,如AppDelegate.m文件中增加上面没有删除的AppDelegate.m文件中的代码,如下所示:

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
#import "AppDelegate.h"

#import "RCTBundleURLProvider.h"
#import "RCTRootView.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;

[[RCTBundleURLProvider sharedSettings] setDefaults];
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];

RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"RNDemo"
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];
return YES;
}

@end

注意:index.ios就是模板在RNDemo目录下生成的index.ios.js文件,moduleNameRNDemo是项目的名称,这里要替换成刚开始初始化模板的命令的项目名称。

最后,按cmd + r后,会自动启动React Native服务,可以看到运行效果。

文章目录
  1. 1. 一、模板生成
  2. 2. 二、环境配置
    1. 2.1. 2.1 添加项目库
    2. 2.2. 2.2 添加配置
  3. 3. 三、增加代码