React NativeでiOS向けにSwiftを用いて、Native Modulesを実装する方法を解説します。
モグモグさん
出来るだけ分かりやすく解説していきます。
- Native Modulesがわかる
- Swiftを用いてカスタムのNative Modulesを作成することができる
- React 17.0.2
- React Native 0.65.1
モグモグさん
Objective-Cで実装する方法についてはこちらで解説しています。
【iOS・Objective-C】React NativeでNative Modulesを実装する方法を解説
Native Modulesとは?
Native Modulesについて簡単に解説します。
モグモグさん
すでに理解している方はスキップしてください。
Native Modulesとは、React Nativeで用意されていない機能をネイティブで実装するための機能です。
アプリの要件によって、React Nativeがもともと用意していない機能を足したり、パフォーマンスの観点等でネイティブで実装すべき箇所をNative Modulesを使って実装したりすることが多いです。
React Nativeでも多くのことがすでにできますが、Native Modulesを使うことで幅が広がります。
- iOS: Objective-CとSwiftどちらでも実装可能
- Android: JavaとKotlinどちらでも実装可能
本記事では紹介しませんが、UIに関連するものは、Native UI Componentsを利用します。
モグモグさん
それぞれのドキュメントを貼っておきますので参考にしてください。
事前準備(ベースのアプリを作成)
まずは、React Nativeでアプリを作成しましょう。
この記事では、NativeModuleExampleというプロジェクトを作成しました。
モグモグさん
すでに作成済みの方はスキップでOKです!
こちらの記事も参考にしてください。
【ReactNative入門 】Macで開発環境を作って始める
Native Modulesの作成
それでは、Native Modulesを作成していきます。
CustomNativeModuleファイルの作成
まずは、Swiftファイルを作成します。
本記事では、CustomNativeModuleSwift
というファイル名にしましたが、任意の名前にしてください。
モグモグさん
次で解説しますが、Objective-C bridging headerを作成しますか?というポップアップが表示される場合は作成してください。
よく使いそうなメソッド + 具体的なメソッドを実装しています。
- シンプルなメソッド
- callbackを返すメソッド
- 引数を取るメソッド
- Promiseを扱うメソッド
- OSのバージョンを返すメソッド
モグモグさん
重要なポイントはコメントに記載しているので、確認してください。
import Foundation
// @objc(CustomNativeModuleSwift)の箇所が重要
@objc(CustomNativeModuleSwift) class CustomNativeModuleSwift: NSObject {
@objc static func requiresMainQueueSetup() -> Bool { return true }
// 出力するだけのメソッド
@objc public func funcSimple() {
print("funcSimple")
}
// callbackメソッド
@objc public func funcCallback(_ callback: RCTResponseSenderBlock) {
callback(["funcCallback"])
}
// 引数を取るcallbackメソッド
@objc public func funcCallbackWithParams(_ param: String, callback: RCTResponseSenderBlock) {
callback(["funcCallbackWithParams: '\(param)'"])
}
// Promise resolveパターンのメソッド
@objc public func funcResolvePromise(
_ resolve: RCTPromiseResolveBlock,
rejecter reject: RCTPromiseRejectBlock
) {
resolve("funcResolvePromise")
}
// Promise rejectパターンのメソッド
@objc public func funcRejectPromise(
_ resolve: RCTPromiseResolveBlock,
rejecter reject: RCTPromiseRejectBlock
) {
reject("error", "funcRejectPromise", nil)
}
// 実用例: デバイスの名前を返すメソッド
@objc public func getDeviceName(
_ callback: RCTResponseSenderBlock
) {
callback([UIDevice.current.name])
}
}
Objective-C Bridging headerを作成
続いてObjective-C bridging headerを作成します。
import <React/RCTBridgeModule.h
を追加するだけですが、忘れないようにしましょう。
#import <React/RCTBridgeModule.h>
Objective-Cファイルを作成しJavaScriptから使えるようにする
続いて、Objective-C
のファイルを作成して、JavaScriptから定義したModuleとメソッドを使えるようにしていきます。
- RCT_EXTERN_MODULE: Moduleを記載
- RCT_EXTERN_METHOD: メソッドを記載
#import "React/RCTBridgeModule.h"
@interface RCT_EXTERN_MODULE(CustomNativeModuleSwift, NSObject)
RCT_EXTERN_METHOD(getDeviceName:
(RCTResponseSenderBlock) callback
)
RCT_EXTERN_METHOD(funcSimple)
RCT_EXTERN_METHOD(funcCallback:
(RCTResponseSenderBlock) callback
)
RCT_EXTERN_METHOD(funcCallbackWithParams:
(NSString *) param
callback: (RCTResponseSenderBlock)callback
)
RCT_EXTERN_METHOD(
funcResolvePromise: (RCTPromiseResolveBlock) resolve
rejecter: (RCTPromiseRejectBlock) reject
)
RCT_EXTERN_METHOD(funcRejectPromise:
(RCTPromiseResolveBlock) resolve
rejecter: (RCTPromiseRejectBlock) reject
)
@end
JavaScript側から使う
カスタムのNative Modulesを作成したので、JavaScript側から使う方法を解説していきます。
App.jsでimport
Moduleの名前は、ご自身で定義したものを使ってください。
import {NativeModules} from 'react-native';
const App = () => {
const {CustomNativeModuleSwift} = NativeModules;
}
各メソッドを呼ぶ
呼ぶ場所は、任意ですが本記事では、useEffect
内でそれぞれのメソッドを呼んでみました。
const App = () => {
useEffect(() => {
CustomNativeModuleSwift.getDeviceName(name => {
console.log(name);
});
CustomNativeModuleSwift.funcSimple();
CustomNativeModuleSwift.funcCallback(result => {
console.log(result);
});
CustomNativeModuleSwift.funcCallbackWithParams('test', (result, param) => {
console.log(result, param);
});
(async () => {
const result = await CustomNativeModuleSwift.funcResolvePromise();
console.log(result);
})();
(async () => {
try {
await CustomNativeModuleSwift.funcRejectPromise();
} catch (err) {
console.error(err);
}
})();
}, []);
}
実行結果
実装したModuleのメソッドがそれぞれ呼ばれていることが分かりますね。
まとめ
モグモグさん
お疲れ様でした!
iOS向けにSwiftを用いて、NativeModulesを実装する方法を解説しました。
React Nativeを実装する上で非常に有用なので、ぜひ実際に使ってみてください!