电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

React?Native與iOS?OC之間的交互示例詳解

瀏覽:28日期:2022-06-13 08:12:45
目錄前置準(zhǔn)備RN 傳值給 iOS方法 1 正常傳值給原生方法 2 傳遞回調(diào)函數(shù)方法 3 獲取 promise 回調(diào)方法 3 獲取 promise 的同步方式iOS 傳值給 RN 端初始的數(shù)據(jù)提供添加監(jiān)聽(tīng)事件總結(jié)前置準(zhǔn)備

首先最好了解一點(diǎn)關(guān)于 oc 的語(yǔ)法知識(shí),不然很多都是看不懂的

創(chuàng)建聲明文件 nativeModule.h

#import <Foundation/Foundation.h>#import <React/RCTBridgeModule.h>@interface nativeModule : NSObject <RCTBridgeModule>@end

創(chuàng)建文件 nativeModule.m

#import <Foundation/Foundation.h>#import 'nativeModule.h'@interface nativeModule ()@end@implementation nativeModule@end

這是添加完文件后的結(jié)構(gòu)目錄

關(guān)于 interface 的區(qū)別:.h里面的@interface,它是供其它Class調(diào)用的。它的@property和functions,都能夠被其它Class“看到”(public)

而.m里面的@interface,在OC里叫作Class Extension,是.h文件中@interface的補(bǔ)充。但是.m文件里的@interface,對(duì)外是不開(kāi)放的,只在.m文件里可見(jiàn)(private)

因此,我們將對(duì)外開(kāi)放的方法、變量放到.h文件中,而將不想要對(duì)外開(kāi)放的變量放到.m文件中(.m文件的方法可以不聲明,直接用)。

RN 傳值給 iOS方法 1 正常傳值給原生

在 .m 文件中添加方法:

// 省略上面的代碼@implementation nativeModule// 這句代碼是必須的 用來(lái)導(dǎo)出 module, 這樣才能在 RN 中訪問(wèn) nativeModule這個(gè) moduleRCT_EXPORT_MODULE();// 接收字符串RCT_EXPORT_METHOD(addHelloWord:(NSString *)name location:(NSString *)location){ NSLog(@'%@,%@', name, location);}@end

RN 代碼:

import { Button, NativeModules } from 'react-native'const { nativeModule } = NativeModules<Button title={'傳 2 個(gè)參數(shù)給 native'} onPress={() => { nativeModule.addHelloWord('你的名字', '位置:浙江')}}/>

點(diǎn)擊此按鈕的作用,就是將 '你的名字', '位置:浙江' 這 2 個(gè)字符串傳遞到了原生端

方法 2 傳遞回調(diào)函數(shù)

在 .m 文件中添加:

// 只接受一個(gè)參數(shù)——傳遞給 JavaScript 回調(diào)函數(shù)的參數(shù)數(shù)組。RCT_EXPORT_METHOD(checkIsRoot:(RCTResponseSenderBlock)callback) { NSArray *array = @[@'string', @'number']; callback(array);}

在 RN 中添加代碼:

<Button title={'js 傳一個(gè)回調(diào)給 native,回調(diào)中收到一個(gè)數(shù)組'} onPress={() => { nativeModule.checkIsRoot((str: string, num: string) => { console.log(str, num) })}}/>

這是在 RN 中 給原生端傳遞了一個(gè)回調(diào)函數(shù),用來(lái)解決,部分操作完成后的回調(diào), 如果 callback 多次調(diào)用 RN 會(huì)報(bào)錯(cuò)

方法 3 獲取 promise 回調(diào)

在 .m 文件中添加代碼:

@interface nativeModule ()@property (nonatomic) RCTPromiseResolveBlock normalResolve;@property (nonatomic) RCTPromiseRejectBlock normalReject;@property (nonatomic) NSInteger num;@end// 這是一個(gè)計(jì)時(shí)器-(void)startTime: (NSArray*) data{ NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2 repeats:YES block:^(NSTimer * _Nonnull timer) { NSArray *events =@[@'Promise ',@'test ',@' array']; if (events) { self.normalResolve(events); [timer invalidate]; } else { [timer invalidate]; NSError *error=[NSError errorWithDomain:@'我是回調(diào)錯(cuò)誤信息...' code:101 userInfo:nil]; self.normalReject(@'no_events', @'There were no events', error); } }]; [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];}// 回調(diào)給RN的參數(shù),回調(diào)的錯(cuò)誤信息RCT_EXPORT_METHOD(getHBDeviceUniqueID: (RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { // 要執(zhí)行的任務(wù) self.normalResolve = resolve; self.normalReject = reject; [self performSelectorOnMainThread:@selector(startTime:) withObject: [NSArray arrayWithObjects: @'1', @'2', nil] waitUntilDone:YES];}

在 RN 中添加代碼:

<Button title={'native傳一個(gè) promise 給 JS'} onPress={() => { nativeModule.getHBDeviceUniqueID().then((arr: string[]) => { console.log('resolve', arr) }).catch((err: string) => { console.error(err) })}}/>

nativeModule.getHBDeviceUniqueID 的執(zhí)行他是一個(gè) promise,可以獲取原生端的回調(diào), 其實(shí)和方法 2 差不多

方法 3 獲取 promise 的同步方式

在 .m 文件中添加:

// 這是一個(gè)計(jì)時(shí)器2-(void)startTime2: (NSArray*) data{ NSLog(@'data%@',data); NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) { NSLog(@'%d', (int)self.num); self.num = self.num + 1; NSLog(@'%d', (int)self.num); if (self.num > 4) { [timer invalidate]; NSLog(@'end'); self.normalResolve(data); } }]; [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];}// RCT_REMAP_METHOD 與RCT_EXPORT_METHOD相同,但是該方法是在JS線程上從JS同步調(diào)用的,可能會(huì)返回結(jié)果。// 同步可能會(huì)有性能問(wèn)題 建議除了 promise 以外都別使用RCT_REMAP_METHOD(findEvents, findEventsWithResolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){ self.normalResolve = resolve; self.normalReject = reject; self.num = 0; [self performSelectorOnMainThread:@selector(startTime2:) withObject: [NSArray arrayWithObjects: @'1', @'2', nil] waitUntilDone:YES];}

在 RN 端添加代碼:

<Button title={'native傳一個(gè) promise 給 JS2'} onPress={() => { nativeModule.findEvents().then((arr: string[]) => { console.log('resolve', arr) }).catch((err: string) => { console.error(err) })}}/>

方法 4 和方法 3 大體一致,但是有一點(diǎn)不同,就是 RCT_REMAP_METHOD 使用此方法會(huì)將代碼變成同步狀態(tài)

iOS 傳值給 RN 端初始的數(shù)據(jù)提供

在 appDelegate.m 文件中添加代碼:

NSArray *imageList = @[@'http://foo.com/bar1.png',@'http://foo.com/bar2.png'];NSDictionary *props = @{@'images' : imageList};RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@'learn' initialProperties:props];// 這一行代碼原本就有,不同點(diǎn)在于 initialProperties:props

在 RN 端寫(xiě)入:

// 重寫(xiě) APP , images就是 iOS 提供的數(shù)據(jù),這里我們通過(guò) context 來(lái)傳遞數(shù)據(jù)export default class App extends React.Component<{ images: string[] }> { render() { return <NativeProps.Provider value={this.props.images}> <AppContainer/> </NativeProps.Provider> }}// 在 hooks 里簡(jiǎn)單的使用const images = useContext(NativeProps);<Text>這是從 native 端傳來(lái)的初始數(shù)據(jù){JSON.stringify(images)}</Text>添加監(jiān)聽(tīng)事件

在 .m 文件中添加代碼:

// 可供監(jiān)聽(tīng)的事件名稱(chēng)- (NSArray<NSString *> *)supportedEvents{ return @[@'EventReminder'];}RCT_EXPORT_METHOD(postNotificationEvent:(NSString *)name){ NSLog(@'calendarEventReminderReceived'); [self sendEventWithName:@'EventReminder' body:@{@'name': name}];;}- (void)calendarEventReminderReceived:(NSNotification *)notification{ // 這是官網(wǎng)的例子 NSLog(@'calendarEventReminderReceived'); NSString *eventName = notification.userInfo[@'name']; [self sendEventWithName:@'EventReminder' body:@{@'name': eventName}];}RCT_EXPORT_METHOD(Send){ NSDictionary *dict = @{@'name' : @'veuimyzi'}; NSNotification *notification = [[NSNotification alloc] initWithName:@'EventReminder' object:nil userInfo:dict] ; [self calendarEventReminderReceived:notification];}

在 RN 中添加代碼:

const ManagerEmitter = new NativeEventEmitter(nativeModule)const [msg, setMsg] = useState([])// hooks 中的使用,類(lèi)似于 componentDidMount 生命周期useEffect(() => { const subscription = ManagerEmitter.addListener( 'EventReminder', (reminder) => {setMsg(prevState => { return prevState.concat(reminder.name)})console.log('這是監(jiān)聽(tīng)的EventReminder事件回復(fù)', reminder.name) } ) return () => { subscription.remove() }}, [])<Button title={'js 監(jiān)聽(tīng)事件,讓 native 給 js 發(fā)通知'} onPress={() => { nativeModule.postNotificationEvent('test')}}/><Button title={'js 監(jiān)聽(tīng)事件,讓 native 給 js 發(fā)通知 send'} onPress={() => { nativeModule.Send()}}/>{ msg.map((item, index) => { return <Text key={item + index}>item:{item}</Text> })}

關(guān)于 postNotificationEvent 方法是屬于最簡(jiǎn)單的使用, 在原生端調(diào)用 sendEventWithName 就可以傳遞數(shù)據(jù)給 RN 的監(jiān)聽(tīng)

而另一個(gè)方法 Send 和 calendarEventReminderReceived ,一個(gè)是來(lái)自于官網(wǎng)的實(shí)例 講的是從 NSNotification獲取數(shù)據(jù), Send 是傳遞數(shù)據(jù)給 calendarEventReminderReceived

關(guān)于監(jiān)聽(tīng)的優(yōu)化, 這個(gè)官網(wǎng)上也有,有空可以看下,就是在 .m 文件中添加下列代碼:

@implementation nativeModule{ bool hasListeners; // 一個(gè)局部變量}-(void)startObserving { hasListeners = YES;}-(void)stopObserving { hasListeners = NO;}// 在發(fā)送監(jiān)聽(tīng)的添加判斷,如果有監(jiān)聽(tīng)才發(fā)送,有效減少橋接代碼的調(diào)用if (hasListeners) { [self sendEventWithName:@'EventReminder' body:@{@'name': name}];;}總結(jié)

上述代碼的庫(kù): https://github.com/Grewer/lea...

關(guān)于原生端和 RN 端的交互基本就是這些了,當(dāng)然原生端還有更多,更復(fù)雜的操作,比如進(jìn)程什么的,如果想寫(xiě)橋接方法,這個(gè)也會(huì)碰到很多,不過(guò)掌握了上面這些,對(duì)于一些三方 SDK 的調(diào)用是夠用了

以上就是React Native與iOS OC之間的交互示例詳解的詳細(xì)內(nèi)容,更多關(guān)于React Native與iOS OC交互的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: JavaScript
主站蜘蛛池模板: 座椅式升降机_无障碍升降平台_残疾人升降平台-南京明顺机械设备有限公司 | 河南橡胶接头厂家,河南波纹补偿器厂家,河南可曲挠橡胶软连接,河南套筒补偿器厂家-河南正大阀门 | 深圳善跑体育产业集团有限公司_塑胶跑道_人造草坪_运动木地板 | 欧必特空气能-商用空气能热水工程,空气能热水器,超低温空气源热泵生产厂家-湖南欧必特空气能公司 | 济南侦探调查-济南调查取证-山东私家侦探-山东白豹调查咨询公司 密集架|电动密集架|移动密集架|黑龙江档案密集架-大量现货厂家销售 | 领袖户外_深度旅游、摄影旅游、小团慢旅行、驴友网 | 广东燎了网络科技有限公司官网-网站建设-珠海网络推广-高端营销型外贸网站建设-珠海专业h5建站公司「了了网」 | 哈希余氯测定仪,分光光度计,ph在线监测仪,浊度测定仪,试剂-上海京灿精密机械有限公司 | 纯化水设备-EDI-制药-实验室-二级反渗透-高纯水|超纯水设备 | 热处理温控箱,热处理控制箱厂家-吴江市兴达电热设备厂 | 短信营销平台_短信群发平台_106短信发送平台-河南路尚 | 学生作文网_中小学生作文大全与写作指导| 北京租车公司_汽车/客车/班车/大巴车租赁_商务会议/展会用车/旅游大巴出租_北京桐顺创业租车公司 | 扬州汇丰仪表有限公司| 硫化罐_蒸汽硫化罐_大型硫化罐-山东鑫泰鑫智能装备有限公司 | 检验科改造施工_DSA手术室净化_导管室装修_成都特殊科室建设厂家_医疗净化工程公司_四川华锐 | 芝麻黑-芝麻黑石材厂家-永峰石业 | 防渗土工膜|污水处理防渗膜|垃圾填埋场防渗膜-泰安佳路通工程材料有限公司 | 细石混凝土泵_厂家_价格-烟台九达机械有限公司 | 青岛球场围网,青岛车间隔离网,青岛机器人围栏,青岛水源地围网,青岛围网,青岛隔离栅-青岛晟腾金属制品有限公司 | 东莞动力锂电池保护板_BMS智能软件保护板_锂电池主动均衡保护板-东莞市倡芯电子科技有限公司 | 干洗加盟网-洗衣店品牌排行-干洗设备价格-干洗连锁加盟指南 | 口信网(kousing.com) - 行业资讯_行业展会_行业培训_行业资料 | 昆明网络公司|云南网络公司|昆明网站建设公司|昆明网页设计|云南网站制作|新媒体运营公司|APP开发|小程序研发|尽在昆明奥远科技有限公司 | 微信聊天记录恢复_手机短信删除怎么恢复_通讯录恢复软件下载-快易数据恢复 | 安徽合肥项目申报咨询公司_安徽合肥高新企业项目申报_安徽省科技项目申报代理 | 泰国试管婴儿_泰国第三代试管婴儿费用|成功率|医院—新生代海外医疗 | 地源热泵一体机,地源热泵厂家-淄博汇能环保设备有限公司 | 砂尘试验箱_淋雨试验房_冰水冲击试验箱_IPX9K淋雨试验箱_广州岳信试验设备有限公司 | 选矿设备-新型重选设备-金属矿尾矿重选-青州冠诚重工机械有限公司 | 石家庄网站建设|石家庄网站制作|石家庄小程序开发|石家庄微信开发|网站建设公司|网站制作公司|微信小程序开发|手机APP开发|软件开发 | 双能x射线骨密度检测仪_dxa骨密度仪_双能x线骨密度仪_品牌厂家【品源医疗】 | 长信科技产业园官网_西安厂房_陕西标准工业厂房 | 专注提供国外机电设备及配件-工业控制领域一站式服务商-深圳市华联欧国际贸易有限公司 | 道康宁消泡剂-瓦克-大川进口消泡剂供应商 | 水冷式工业冷水机组_风冷式工业冷水机_水冷螺杆冷冻机组-深圳市普威机械设备有限公司 | 编织人生 - 权威手工编织网站,编织爱好者学习毛衣编织的门户网站,织毛衣就上编织人生网-编织人生 | 布袋除尘器|除尘器设备|除尘布袋|除尘设备_诺和环保设备 | 微型气泵-真空-蠕动-水泵-厂家-深圳市品亚科技有限公司 | 薪动-人力资源公司-灵活用工薪资代发-费用结算-残保金优化-北京秒付科技有限公司 | 黑田精工电磁阀-CAMMOZI气缸-ROSS电磁-上海茂硕机械设备有限公司 |