はじめに
Expoは、React Nativeでのアプリ開発を超絶楽に行えるフレームワークです。
Expoのフルマネージド環境下では、優れた開発体験と引き換えに、ネイティブの機能はExpoで提供されているもの以外を使用できません。
ExpoのAPI郡を使用しながらネイティブの機能を使用するライブラリを使用したい場合、
Expoプロジェクトの初期化時にBare Workflowを選択したり、
Expoフルマネージドプロジェクトをejectする等の方法があります。
今回は既存のReact Nativeプロジェクトでexpo-notificationsを使用する手順を紹介します。
リポジトリ
コードはこちら
ライブラリのバージョン
"react": "17.0.2"
"react-native": "0.65.1"
"react-native-unimodules": "0.14.6"
"expo-notifications": "0.12.3"
手順
既存プロジェクトにreact-native-unimodulesを追加する
react-native-unimodules
はExpoのユニモジュールを使用するためのライブラリです。
既存のReact Nativeに導入することで、Expoから提供されているAPIを使用できます。
yarn add react-native-unimodules
cd ./ios && pod install
iOSとAndroidの各設定は公式のドキュメントにあります。
https://docs.expo.dev/bare/installing-unimodules/
動作確認は、下記で行なえます。
systemFontsがundefined
でなく、配列が表示されれば正常に設定完了です。
import {Constants} from 'react-native-unimodules';
console.log(Constants.systemFonts);
expo-notificationsを追加する
Expoの通知のライブラリです。
ローカル通知やExpoの提供するプッシュ通知機能を使用することができます。
プッシュ通知のテストには、ウェブツールも提供されています。
https://expo.dev/notifications
yarn add expo-notifications
あとは、他の通知ライブラリと同様、各種APIを使用して通知設定を行うだけです。
2021/09/05 補足: patchの追加
react-native-unimodules@0.14.6
が、まだreact-native@0.65.1
に対応していないため、patchをあてる必要があります。
@unimodules+core+7.1.1.patch
diff --git a/node_modules/@unimodules/core/ios/UMCore/UMUtilities.m b/node_modules/@unimodules/core/ios/UMCore/UMUtilities.m
index e1c02e3..c8b7604 100644
--- a/node_modules/@unimodules/core/ios/UMCore/UMUtilities.m
+++ b/node_modules/@unimodules/core/ios/UMCore/UMUtilities.m
@@ -28,7 +28,9 @@ UM_REGISTER_MODULE();
- (void)setModuleRegistry:(UMModuleRegistry *)moduleRegistry
{
- _moduleRegistry = moduleRegistry;
+ if ([moduleRegistry isKindOfClass: [UMModuleRegistry class]]) {
+ _moduleRegistry = moduleRegistry;
+ }
}
- (nullable NSDictionary *)launchOptions
@unimodules+react-native-adapter+6.3.5.patch
diff --git a/node_modules/@unimodules/react-native-adapter/ios/UMReactNativeAdapter/Services/UMReactNativeEventEmitter.m b/node_modules/@unimodules/react-native-adapter/ios/UMReactNativeAdapter/Services/UMReactNativeEventEmitter.m
index 7fe313b..6fe899a 100644
--- a/node_modules/@unimodules/react-native-adapter/ios/UMReactNativeAdapter/Services/UMReactNativeEventEmitter.m
+++ b/node_modules/@unimodules/react-native-adapter/ios/UMReactNativeAdapter/Services/UMReactNativeEventEmitter.m
@@ -139,7 +139,9 @@ RCT_EXPORT_METHOD(removeProxiedListeners:(NSString *)moduleName count:(double)co
- (void)setModuleRegistry:(UMModuleRegistry *)moduleRegistry
{
- _umModuleRegistry = moduleRegistry;
+ if ([moduleRegistry isKindOfClass:[UMModuleRegistry class]]) {
+ _umModuleRegistry = moduleRegistry;
+ }
}
@end
diff --git a/node_modules/@unimodules/react-native-adapter/build/NativeModulesProxy.native.js b/node_modules/@unimodules/react-native-adapter/build/NativeModulesProxy.native.js
index fdcfaba..d2a55e1 100644
--- a/node_modules/@unimodules/react-native-adapter/build/NativeModulesProxy.native.js
+++ b/node_modules/@unimodules/react-native-adapter/build/NativeModulesProxy.native.js
@@ -20,8 +20,10 @@ if (NativeProxy) {
//
// On Android only {start,stop}Observing are called on the native module
// and these should be exported as Expo methods.
- NativeModulesProxy[moduleName].addListener = (...args) => NativeModules.UMReactNativeEventEmitter.addProxiedListener(moduleName, ...args);
- NativeModulesProxy[moduleName].removeListeners = (...args) => NativeModules.UMReactNativeEventEmitter.removeProxiedListeners(moduleName, ...args);
+ if (NativeModules.UMReactNativeEventEmitter) {
+ NativeModulesProxy[moduleName].addListener = (...args) => NativeModules.UMReactNativeEventEmitter.addProxiedListener(moduleName, ...args);
+ NativeModulesProxy[moduleName].removeListeners = (...args) => NativeModules.UMReactNativeEventEmitter.removeProxiedListeners(moduleName, ...args);
+ }
});
}
else {
おわりに
ライブラリのメンテは、リソースやコストの問題で行われなくなったものをよく見かけます。
ExpoのライブラリはExpoチームによるメンテナンスが行われている安定性をふまえると、
実際に使用してみなければハマりどころは分からないものですが、
事業プロダクトでもユニモジュールとして採用候補に入るかと思いました。