我只是从干净的 Xcode 项目开始制作整个过程。通常我简单地创建 RN 应用程序,弹出然后翻译为 cocoapods ios 部分。
它主要基于 RN 文档:http://facebook.github.io/react-native/docs/0.51/integration-with-existing-apps.html
所以环境:macOS Sierra、Xcode 9.2、RN 0.51.0
项目名称:MyApp
准备
- 创建新的 Xcode 项目,从“单一视图应用”模板,产品名称“MyApp”,语言 Objective-C
- 运行,看看效果如何
-
cd MyApp、mkdir ios、mv MyApp* ios(将所有ios相关文件移至ios子文件夹)
安装 npm 依赖项
在项目的根文件夹中创建package.json(非常基本)
{
"name": "MyApp",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start"
},
"dependencies": {
"react": "16.0.0",
"react-native": "0.51.0"
},
"devDependencies": {
"babel-jest": "22.0.4",
"babel-preset-react-native": "4.0.0"
}
}
运行npm install
Seup cocoapods
cd ios
-
pod init(生成 Podfile)
- 在 MyApp 目标的 Podfile 中声明 react 依赖项
pod 'React', :path => '../node_modules/react-native', :subspecs => [
'Core',
'CxxBridge',
'RCTAnimation',
'RCTBlob',
'RCTText',
'RCTNetwork',
'RCTWebSocket',
'RCTImage',
'RCTLinkingIOS',
'DevSupport',
]
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'
您可以添加/删除 React 子规范以包含/删除 RN 功能,这是一个艰难的过程,因为 RN 组件不是完全独立的。
-
pod install(将pods集成到项目中,将创建MyApp.xcworkspace,它应该用于编译应用程序)
-
open MyApp.xcworkspace,构建并运行,应用应该仍然可以工作
嵌入 RN 根视图
用这个 sn-p 替换你的 AppDelegate.m:
#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#if RCT_DEV
#import <React/RCTDevLoadingView.h>
#endif
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
RCTBundleURLProvider* provider = [RCTBundleURLProvider sharedSettings];
NSURL* jsCodeLocation = [provider jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:jsCodeLocation moduleProvider:nil launchOptions:launchOptions];
#if RCT_DEV
[bridge moduleForClass:[RCTDevLoadingView class]];
#endif
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"MyApp" initialProperties:@{}];
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
- 向 Info.plist 添加 ATS 异常(否则 MyApp 将无法使用 http 连接到打包服务器)
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
- 在模拟器中编译并运行,您应该会看到带有“没有捆绑 URL 存在”消息的红屏。 (这是因为没有打包服务器在运行,也没有编译好的 jsbundle)
Javascript 部分
使用此代码创建MyApp/index.js(来自RN模板):
import { AppRegistry } from 'react-native';
import App from './App';
AppRegistry.registerComponent('MyApp', () => App);
创建MyApp/App.js:
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
});
- 从根项目文件夹 (
MyApp) 启动打包程序 npm start
- 从 xcode 运行应用程序,您应该会看到加载指示器,然后 RN 呈现屏幕并显示“欢迎使用 React Native!”
打包器
- 您还应该添加打包程序构建步骤以将编译后的 js 嵌入到应用程序包
main.jsbundle,这样它就可以在没有打包程序开发服务器的情况下运行。
使用此内容将脚本步骤添加到 MyApp 目标的构建阶段:
export NODE_BINARY=node
../node_modules/react-native/scripts/react-native-xcode.sh
这个步骤对我有用。