【React Native】React Native 移植原生iOS平台

【React Native】React Native 移植原生iOS平台

主要命令:

  (JS_DIR=`pwd`/ReactComponent; cd Pods/React/packager;  node packager.js  --root $JS_DIR)

(一)前言

今天我们来看一下React Native移植到iOS原生应用,通过本节讲解,相信大家对于正在开发的iOS原生项目就可以移植到React Native平台中来,或者采取原生加RN混合开发模式啦。

(二)准备工作

1.安装CocoaPods -这个相应大家如果之前做过iOS开发应该都清除的吧。安装命令:gem install cocoapods 注意如果出现安装权限问题,可以运行sudo gem install cocoapods命令

2.Node.js -如果大家已经在Mac平台已经成功运行过React Native应用,那么该肯定是安装了(没安装,点击进入了解)。安装nvm的教程点击命令,该命令会进行安装最新的Node.js版本,然后配置好环境变量。最后你可以通过命令node来启动运行Node.js环境。大家可能也知道,通过nvm,大家可以安装多个Node.js版本并且很方便的进行切换选择。

3.间接着,你可以命令切换到你的项目的根目录,命令运行npm install react-native来进行安装react-native包依赖。

以上步骤完成之后,在你项目根目录上面会存在一个React Native包,该命名为node_modules,和.xcodeproj文件平级。

(三)使用CocoaPods进行安装React Native库

CocoaPods是iOS/Mac开发中的包管理器,我们需要使用CocoaPods来进行下载React Native。如果你到现在还没有安装CocoaPods,那么请点击了解安装向导 ,至于具体怎么样安装相信大家看官方向导或者百度一下,就会了。

当你用CocoaPods进行工作的时候,需要往Podfile文件中添加如下的一些代码信息。如果你还没有该文件,可以在项目的根目录上面进行创建一下。具体需要添加的信息如下:


# Depending on how your project is organized, your node_modules directory may be
# somewhere else; tell CocoaPods where you've installed react-native from npm
pod 'React', :path => './node_modules/react-native', :subspecs => [
  'Core',
  'RCTImage',
  'RCTNetwork',
  'RCTText',
  'RCTWebSocket',
  # Add any other subspecs you want to use in your project
]

记住需要添加安装所有的组件模块依赖才可以,例如如果你需要使用<Text>元素,但是如果没有安装RCTText,那么不行啦。

然后运行命令进行安装: pod install

(四)创建React Native应用

下面你两个注意步骤:

1.应用的入口/根JavaScript文件必须包含你的实际React Native应用和其他组件

2.封装Objective-C代码,加载你的脚本代码和创建一个RCTRootView对象来显示和管理你的React Native组件。

现在我们开始创建啦:

首先创建一个文件夹来存放应用的React代码,然后新建一个简单的index.ios.js文件,具体命令如下:

$ mkdir ReactComponent
$ touch ReactComponent/index.ios.js

复制和粘贴如下的代码到index.ios.js文件中,这是一个最简单的React Native应用啦;

'use strict';


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


conststyles = React.StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'red'
  }
});


class SimpleApp extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>This is a simple application.</Text>
      </View>
    )
  }
}


React.AppRegistry.registerComponent('SimpleApp', () => SimpleApp);

上面代码中的SimpeApp就是你的模块名称,该名称请记住,后边需要用到的哦~

(五)往应用中添加容器视图

现在你需要一个容器视图来转载React Native组件,该可以为你应用中任何的UIView。

当然了,为了我们的代码更加整洁干净,我们创建一个继承UIView的ReactView。你点击YourProject.xcworkspace(具体你本地的项目),然后创建一个新的类ReactView(当然你可以随你自己喜欢进行命名…)

// ReactView.h


#import <UIKit/UIKit.h>
@interface ReactView : UIView
@end

然后在需要管理这个视图的ViewController中,添加关联。

// ViewController.m

@interface ViewController ()
@property (weak, nonatomic) IBOutlet ReactView *reactView;
@end

[注意].如果你的是Swift应用,就不需要这一步。同时这边我为了简化的演示相关效果,已经禁用了AutoLayout了,但是在实际的开发中,那么就需要打开AutoLayout并且设置相关约束。

(六)往容器视图中添加RCTRootView

前面我们已经做了好多准备工作了,那么现在重点来了,最后在确定一遍,你准备好了没?现在我们需要来创建RCTRootView来引入React Native应用了。

在ReactView.m文件中,我们首先需要加载index.ios.bundle文件来初始化RCTRootView, index.ios.bundle文件会由React Native Server进行创建并且可以通过React Native服务访问到。这个我们之后的教程会讲解到啦。

NSURL *jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios"];
// For production use, this `NSURL` could instead point to a pre-bundled file on disk:
//
//  NSURL *jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
//
// To generate that file, run the curl command and add the output to your main Xcode build target:
//
//  curl http://localhost:8081/index.ios.bundle -o main.jsbundle
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                    moduleName: @"SimpleApp"
                                            initialProperties:nil
                                                launchOptions:nil];

然后把它添加成ReactView的子视图

[self addSubview:rootView];
rootView.frame = self.bounds;

(七)Swift应用

如果你的是Swift应用的话,那么需要你在ReactView.swift文件中添加如下代码:

import UIKit
import React


class ReactView: UIView {


 let rootView: RCTRootView = RCTRootView(bundleURL: NSURL(string: "http://localhost:8081/index.ios.bundle?platform=ios"),
   moduleName: "SimpleApp", initialProperties: nil, launchOptions: nil)


 override func layoutSubviews() {
   super.layoutSubviews()


   loadReact()
 }


 func loadReact () {
       addSubview(rootView)
       rootView.frame = self.bounds
 }
}

最后你需要确定一下你的该视图有没有添加到视图容器中或者故事板文件中(StoryBoard)

(八)启动开发服务器

在项目根目录中,我们需要开启React Native开发服务器,具体命令如下:(一般教程用)

(JS_DIR=pwd/ReactComponent;cd node_modules/react-native; npm run start -- --root $JS_DIR)

注意:上面的命令可能不生效用这个命令👇

(JS_DIR=`pwd`/ReactComponent; cd Pods/React/packager;  node packager.js  --root $JS_DIR)

以上的命令,可以开启React Native开发服务,来构建我们的bundle文件。--root选项用来标注React Native应用所在的根目录。我们当前的例子是ReactComponents目录,在该文件夹中有一个index.ios.js文件。服务器启动之后会进行打包出来index.ios.bundle文件,然后让我们可以通过http://localhost:8081/index.ios.bundle进行访问。

(九)更新App Transport Security

在iOS9.0开始或者更高版本的系统中,除非特别配置,否则我们的应用是不能通过http访问localhost主机服务器的。具体解决方案可以查看:http://stackoverflow.com/questions/31254725/transport-security-has-blocked-a-cleartext-http

解决方案:推荐大家在应用的Info.plist文件作如下修改,把localhost本机访问排查例外项。

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

如果大家没有这样做,那么可能会遇到Could not connect to development server的错误哦

(十)编译和运行

现在开始编译和运行你的应用,你会发现你的React Native应用运行在ReactView视图容器中了,具体截图如下

注意在模拟器调试中我们可以实现热加载的(只要修改了JS代码,模拟器页面自动刷新的效果,确保在Build Settings->Preprocessor Macros中设置DEBUG=1)

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

推荐阅读更多精彩内容