React NativeでBLE
BLE用のライブラリーには react-native-ble-plx を使います。Polidea社は他にも各プラットフォーム向けのライブラリーを提供しており安心感がありますね。
まずはなにはともあれProjectをinitします。
npx react-native init MyApp --template react-native-template-typescript
react-native-ble-plx
のREADMEではExpo を使うことになっていますが、すぐにeject
をするのであんまり意味ないのと、Expoだと実機でビルドするためにPush Notificationの設定など追加で面倒な作業が必要になるため、素のReactNativeでやります。
続いて react-native-ble-plx
をインストールします。
yarn add react-native-ble-plx
次にライブラリーの Linkingを行います。
ios
ディレクトリに移動し pod install
で react-native-ble-plx
のiOS依存ライブラリがインストールされます
最後に ios/MyApp/Info.plist
にBLEの使用用途の文字列を定義します。
keyは NSBluetoothAlwaysUsageDescription
、値は適当な文字列を入力します。
--- ios/MyApp/Info.plist
+++ ios/MyApp/Info.plist
@@ -51,5 +51,7 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
+ <key>NSBluetoothAlwaysUsageDescription</key>
+ <string>Commuticate to BLE device</string>
</dict>
</plist>
これを行うことで、アプリでBLE使用時にユーザーにBLEの利用を許可するかどうかの確認ダイアログが出るようになります。定義しないとクラッシュします。
BleManager
を App.tsx
でimportして動作確認します。
--- App.tsx
+++ App.tsx
@@ -27,6 +27,10 @@
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
+ import { BleManager } from "react-native-ble-plx";
+
+ const manager = new BleManager();
+
const Section: React.FC<{
title: string;
}> = ({children, title}) => {
@@ -62,6 +66,14 @@
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
+ const [state, setState] = React.useState("");
+ React.useEffect(() => {
+ manager.state().then(state => {
+ setState(state)
+ });
+ });
+
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
@@ -86,6 +98,9 @@
<Section title="Learn More">
Read the docs to discover what to do next:
</Section>
+ <Section title="BLE state">
+ State: {`${state}`}
+ </Section>
<LearnMoreLinks />
</View>
</ScrollView>
yarn ios
で iOSのSimulatorを立ち上げます
Stateは Unsupported
と出ますが、これはSimulatorがBLEをサポートしていないためです。
実機でビルドすると、
Stateは Unknown
でした
以下の通り、stateをobserveするように変更します。
--- App.tsx
+++ App.tsx
@@ -68,8 +68,7 @@
const [state, setState] = React.useState("");
React.useEffect(() => {
- manager.state().then(state => {
+ manager.onStateChange(state => {
setState(state)
});
});
すると、
Stateが PoweredON
になりました 🎉