欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2023年07月12日 10:41:33   作者:Grewer  
這篇文章主要為大家介紹了React?Native與iOS?OC之間的交互示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前置準(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è) module
RCT_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 端寫入:

// 重寫 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)的事件名稱
- (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 中的使用,類似于 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)程什么的,如果想寫橋接方法,這個(gè)也會(huì)碰到很多,不過(guò)掌握了上面這些,對(duì)于一些三方 SDK 的調(diào)用是夠用了

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

相關(guān)文章

  • React-Native實(shí)現(xiàn)ListView組件之上拉刷新實(shí)例(iOS和Android通用)

    React-Native實(shí)現(xiàn)ListView組件之上拉刷新實(shí)例(iOS和Android通用)

    本篇文章主要介紹了React-Native實(shí)現(xiàn)ListView組件之上拉刷新實(shí)例(iOS和Android通用),具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-07-07
  • React事件綁定的方式詳解

    React事件綁定的方式詳解

    react事件綁定時(shí)。this并不會(huì)指向當(dāng)前DOM元素。往往使用bind來(lái)改變this指向,今天通過(guò)本文給大家介紹React事件綁定的方式,感興趣的朋友
    2021-07-07
  • 用react實(shí)現(xiàn)一個(gè)簡(jiǎn)單的scrollView組件

    用react實(shí)現(xiàn)一個(gè)簡(jiǎn)單的scrollView組件

    這篇文章主要給大家介紹一下如何用 react 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 scrollView組件,文中有詳細(xì)的代碼示例,具有一定的參考價(jià)值,需要的朋友可以參考下
    2023-07-07
  • react中常見(jiàn)hook的使用方式

    react中常見(jiàn)hook的使用方式

    這篇文章主要介紹了react中常見(jiàn)hook的使用方式與區(qū)別,幫助大家更好的理解和學(xué)習(xí)使用react,感興趣的朋友可以了解下
    2021-04-04
  • React Hooks中模擬Vue生命周期函數(shù)的指南

    React Hooks中模擬Vue生命周期函數(shù)的指南

    React Hooks 提供了一種在函數(shù)組件中使用狀態(tài)和其他 React 特性的方式,而不需要編寫類組件,Vue 的生命周期函數(shù)和 React Hooks 之間有一定的對(duì)應(yīng)關(guān)系,本文給大家介紹了React Hooks中模擬Vue生命周期函數(shù)的指南,需要的朋友可以參考下
    2024-10-10
  • ReactJs快速入門教程(精華版)

    ReactJs快速入門教程(精華版)

    React 起源于 Facebook 的內(nèi)部項(xiàng)目,因?yàn)樵摴緦?duì)市場(chǎng)上所有 JavaScript MVC 框架,都不滿意,就決定自己寫一套,用來(lái)架設(shè) Instagram 的網(wǎng)站.這篇文章主要介紹了ReactJs快速入門教程(精華版)的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • react+tsx中使用better-scroll詳解

    react+tsx中使用better-scroll詳解

    這篇文章主要介紹了react+tsx中使用better-scroll,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • 原生+React實(shí)現(xiàn)懶加載(無(wú)限滾動(dòng))列表方式

    原生+React實(shí)現(xiàn)懶加載(無(wú)限滾動(dòng))列表方式

    這篇文章主要介紹了原生+React實(shí)現(xiàn)懶加載(無(wú)限滾動(dòng))列表方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • React使用React.lazy和Suspense實(shí)現(xiàn)組件懶加載

    React使用React.lazy和Suspense實(shí)現(xiàn)組件懶加載

    React 提供了 React.lazy 和 Suspense 這兩個(gè)好東西,能讓我們實(shí)現(xiàn)組件的懶加載,下面就跟隨小編一起來(lái)了解一下如何使用它們實(shí)現(xiàn)懶加載的具體步驟吧
    2025-03-03
  • 詳解React如何獲取狀態(tài)的舊值

    詳解React如何獲取狀態(tài)的舊值

    最近剛開(kāi)始接觸 React,突然腦海出現(xiàn)一個(gè)問(wèn)題,React中怎么在狀態(tài)更新時(shí)獲取它的舊值,特別是如果你之前用過(guò) Vue,你可能會(huì)想知道 React 中有沒(méi)有類似 Vue 的 watch 屬性,那么react中怎么實(shí)現(xiàn)呢?本文就給大家介紹一下React如何獲取狀態(tài)的舊值,需要的朋友可以參考下
    2024-07-07

最新評(píng)論