跳至主要內容

iOS 原生模組

資訊

原生模組和原生元件是我們用於舊版架構的穩定技術。當新架構穩定後,它們將在未來被棄用。新架構使用 Turbo 原生模組Fabric 原生元件 來達成類似的結果。

歡迎使用 iOS 的原生模組。請先閱讀 原生模組簡介,了解原生模組的簡介。

建立行事曆原生模組

在以下指南中,您將建立一個原生模組,CalendarModule,它將允許您從 JavaScript 存取 Apple 的行事曆 API。最後,您將能夠從 JavaScript 呼叫 CalendarModule.createCalendarEvent('Dinner Party', 'My House');,呼叫一個建立行事曆事件的原生方法。

設定

首先,在 Xcode 中開啟 React Native 應用程式內的 iOS 專案。您可以在 React Native 應用程式中找到您的 iOS 專案

Image of opening up an iOS project within a React Native app inside of xCode.
您可以在哪裡找到 iOS 專案的圖片

我們建議使用 Xcode 編寫原生程式碼。Xcode 是為 iOS 開發而建,使用它將有助於您快速解決較小的錯誤,例如程式碼語法。

建立自訂原生模組檔案

第一步是建立我們的主要自訂原生模組標頭和實作檔案。建立一個名為 RCTCalendarModule.h 的新檔案

Image of creating a class called  RCTCalendarModule.h.
在與 AppDelegate 相同的資料夾中建立自訂原生模組檔案的圖片

並加入以下內容

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

您可以使用任何符合您正在建立的原生模組的名稱。將類別命名為 RCTCalendarModule,因為您正在建立一個行事曆原生模組。由於 ObjC 沒有像 Java 或 C++ 那樣的語言層級命名空間支援,因此慣例是在類別名稱之前加上子字串。這可能是您的應用程式名稱或基礎架構名稱的縮寫。在此範例中,RCT 指的是 React。

如下所示,CalendarModule 類別實作了 RCTBridgeModule 協定。原生模組是一個實作 RCTBridgeModule 協定的 Objective-C 類別。

接下來,讓我們開始實作原生模組。在同一個資料夾中建立對應的實作檔案 RCTCalendarModule.m,並包含以下內容

// RCTCalendarModule.m
#import "RCTCalendarModule.h"

@implementation RCTCalendarModule

// To export a module named RCTCalendarModule
RCT_EXPORT_MODULE();

@end

模組名稱

目前,您的 RCTCalendarModule.m 原生模組只包含一個 RCT_EXPORT_MODULE 巨集,它會匯出並向 React Native 註冊原生模組類別。RCT_EXPORT_MODULE 巨集也會接收一個選用引數,用來指定模組在 JavaScript 程式碼中可存取的名稱。

這個引數不是字串文字。在以下範例中,傳遞的是 RCT_EXPORT_MODULE(CalendarModuleFoo),而不是 RCT_EXPORT_MODULE("CalendarModuleFoo")

// To export a module named CalendarModuleFoo
RCT_EXPORT_MODULE(CalendarModuleFoo);

然後可以在 JS 中像這樣存取原生模組

const {CalendarModuleFoo} = ReactNative.NativeModules;

如果您沒有指定名稱,JavaScript 模組名稱將會與 Objective-C 類別名稱相符,並移除任何「RCT」或「RK」前綴。

讓我們遵循以下範例,並在沒有任何引數的情況下呼叫 RCT_EXPORT_MODULE。因此,模組將使用名稱 CalendarModule 公開給 React Native,因為這是 Objective-C 類別名稱,已移除 RCT。

// Without passing in a name this will export the native module name as the Objective-C class name with “RCT” removed
RCT_EXPORT_MODULE();

然後可以在 JS 中像這樣存取原生模組

const {CalendarModule} = ReactNative.NativeModules;

將原生方法匯出至 JavaScript

React Native 必須明確告知,才會在 JavaScript 中公開原生模組中的任何方法。這可以使用 RCT_EXPORT_METHOD 巨集來完成。以 RCT_EXPORT_METHOD 巨集撰寫的方法是非同步的,因此回傳類型永遠是 void。若要將 RCT_EXPORT_METHOD 方法的結果傳遞給 JavaScript,可以使用回呼或發出事件(如下所述)。讓我們繼續使用 RCT_EXPORT_METHOD 巨集,為我們的 CalendarModule 原生模組設定原生方法。將其稱為 createCalendarEvent(),並先讓它採用名稱和位置引數作為字串。引數類型選項將在稍後介紹。

RCT_EXPORT_METHOD(createCalendarEvent:(NSString *)name location:(NSString *)location)
{
}

請注意,除非方法依賴於 RCT 引數轉換(請參閱下方的引數類型),否則 TurboModules 將不需要 RCT_EXPORT_METHOD 巨集。最終,React Native 將移除 RCT_EXPORT_MACRO,因此我們不鼓勵人們使用 RCTConvert。相反地,您可以在方法主體中進行引數轉換。

在建構 createCalendarEvent() 方法的功能之前,請在方法中新增主控台記錄,以便您確認已在 React Native 應用程式中從 JavaScript 呼叫它。使用 React 的 RCTLog API。讓我們在檔案頂端匯入該標頭,然後新增記錄呼叫。

#import <React/RCTLog.h>
RCT_EXPORT_METHOD(createCalendarEvent:(NSString *)name location:(NSString *)location)
{
RCTLogInfo(@"Pretending to create an event %@ at %@", name, location);
}

同步方法

您可以使用 RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD 來建立同步原生方法。

RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getName)
{
return [[UIDevice currentDevice] name];
}

此方法的回傳類型必須為物件類型 (id),並且應該可序列化為 JSON。這表示掛鉤只能回傳 nil 或 JSON 值(例如 NSNumber、NSString、NSArray、NSDictionary)。

目前,我們不建議使用同步方法,因為同步呼叫方法可能會對效能造成重大影響,並在您的原生模組中引入與執行緒相關的錯誤。此外,請注意,如果您選擇使用 RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD,您的應用程式將無法再使用 Google Chrome 除錯程式。這是因為同步方法需要 JS VM 與應用程式共用記憶體。對於 Google Chrome 除錯程式,React Native 在 Google Chrome 中的 JS VM 內執行,並透過 WebSockets 與行動裝置非同步通訊。

測試您已建置的內容

此時,您已在 iOS 中設定原生模組的基本架構。透過存取原生模組並在 JavaScript 中呼叫其匯出方法來測試它。

在應用程式中找到要新增呼叫原生模組的 createCalendarEvent() 方法的地方。以下是您可以在應用程式中新增的元件範例,NewModuleButton。您可以在 NewModuleButtononPress() 函式中呼叫原生模組。

import React from 'react';
import {NativeModules, Button} from 'react-native';

const NewModuleButton = () => {
const onPress = () => {
console.log('We will invoke the native module here!');
};

return (
<Button
title="Click to invoke your native module!"
color="#841584"
onPress={onPress}
/>
);
};

export default NewModuleButton;

要從 JavaScript 存取原生模組,您需要先從 React Native 匯入 NativeModules

import {NativeModules} from 'react-native';

然後,您可以從 NativeModules 存取 CalendarModule 原生模組。

const {CalendarModule} = NativeModules;

現在您已取得 CalendarModule 原生模組,您可以呼叫原生方法 createCalendarEvent()。以下是新增到 NewModuleButton 中的 onPress() 方法

const onPress = () => {
CalendarModule.createCalendarEvent('testName', 'testLocation');
};

最後一個步驟是重新建置 React Native 應用程式,以便您可以取得最新的原生程式碼(包含您的新原生模組!)。在命令列中,在 react native 應用程式所在的位置,執行下列

npm run ios

在反覆運算時建置

在您使用這些指南並反覆運算原生模組時,您需要對應用程式進行原生重新建置,才能從 JavaScript 存取您最近的變更。這是因為您編寫的程式碼位於應用程式的原生部分。雖然 React Native 的 metro bundler 可以監控 JavaScript 的變更,並為您即時重新建置 JS 程式集,但它不會對原生程式碼執行此操作。因此,如果您要測試最新的原生變更,您需要使用上述命令重新建置。

回顧✨

現在您應該可以在 JavaScript 中的原生模組上呼叫 createCalendarEvent() 方法。由於您在函式中使用 RCTLog,因此您可以透過在應用程式中啟用偵錯模式並查看 Chrome 或行動應用程式偵錯工具 Flipper 中的 JS 主控台,確認您的原生方法已呼叫。每次呼叫原生模組方法時,您都應該會看到 RCTLogInfo(@"Pretending to create an event %@ at %@", name, location); 訊息。

Image of logs.
Flipper 中的 iOS 記錄影像

在這個步驟中,您已經建立了一個 iOS 原生模組,並從 React Native 應用程式中的 JavaScript 呼叫其方法。您可以繼續閱讀,深入了解原生模組方法所使用的引數類型,以及如何在原生模組中設定回呼和 Promise。

超越日曆原生模組

更好的原生模組匯出

透過從 NativeModules 中提取原生模組來匯入,如上所示,有點笨拙。

為了讓原生模組的使用者在每次想要存取原生模組時不必這麼做,您可以為模組建立一個 JavaScript 封裝器。建立一個名為 NativeCalendarModule.js 的新 JavaScript 檔案,內容如下

/**
* This exposes the native CalendarModule module as a JS module. This has a
* function 'createCalendarEvent' which takes the following parameters:

* 1. String name: A string representing the name of the event
* 2. String location: A string representing the location of the event
*/
import {NativeModules} from 'react-native';
const {CalendarModule} = NativeModules;
export default CalendarModule;

這個 JavaScript 檔案也成為您新增任何 JavaScript 端功能的絕佳位置。例如,如果您使用 TypeScript 等型別系統,您可以在這裡為原生模組新增型別註解。雖然 React Native 尚未支援原生至 JS 型別安全性,但透過這些型別註解,您的所有 JS 程式碼都會是型別安全的。這些註解也會讓您更容易在日後切換至型別安全的原生模組。以下是為日曆模組新增型別安全性的範例

/**
* This exposes the native CalendarModule module as a JS module. This has a
* function 'createCalendarEvent' which takes the following parameters:
*
* 1. String name: A string representing the name of the event
* 2. String location: A string representing the location of the event
*/
import {NativeModules} from 'react-native';
const {CalendarModule} = NativeModules;
interface CalendarInterface {
createCalendarEvent(name: string, location: string): void;
}
export default CalendarModule as CalendarInterface;

在您其他 JavaScript 檔案中,您可以存取原生模組並呼叫其方法,如下所示

import NativeCalendarModule from './NativeCalendarModule';
NativeCalendarModule.createCalendarEvent('foo', 'bar');

請注意,這假設您匯入 CalendarModule 的位置與 NativeCalendarModule.js 的階層相同。請視需要更新相對匯入。

引數類型

當在 JavaScript 中呼叫原生模組方法時,React Native 會將引數從 JS 物件轉換為其 Objective-C/Swift 物件類比。因此,例如,如果您的 Objective-C 原生模組方法接受 NSNumber,在 JS 中,您需要使用數字呼叫方法。React Native 會為您處理轉換。以下是原生模組方法支援的引數類型清單,以及它們對應的 JavaScript 等效項。

Objective-CJavaScript
NSString字串, ?字串
BOOL布林值
double數字
NSNumber?數字
NSArray陣列, ?陣列
NSDictionary物件, ?物件
RCTResponseSenderBlock函式 (成功)
RCTResponseSenderBlock, RCTResponseErrorBlock函式 (失敗)
RCTPromiseResolveBlock, RCTPromiseRejectBlock承諾

目前支援下列類型,但 TurboModules 不會支援。請避免使用這些類型。

  • 函式 (失敗) -> RCTResponseErrorBlock
  • 數字 -> NSInteger
  • 數字 -> CGFloat
  • 數字 -> float

對於 iOS,您也可以使用 RCTConvert 類別支援的任何引數類型撰寫原生模組方法 (有關支援內容的詳細資訊,請參閱 RCTConvert)。RCTConvert 輔助函式全部接受 JSON 值作為輸入,並將其對應到原生 Objective-C 類型或類別。

匯出常數

原生模組可以透過覆寫原生方法 constantsToExport() 來匯出常數。下方覆寫了 constantsToExport(),並傳回一個包含預設事件名稱屬性的字典,您可以在 JavaScript 中存取,如下所示

- (NSDictionary *)constantsToExport
{
return @{ @"DEFAULT_EVENT_NAME": @"New Event" };
}

接著,可以在 JS 中呼叫原生模組上的 getConstants() 來存取常數,如下所示

const {DEFAULT_EVENT_NAME} = CalendarModule.getConstants();
console.log(DEFAULT_EVENT_NAME);

技術上來說,可以直接從 NativeModule 物件存取在 constantsToExport() 中匯出的常數。TurboModules 將不再支援此功能,因此我們鼓勵社群改用上述方法,以避免日後必須進行必要的遷移。

請注意,常數只會在初始化時匯出,因此如果您在執行階段變更 constantsToExport() 值,不會影響 JavaScript 環境。

對於 iOS,如果您覆寫了 constantsToExport(),也應該實作 + requiresMainQueueSetup,讓 React Native 知道您的模組是否需要在執行任何 JavaScript 程式碼之前在主執行緒上初始化。否則,您會看到警告,表示您的模組未來可能會在背景執行緒上初始化,除非您明確使用 + requiresMainQueueSetup: 選擇不這麼做。如果您的模組不需要存取 UIKit,則應該對 + requiresMainQueueSetup 回應否。

回呼

原生模組也支援一種獨特的引數類型 - 回呼。回呼用於將資料從 Objective-C 傳遞到 JavaScript,以供非同步方法使用。它們也可以用於從原生端非同步執行 JS。

對於 iOS,回呼是使用類型 RCTResponseSenderBlock 實作的。下方將回呼參數 myCallBack 新增到 createCalendarEventMethod()

RCT_EXPORT_METHOD(createCalendarEvent:(NSString *)title
location:(NSString *)location
myCallback:(RCTResponseSenderBlock)callback)

您可以在原生函數中呼叫回呼,提供您想傳遞給 JavaScript 的任何結果,並以陣列方式傳遞。請注意,RCTResponseSenderBlock 只接受一個參數,即傳遞給 JavaScript 回呼的參數陣列。以下將傳回在先前呼叫中建立的事件 ID。

重要的是,在原生函數完成後,並不會立即呼叫回呼,請記住通訊是異步的。

RCT_EXPORT_METHOD(createCalendarEvent:(NSString *)title location:(NSString *)location callback: (RCTResponseSenderBlock)callback)
{
NSInteger eventId = ...
callback(@[@(eventId)]);

RCTLogInfo(@"Pretending to create an event %@ at %@", title, location);
}

然後可以使用以下方式在 JavaScript 中存取此方法

const onSubmit = () => {
CalendarModule.createCalendarEvent(
'Party',
'04-12-2020',
eventId => {
console.log(`Created a new event with id ${eventId}`);
},
);
};

原生模組應該只呼叫其回呼一次。不過,它可以儲存回呼並在稍後呼叫它。此模式通常用於包裝需要委派的 iOS API,請參閱 RCTAlertManager 以取得範例。如果從未呼叫回呼,則會洩漏一些記憶體。

有兩種處理回呼錯誤的方法。第一個方法是遵循 Node 的慣例,並將傳遞給回呼陣列的第一個參數視為錯誤物件。

RCT_EXPORT_METHOD(createCalendarEventCallback:(NSString *)title location:(NSString *)location callback: (RCTResponseSenderBlock)callback)
{
NSNumber *eventId = [NSNumber numberWithInt:123];
callback(@[[NSNull null], eventId]);
}

在 JavaScript 中,您可以檢查第一個參數,以查看是否傳遞錯誤

const onPress = () => {
CalendarModule.createCalendarEventCallback(
'testName',
'testLocation',
(error, eventId) => {
if (error) {
console.error(`Error found! ${error}`);
}
console.log(`event id ${eventId} returned`);
},
);
};

另一個選項是使用兩個獨立的回呼:onFailure 和 onSuccess。

RCT_EXPORT_METHOD(createCalendarEventCallback:(NSString *)title
location:(NSString *)location
errorCallback: (RCTResponseSenderBlock)errorCallback
successCallback: (RCTResponseSenderBlock)successCallback)
{
@try {
NSNumber *eventId = [NSNumber numberWithInt:123];
successCallback(@[eventId]);
}

@catch ( NSException *e ) {
errorCallback(@[e]);
}
}

然後,可以在 JavaScript 中新增一個獨立的回呼,用於錯誤和成功回應

const onPress = () => {
CalendarModule.createCalendarEventCallback(
'testName',
'testLocation',
error => {
console.error(`Error found! ${error}`);
},
eventId => {
console.log(`event id ${eventId} returned`);
},
);
};

如果您想將類似錯誤的物件傳遞給 JavaScript,請使用 RCTUtils.h. 中的 RCTMakeError。目前這只會將一個錯誤形狀的字典傳遞給 JavaScript,但 React Native 的目標是未來自動產生真正的 JavaScript 錯誤物件。您也可以提供 RCTResponseErrorBlock 參數,用於錯誤回呼並接受 NSError \* 物件。請注意,TurboModules 不支援此參數類型。

承諾

原生模組也可以履行承諾,這可以簡化您的 JavaScript,特別是在使用 ES2016 的 async/await 語法時。當原生模組方法的最後一個參數是 RCTPromiseResolveBlockRCTPromiseRejectBlock 時,其對應的 JS 方法將傳回一個 JS Promise 物件。

將上述程式碼重新整理為使用承諾,而不是回呼,如下所示

RCT_EXPORT_METHOD(createCalendarEvent:(NSString *)title
location:(NSString *)location
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSInteger eventId = createCalendarEvent();
if (eventId) {
resolve(@(eventId));
} else {
reject(@"event_failure", @"no event id returned", nil);
}
}

此方法的 JavaScript 對應項傳回一個 Promise。這表示您可以在非同步函數中使用 await 關鍵字來呼叫它並等待其結果

const onSubmit = async () => {
try {
const eventId = await CalendarModule.createCalendarEvent(
'Party',
'my house',
);
console.log(`Created a new event with id ${eventId}`);
} catch (e) {
console.error(e);
}
};

傳送事件給 JavaScript

原生模組可以在不直接呼叫的情況下,向 JavaScript 發出事件信號。例如,您可能想要向 JavaScript 發出提醒,表示來自原生 iOS 行事曆應用程式的行事曆事件即將發生。執行此動作的首選方式是建立 RCTEventEmitter 的子類別,實作 supportedEvents 並呼叫 self sendEventWithName

更新您的標頭類別,以匯入 RCTEventEmitter 並建立 RCTEventEmitter 的子類別

//  CalendarModule.h

#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>

@interface CalendarModule : RCTEventEmitter <RCTBridgeModule>
@end

JavaScript 程式碼可透過在模組周圍建立新的 NativeEventEmitter 執行個體來訂閱這些事件。

如果您在沒有任何偵聽器的情況下發出事件,將會收到警告,表示您不必要地消耗資源。為避免這種情況,並最佳化模組的工作負載(例如,取消訂閱上游通知或暫停背景工作),您可以在 RCTEventEmitter 子類別中覆寫 startObservingstopObserving

@implementation CalendarManager
{
bool hasListeners;
}

// Will be called when this module's first listener is added.
-(void)startObserving {
hasListeners = YES;
// Set up any upstream listeners or background tasks as necessary
}

// Will be called when this module's last listener is removed, or on dealloc.
-(void)stopObserving {
hasListeners = NO;
// Remove upstream listeners, stop unnecessary background tasks
}

- (void)calendarEventReminderReceived:(NSNotification *)notification
{
NSString *eventName = notification.userInfo[@"name"];
if (hasListeners) {// Only send events if anyone is listening
[self sendEventWithName:@"EventReminder" body:@{@"name": eventName}];
}
}

執行緒

除非原生模組提供自己的方法佇列,否則不應對其被呼叫的執行緒做出任何假設。目前,如果原生模組未提供方法佇列,React Native 將為其建立一個獨立的 GCD 佇列,並在那裡呼叫其方法。請注意,這是實作細節,可能會變更。如果您想明確為原生模組提供方法佇列,請覆寫原生模組中的 (dispatch_queue_t) methodQueue 方法。例如,如果需要使用僅限主執行緒的 iOS API,則應透過以下方式指定:

- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}

類似地,如果某個作業可能需要很長時間才能完成,原生模組可以指定自己的佇列來執行作業。同樣地,目前 React Native 將為您的原生模組提供一個獨立的方法佇列,但這是您不應依賴的實作細節。如果您未提供自己的方法佇列,未來,您的原生模組的長時間執行作業可能會導致在其他不相關的原生模組上執行的非同步呼叫遭到封鎖。例如,此處的 RCTAsyncLocalStorage 模組建立自己的佇列,以便 React 佇列不會因等待潛在的緩慢磁碟存取而遭到封鎖。

- (dispatch_queue_t)methodQueue
{
return dispatch_queue_create("com.facebook.React.AsyncLocalStorageQueue", DISPATCH_QUEUE_SERIAL);
}

指定的 methodQueue 將由模組中的所有方法共用。如果您的方法只有一個是長時間執行的(或由於某些原因需要在與其他方法不同的佇列上執行),您可以在方法內使用 dispatch_async 在另一個佇列上執行該特定方法的程式碼,而不會影響其他方法

RCT_EXPORT_METHOD(doSomethingExpensive:(NSString *)param callback:(RCTResponseSenderBlock)callback)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Call long-running code on background thread
...
// You can invoke callback from any thread/queue
callback(@[...]);
});
}

在模組間共用傳送佇列

methodQueue 方法會在模組初始化時呼叫一次,然後由 React Native 保留,因此無需自行保留佇列的參考,除非您想在模組中使用它。不過,如果您想在多個模組之間共用同一個佇列,則需要確保保留並為每個模組傳回同一個佇列實例。

依賴注入

React Native 會自動建立並初始化任何已註冊的原生模組。不過,您可能想建立並初始化您自己的模組實例,例如,注入依賴項。

您可以透過建立一個實作 RCTBridgeDelegate 協定的類別,使用委派作為引數初始化一個 RCTBridge,並使用已初始化的橋初始化一個 RCTRootView 來執行此動作。

id<RCTBridgeDelegate> moduleInitialiser = [[classThatImplementsRCTBridgeDelegate alloc] init];

RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:moduleInitialiser launchOptions:nil];

RCTRootView *rootView = [[RCTRootView alloc]
initWithBridge:bridge
moduleName:kModuleName
initialProperties:nil];

匯出 Swift

Swift 不支援巨集,因此在 React Native 中將原生模組及其方法公開給 JavaScript 需要更多設定。不過,它的運作方式大致相同。假設您有同一個 CalendarModule,但它是 Swift 類別

// CalendarManager.swift

@objc(CalendarManager)
class CalendarManager: NSObject {

@objc(addEvent:location:date:)
func addEvent(_ name: String, location: String, date: NSNumber) -> Void {
// Date is ready to use!
}

@objc
func constantsToExport() -> [String: Any]! {
return ["someKey": "someValue"]
}

}

務必使用 @objc 修飾詞,以確保類別和函式正確匯出至 Objective-C 執行時期。

然後建立一個私人實作檔案,其中會將必要的資訊註冊到 React Native

// CalendarManagerBridge.m
#import <React/RCTBridgeModule.h>

@interface RCT_EXTERN_MODULE(CalendarManager, NSObject)

RCT_EXTERN_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(nonnull NSNumber *)date)

@end

對於那些剛接觸 Swift 和 Objective-C 的人來說,每當您在 iOS 專案中混合使用這兩種語言時,您還需要一個額外的橋接檔案,稱為橋接標頭,以將 Objective-C 檔案公開給 Swift。如果您透過 Xcode 的 檔案>新增檔案 選單選項將 Swift 檔案新增到您的應用程式,Xcode 會提供為您建立這個標頭檔案。您需要在此標頭檔案中匯入 RCTBridgeModule.h

// CalendarManager-Bridging-Header.h
#import <React/RCTBridgeModule.h>

您也可以使用 RCT_EXTERN_REMAP_MODULE_RCT_EXTERN_REMAP_METHOD 來變更您正在匯出的模組或方法的 JavaScript 名稱。如需更多資訊,請參閱 RCTBridgeModule

製作第三方模組時的重要事項:包含 Swift 的靜態函式庫僅在 Xcode 9 及後續版本中受支援。為了讓 Xcode 專案在您於模組中包含的 iOS 靜態函式庫中使用 Swift 時建置,您的主要應用程式專案必須包含 Swift 程式碼和橋接標頭本身。如果您的應用程式專案不包含任何 Swift 程式碼,解決方法可以是單一空白 .swift 檔案和空白橋接標頭。

保留的方法名稱

invalidate()

原生模組可以透過實作 iOS 上的 invalidate() 方法來符合 RCTInvalidating 協定。當原生橋接無效時(例如:開發模式重新載入),可以呼叫這個方法。請視需要使用此機制為您的原生模組進行必要的清除工作。