Swift已有项目手动集成ReactNative

000

背景

记得2017年初写过一篇公司放弃RN血泪史的经历,当时之所以放弃时因为前期投入过多人力物力研究,以至于第一版本耗时太多未见成效,所有被老板叫停。真是"常在河边走哪有不湿鞋"最近因为苹果审核的问题,我们又在找寻及时更新的方案。之所以选择ReactNative是看好了它能与CodePush结合实现热更新的功能。

最近大前端的趋势越来越火,跨平台方案也层出不穷从ReactNativeWeex再到这两天风靡一世的Flutter,可真是想感叹一声“md,RN我还没学会,Flutter又来了!”。

大家也不要杞人忧天,选择了这个行业就不要害怕学习,RN也就是学学NodeJSCSSJavaScriptJSXReactReactNativeNative等那么多。

正文

如果单纯创建一个ReactNative项目很简单,大家按照官网的教程来就行了,今天主要讲讲在已有的Swift项目中集成ReactNative步骤,我一开始是使用CocoaPods集成的,发现各种坑,不是yoga找不到、glog找不到,就是各种版本不一致的错误。经过上网查阅各种资料后我选择了放弃,改成手动集成。

前提已经拥有了一个Swift项目,我们假设叫RNSwiftDemo,并搭建好了ReactNative开发环境。

1. 创建一个空目录

首先创建一个空目录,我们这里叫RNDemo,用于存放React Native项目.

2. 创建package.json文件

2.1 添加package.json

在项目根目录下创建一个名为package.json的空文件,然后填入以下内容:

{
  "name": "RNSwiftDemo",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "dependencies": {
    "react": "16.3.0-alpha.1",
    "react-native": "^0.54.2",
  }
}

在根目录执行以下命令npm install,执行完后会发现项目目录中多了一个node_modules文件夹,然后执行npm start命令。

1001.png
2.2 添加index.js

修改index.js文件如下:

import { 
  AppRegistry,
  Text,
  View,
} from 'react-native';
import React, { Component } from 'react';
class RNHomeView extends Component{
  render() {
    return (
      <View style={{backgroundColor:'white' }}>
        <Text style={{fontSize:20, marginTop:200}}>Hello World!</Text>
      </View>
    );
  }
}
class MyApp extends Component {
  render() {
      return <RNHomeView />; 
  }
}
AppRegistry.registerComponent('RNSwiftDemo', () => MyApp);

3. 配置Swift项目

**3.1 **把Rn项目中的node_modules文件夹拷贝到Swift项目根目录,如下:

1002.png

3.2在XCode中打开Swift项目,在RNSwiftDemo目录中创建一个RnLibs的Group

3.3 RnLibs中添加依赖的React Native项目。(不同的项目所添加的依赖库不同,需要自己甄别)

React Native依赖项目主要在node_modules/react-native/Libraries目录中和node_modules/react-native/React中的React.xcodeproj

添加依赖后的效果如下:

1003.png

1004.png

3.4添加依赖库

选择项目—Targes—RNSwiftDemo—BuildPhases—Link Binary With Libraries,把依赖项目生成的依赖库添加进去(注意不要选择from缀带‘-tvOs’的)

1006.png
1007.png

3.5 添加Header Search Path

1008.png

3.6 设置Other Linker Flag

在Build Settings中搜索【other link flags】,添加-ObjC-lc++

1009.png

4. Swift代码

4.1 创建Swift和OC混编的桥接头文件

如果原项目中有RNSwiftDemo-Bridging-Header.h类似这个文件可以跳过4.1。如果没有在项目中随便创建一个OC的文件,XCode会提示是否创建桥接头文件,点击创建就可以了,最后记得把无用的OC文件删掉。

1010.png

4.2 引用RN头文件

把一下代码粘贴到桥接头文件中

#import <React/RCTRootView.h>
#import <React/RCTBundleURLProvider.h>
#import "UIView+React.h"

4.3 添加RN页面

接下来我们准备在首页添加一个按钮,点击按钮跳转到RN页面。RN页面的Controller我们这里叫做“RnViewController”。下面在RnViewController添加如下代码

override func viewDidLoad() {
    super.viewDidLoad()
    let url = URL(string: "http://localhost:8081/index.bundle?platform=ios")!
    let rootView = RCTRootView(
        bundleURL: url,
        moduleName: "RNSwiftDemo",//这里的名字要和index.js中相同
        initialProperties: nil,
        launchOptions: nil
    )
    view = rootView
}

在Info.plist中添加如下配置,

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

5. 运行

如果npm未启动,先到RN项目中执行npm start。然后运行iOS项目就可以了,运行效果如下:

1011.png

遇到问题

1. 找不到React头文件

如果运行出现找不到React头文件(例如:React/RCTBridgeModule.h file not found)的情况,可以先选择React外部依赖项目build编译,然后再运行Swift项目。也可以按照下边介绍配置编译依赖:

1.1 Disable the parallel builds:

  • xCode menu -> Product -> Scheme -> Manage Shemes...
  • Double click on your application
  • Build tab -> clear the tick on Pallelize Build

1.2 Add react as a project dependecy

  • xCode Project Navigator -> drag React.xcodeproj from Libraries to root tree
  • Build Phases Tab -> Target Dependencies -> + -> add React

2. Undefined symbols for architecture x86_64: “std::terminate()”, referenced from

运行项目时Xcode报错。

解决办法:add -lc++ in Other Linker Flags in your xcode project build settings.

3. Invariant Violation:Application 项目名 has not been registered.

error1: Invariant Violation:Application 项目名 has not been registered.

这个错误的原因是index.ios.js 中的注册名,和代码中的引用名不同;
index.js 中

AppRegistry.registerComponent('RNSwiftDemo', () => MyApp);

Swift中:

let rootView = RCTRootView(
    bundleURL: url,
    moduleName: "RNSwiftDemo",
    initialProperties: nil,
    launchOptions: nil
 )

何去何从

作者也是ReactNative刚开始学习,熟悉后会分享下React、ReactNative开发相关知识,更多iOS、iOS逆向、ReactNative相关文章请关注微博或者微信公众账号:乐Coding。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • 娃娃们在草地上跑来跑去奶奶跟在后面阳光跟在后面玩具丢在后面爸爸等在前面 娃娃们在摇篮里转来转去树荫遮在上面妈妈站在...
    葺宝阅读 256评论 0 1
  • 2018刚刚开始,用G·K·切斯特顿的话说,新年的目的并非是拥有新的一年,而是拥有一个新的灵魂。 成长就是一个不断...
    珍藏一种风范阅读 162评论 0 0
  • 涛子跟女友最近都分分合合了无数回,每次都是他妥协告终,用他自己的话说 “一切都是我的错”。 这周他风尘...
    青梅3煮酒阅读 273评论 3 3
  • 只要你有耐心,时间就是你的朋友 每年春节,村里面才有一些人气。平时工作挺忙的,即使小时候的玩伴也没时间在一起聊聊天...
    米小哥阅读 209评论 0 0