iOS React Native 学习总结

一、简单介绍

不同于Hybrid ap,React Native里面没有webview,iOS7中加入了JavaScriptCore.framework框架,而RN正是用JavascriptCore执行js代码的。

二、环境配置

需要安装Watchman Flow Node环境,推荐使用Homebrew,注意Xcode版本不能低于7.0

brew install node Node安装

brew install

watchmanbrew install

flowbrew update && brew upgrade 环境更新

三、工程创建

国内需要换源

npm config set registry https://registry.

npm.taobao.orgnpm config set disturl https://npm.taobao.org/dist

执行以下两条命令安装全局npm环境和初始化工程RNDEMO

$ sudo npm install -g react-native-cli

$ react-native init RNDemo

cd到工程根目录中用npm start(如果开启了自动启动调试服务器则不需要)启动服务,然后运行工程

集成RN环境到Native中

1.拷贝node_modules环境到工程中

2.将需要的.xcodeproj文件添加到工程中Alt text


3.点击 项目>Targets>Bulid Phases>Link Binary With Libraries添加对应的静态库Alt text


4.点击 项目>Targets>Bulid Settings>Search Paths>Header Search Paths注册React.xcodeproj文件路径Alt text


5.因为静态库里面可能有Category 所以需要在项目>Targets>Build Settings -> other linker flags 中加入-ObjC或者-all_loadAlt text


四、RN在工程用的一些应用

关于原生组件

  RN能用JS方便地调用官方封装的组件来加大开发效率,但是一些个性化或者js不太方便的东西还是需要native实现,于是需要native提供一些原生组件来完善。这主要分为两类,Module类和View类

1.Module类需要导入头文件#import "RCTBridgeModule.h"并遵守RCTBridgeModule协议

2.view类由ViewManager类管理,ViewManager需要导入头文件#import "RCTViewManager.h"并继承至RCTViewManager,遵守RCTBridgeModule协议并实现- (UIView *)view方法return view;即为自定义组件。

  两种类都需要实现 RCT_EXPORT_MODULE(js_name) 协议宏,js_name是js调用该类名称,缺省情况下截取类所在文件名,一个类所在文件被引用时,系统会调用其+(void)load函数,当RCT_EXPORT_MODULE()所在文件被引用时,系统调用load 函数,函数里简单的调用RCTRegisterModule(self) 把自己注册到一个全局数组RCTModuleClasses,这样系统中导出的类都会自动注册到这个全局变量数组里

void RCTRegisterModule(Class moduleClass)

{

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

RCTModuleClasses = [NSMutableArray new];

});

RCTAssert([moduleClass conformsToProtocol:@protocol(RCTBridgeModule)], @"%@ does not conform to the RCTBridgeModule protocol", moduleClass);

// Register module

[RCTModuleClasses addObject:moduleClass];

}

属性导出

  RN可以向Native传递多种参数,可以以这些支持的类型传递数据native组件用`EXPORT_VIEW_PROPERTY(<#name#>, <#type#>)`来导出类的属性,js传递数据会调用相应的set方法,native可以在set方法里面做些逻辑和数据处理。支持字符串NSString,NSArray数组,基本数据类型,NSnumeber,NSDictionary字典等,自定义类型,并在RCTCovert中,重定义了如下几种数据类型来处理一些泛型

typedef NSArray NSArrayArray __deprecated_msg("Use NSArray");typedef NSArray NSStringArray __deprecated_msg("Use NSArray");typedef NSArray NSStringArrayArray __deprecated_msg("Use NSArray");

typedef NSArray NSDictionaryArray __deprecated_msg("Use NSArray");

typedef NSArray NSURLArray __deprecated_msg("Use NSArray");

typedef NSArray RCTFileURLArray __deprecated_msg("Use NSArray");

typedef NSArray NSNumberArray __deprecated_msg("Use NSArray");

typedef NSArray UIColorArray __deprecated_msg("Use NSArray");

枚举类型用RCT_ENUM_CONVERTER(type, values, default, getter)导出

例如:

RCT_ENUM_CONVERTER(UIActivityIndicatorViewStyle, (@{

@"large": @(UIActivityIndicatorViewStyleWhiteLarge),

@"small": @(UIActivityIndicatorViewStyleWhite),

}), UIActivityIndicatorViewStyleWhiteLarge, integerValue)

values为字典类型,default在js传递数据为空时候使用

方法导出

RCT_EXPORT_METHOD(<#method#>)可导出方法,js通过注册到全局数组RCTModuleClasses中的实例来调用方法

RCT_EXPORT_METHOD(getCurrentVersion:(RCTResponseSenderBlock)callback)

{

NSString *events = [self appVersion];

callback(@[events]);

}

Nativ模块实现

       React Native 在一个单独的串行 GCD 队列中调用 native 模块方法,如果 native 模块需要调用 main-thread-only iOS API例如刷新UI,push viewController 应该在主队列操作:

-(void)whatYouWantTodo{

dispatch_async(dispatch_get_main_queue(), ^{

coding......

}}

Block回调

对应属性导出,native也可以向js传递数据,RCTBridgeMethod中定义了一个block typedef void (^RCTResponseSenderBlock)(NSArray *response);用来返回数据给js。

发送事件到 JavaScript

RCTEventDispatcher类中定义了一些事件处理方法

例如Native 模块可以在不被直接调用的情况下向 JavaScript 发送事件信号

- (void)calendarEventReminderReceived:(NSNotification *)notification

{

NSString *eventName = notification.userInfo[@"name"];

[self.bridge.eventDispatcher sendAppEventWithName:@"EventReminder"

body:@{@"name": eventName}];

}

JavaScript 代码可以订阅这些事件:

var subscription = DeviceEventEmitter.addListener(

'EventReminder',

(reminder) => console.log(reminder.name)

);

tips:js需要移除订阅事件

subscription.remove();

五、简单提提JavaScriptCore

OC调用js

-(void)webViewDidFinishLoad:(UIWebView *)webView

{

//网页加载完成调用此方法

//首先创建JSContext 对象(此处通过当前webView的键获取到jscontext)

JSContext *context=[webView valueForKeyPath: @"documentView.webView.mainFrame.javaScriptContext"];

NSString *alertJS=@"alert('超哥你好,大河向东流')"; //准备执行的js代码

[context evaluateScript:alertJS];//通过oc方法调用js的alert

}

效果如下:


block中JSContext注意防止循环引用,

用[JSContext currentContext]

JSContext *context1 = [[JSContext alloc] init];

context1[@"callback"] = ^{

JSValue *object = [JSValue valueWithNewObjectInContext:[JSContext currentContext]];

object[@"one"] = @(1);

object[@"two"] = @(2);

return object;

};

JSValue内存泄漏

JS中对象为弱类型,OC中为强类型直接保存会内存泄漏

- (void)setOnClickHandler:(JSValue *)handler

{

_onClickHandler = [JSManagedValue managedValueWithValue:handler];

[_context.virtualMachine addManagedReference:_onClickHandler

withOwner:self]

}

资料参考:

JavaScriptCore的使用和消息传递

JavaScriptCore与内存管理

React Native官方文档中文

通讯以及消息循环

知识浅薄,如有错漏,敬请指正

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

推荐阅读更多精彩内容