Skip to content
This repository has been archived by the owner on Apr 16, 2024. It is now read-only.

Commit

Permalink
docs(react): ๐Ÿ“ finish documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewDongminYoo committed Apr 11, 2023
1 parent 1330e6d commit f6789d4
Show file tree
Hide file tree
Showing 4 changed files with 322 additions and 15 deletions.
23 changes: 17 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,19 @@ This project is an extreme enhancement of a previously existing native module at

## Installation

```sh
npm install @dongminyu/segway-ble-manager
```shell
# if you use pure npm (what a classic!),
npm install @dongminyu/react-native-segway-ble-manager
```

```shell
# or if you prefer to use Yarn (I love it's parallel install feature),
yarn add @dongminyu/react-native-segway-ble-manager
```

```shell
# or if you use pnpm (it's fast and efficient),
pnpm add @dongminyu/react-native-segway-ble-manager
```

## Permission Setting
Expand All @@ -22,15 +33,15 @@ npm install @dongminyu/segway-ble-manager
```xml
<!-- iOS 13 and newer, include the `NSBluetoothAlwaysUsageDescription` -->
<key>NSBluetoothAlwaysUsageDescription</key>
<string>์Šค์ฟ ํ„ฐ ์กฐ์ž‘์„ ์œ„ํ•ด ๋ธ”๋ฃจํˆฌ์Šค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค</string>
<string>Use Bluetooth when it needs to control the scooter</string>
<!-- iOS 12 and earlier, include `NSBluetoothPeripheralUsageDescription` -->
<key>NSBluetoothPeripheralUsageDescription</key>
<string>์Šค์ฟ ํ„ฐ ์กฐ์ž‘์„ ์œ„ํ•ด ๋ธ”๋ฃจํˆฌ์Šค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค</string>
<string>Use Bluetooth peripherals to control the scooter</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>์Šค์ฟ ํ„ฐ ์กฐ์ž‘์„ ์œ„ํ•ด ์œ„์น˜๋ฐ์ดํ„ฐ๋ฅผ ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค</string>
<string>Accesses location data to measure the distance</string>
```

- in Android
- Android ์„ค์ •

```xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Expand Down
296 changes: 296 additions & 0 deletions README_kr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,296 @@
# @dongminyu/segway-ble-manager

`react-native-segway-ble-manager`๋Š” ์„ธ๊ทธ์›จ์ด ๊ธฐ๊ธฐ์™€ ๋ธ”๋ฃจํˆฌ์Šค ์ €์—๋„ˆ์ง€(BLE) ์—ฐ๊ฒฐ์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋ฆฌ์•กํŠธ ๋„ค์ดํ‹ฐ๋ธŒ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.
`react-native-segway-ble-manager`๋Š” ์„ธ๊ทธ์›จ์ด ๊ธฐ๊ธฐ์™€ BLE๋ฅผ ํ†ตํ•ด ์—ฐ๊ฒฐํ•˜๊ณ  ํ†ต์‹ ํ•˜๊ธฐ ์œ„ํ•œ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด API๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ์™€ iOS ํ”Œ๋žซํผ์„ ๋ชจ๋‘ ์ง€์›ํ•˜๋ฉฐ ๋””๋ฐ”์ด์Šค ๊ฒ€์ƒ‰, ์—ฐ๊ฒฐ ๊ด€๋ฆฌ, ๋ฐ์ดํ„ฐ ์ „์†ก๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๊ฐœ๋ฐœ์ž๋Š” `react-native-segway-ble-manager`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‚˜์ธ๋ด‡ ์„ธ๊ทธ์›จ์ด ๋””๋ฐ”์ด์Šค ์ œ์–ด ๊ธฐ๋Šฅ์„ React Native ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์‰ฝ๊ฒŒ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

## ํ”„๋กœ์ ํŠธ ๊ฐœ์š”

์ด ํ”„๋กœ์ ํŠธ๋Š” ๊ธฐ์กด์— ์žˆ๋˜ ๋„ค์ดํ‹ฐ๋ธŒ ๋ชจ๋“ˆ์„ ๋Œ€ํญ ๊ฐœ์„ ํ•œ ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค. ์ด์ „ ๋ชจ๋“ˆ์€ ๋ชจ๋“  ๋ฉ”์„œ๋“œ๋ฅผ ์ž„ํฌํŠธ๋œ ๋ชจ๋“ˆ์—์„œ ์ง์ ‘ ๊ฐ€์ ธ์™”์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํƒ€์ž…-์„ธ์ดํ”„ํ•˜์ง€ ์•Š์•„์„œ ๋ช‡ ๊ฐ€์ง€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“ˆ์„ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด React Native์˜ ์ƒˆ๋กœ์šด ์•„ํ‚คํ…์ฒ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ƒˆ๋กœ์šด ๋„ค์ดํ‹ฐ๋ธŒ ๋ชจ๋“ˆ์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ชจ๋“ˆ์„ ํ†ตํ•ด ๊ฐœ๋ฐœ์ž๋Š” ์„ธ๊ทธ์›จ์ด ์ฐจ๋Ÿ‰์— ์—ฐ๊ฒฐํ•˜๊ณ , ์ฐจ๋Ÿ‰ ์ •๋ณด๋ฅผ ์ฟผ๋ฆฌ ๋ฐ ๊ธฐ๊ธฐ๋ฅผ ์กฐ์ž‘ํ•˜๊ณ , ๋””๋ฐ”์ด์Šค์—์„œ ์ƒ์„ฑ๋œ ์ด๋ฒคํŠธ๋ฅผ ๊ตฌ๋…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

## ์„ค์น˜ ๋ฐฉ๋ฒ•

```shell
# npm์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, (๊ธฐ๋ณธ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €์ž…๋‹ˆ๋‹ค.)
$ npm install @dongminyu/react-native-step-counter
```

```shell
# Yarn์„ ์„ ํ˜ธํ•œ๋‹ค๋ฉด, (๋ณ‘๋ ฌ ์„ค์น˜๋ฅผ ์ง€์›ํ•ด ๋น ๋ฅธ ์†๋„๋ฅผ ์ œ๊ณตํ•˜๋Š” ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €์ž…๋‹ˆ๋‹ค.)
$ yarn add @dongminyu/react-native-step-counter
```

```shell
# pnpm์„ ์„ ํ˜ธํ•œ๋‹ค๋ฉด, (๊ธ€๋กœ๋ฒŒ ํŒจํ‚ค์ง€์™€ ํ•˜๋“œ๋งํฌ๋กœ ๋น ๋ฅธ ์†๋„๋ฅผ ์ œ๊ณตํ•˜๋Š” ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €์ž…๋‹ˆ๋‹ค.)
$ pnpm add @dongminyu/react-native-step-counter
```

๋ฆฌ์•กํŠธ๋„ค์ดํ‹ฐ๋ธŒ 0.60 ๋ฒ„์ „ ์ดํ›„ ์„ค์น˜๋œ ๋„ค์ดํ‹ฐ๋ธŒ ๋ชจ๋“ˆ์€ ์˜คํ†  ๋งํฌ๋ฉ๋‹ˆ๋‹ค. ๋„ค์ดํ‹ฐ๋ธŒ ๋ชจ๋“ˆ์„ ์ˆ˜๋™์œผ๋กœ ์—ฐ๊ฒฐํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๐Ÿ‘ฃ ๋ฆฌ์•กํŠธ ๋„ค์ดํ‹ฐ๋ธŒ์˜ ์ƒˆ๋กœ์šด ์•„ํ‚คํ…์ณ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์›ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

## ๊ด€๋ จ ๊ถŒํ•œ ์„ค์ •

- iOS ์„ค์ •

```xml
<!-- iOS 13 and newer, include the `NSBluetoothAlwaysUsageDescription` -->
<key>NSBluetoothAlwaysUsageDescription</key>
<string>์Šค์ฟ ํ„ฐ ์กฐ์ž‘์„ ์œ„ํ•ด ๋ธ”๋ฃจํˆฌ์Šค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค</string>
<!-- iOS 12 and earlier, include `NSBluetoothPeripheralUsageDescription` -->
<key>NSBluetoothPeripheralUsageDescription</key>
<string>์Šค์ฟ ํ„ฐ ์กฐ์ž‘์„ ์œ„ํ•ด ๋ธ”๋ฃจํˆฌ์Šค๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>์Šค์ฟ ํ„ฐ ์กฐ์ž‘์„ ์œ„ํ•ด ์œ„์น˜๋ฐ์ดํ„ฐ๋ฅผ ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค</string>
```

- in Android

```xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="true" />
```

## ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ ์ฝ”๋“œ

๋‹ค์Œ์€ `react-native-segway-ble-manager` ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ์„ธ๊ทธ์›จ์ด ์ฐจ๋Ÿ‰์— ์—ฐ๊ฒฐํ•˜๊ณ  ์ž ๊ธˆ์„ ํ•ด์ œํ•˜๊ณ  ์—ฐ๊ฒฐ์„ ํ•ด์ œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ฃผ๋Š” ์ฝ”๋“œ ์Šค๋‹ˆํŽซ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค:

```typescript
import {
connect,
disconnect,
init,
openBatteryCover,
openSaddle,
openTailBox,
queryVehicleInformation,
queryIoTInformation,
} from '@dongminyu/segway-ble-manager';

const BLE_INIT_SECRET_KEY = 'MY_SECRET_KEY';
const BLE_INIT_OPERATION_CODE = 'MY_OPERATOR_CODE';
const deviceMac = 'DEVICE_MAC_ADDRESS';
const deviceKey = 'DEVICE_KEY';
const iotImei = 'IOT_IMEI';

React.useEffect(() => {
init(BLE_INIT_SECRET_KEY, BLE_INIT_OPERATION_CODE, true);
// get required permissions
getRequiredPermissions();
}, []);

React.useEffect(() => {
let intervalId: number;
if (timer > 0) {
intervalId = setInterval(() => {
setTimer(timer - 1);
}, 1000);
}
return () => {
setLoading(false);
return clearInterval(intervalId);
};
}, [timer]);
```

์ด ์˜ˆ์ œ์—์„œ๋Š” ๋จผ์ € `react-native-segway-ble-manager` ๋ชจ๋“ˆ์—์„œ `Spec` ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํฌํ•จํ•œ ํ•„์š”ํ•œ ๋ชจ๋“ˆ์„ ์ž„ํฌํŠธํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ `NativeEventEmitter` ํด๋ž˜์Šค์˜ ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  `BleManager` ๋ชจ๋“ˆ์„ ์ธ์ˆ˜๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์œผ๋กœ, `secretKey`, `operatorCode`, `deviceMac`, `deviceKey` ๋ฐ `iotImei`์™€ ๊ฐ™์€ ๋ช‡ ๊ฐ€์ง€ ๊ตฌ์„ฑ ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ `BleManager` ๋ชจ๋“ˆ์„ ์ดˆ๊ธฐํ™”ํ•˜์—ฌ `secretKey`, `operatorCode` ๋ฐ ๋””๋ฒ„๊ทธ ๋ชจ๋“œ ์‚ฌ์šฉ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ถ€์šธ ๊ฐ’์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

`BleManager`๊ฐ€ ์ดˆ๊ธฐํ™”๋˜๋ฉด `connect` ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ `deviceMac`, `deviceKey`, `iotImei`๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์„ธ๊ทธ์›จ์ด ์ฐจ๋Ÿ‰์ด ์—ฐ๊ฒฐ๋  ๋•Œ(`onConnected`)์™€ ์—ฐ๊ฒฐ์ด ๋Š์–ด์งˆ ๋•Œ(`onDisconnected`)์— ๋Œ€ํ•œ ๋‘ ๊ฐœ์˜ ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

์„ธ๊ทธ์›จ์ด ์ฐจ๋Ÿ‰์ด ์—ฐ๊ฒฐ๋˜๋ฉด `unLock` ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ž ๊ธˆ์„ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค. ์ž ๊ธˆ์ด ํ•ด์ œ๋˜๋ฉด ์ฝ˜์†”์— ๋ฉ”์‹œ์ง€๋ฅผ ๊ธฐ๋กํ•œ ๋‹ค์Œ `disconnect` ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ฐจ๋Ÿ‰๊ณผ์˜ ์—ฐ๊ฒฐ์„ ๋Š์Šต๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ์ฐจ๋Ÿ‰ ์—ฐ๊ฒฐ์ด ํ•ด์ œ๋˜๋ฉด ์ฝ˜์†”์— ๋˜ ๋‹ค๋ฅธ ๋ฉ”์‹œ์ง€๋ฅผ ๊ธฐ๋กํ•˜๊ณ  ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ œ๊ฑฐํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ์ผ ๋ฟ์ด์ง€๋งŒ, `react-native-segway-ble-manager` ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ์„ธ๊ทธ์›จ์ด ์ฐจ๋Ÿ‰์— ์—ฐ๊ฒฐํ•˜๊ณ  ์ œ์–ดํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์–ด๋Š ์ •๋„์˜ ๊ฐ€์ด๋“œ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

## ๋ฐ์ดํ„ฐ ํƒ€์ž… ์ •์˜ ๋ฐ ํ•˜์œ„ ํ˜ธํ™˜์„ฑ

์ƒˆ๋กœ์šด ์•„ํ‚คํ…์ฒ˜๋Š” ์‹ค์ œ๋กœ React Native๊ฐ€ ์•ผ์‹ฌ์ฐจ๊ฒŒ ๋ฐœํ‘œํ•œ ๊ณ ์„ฑ๋Šฅ์˜ ํ„ฐ๋ณด ๋ชจ๋“ˆ(+ํŒจ๋ธŒ๋ฆญ ์ปดํฌ๋„ŒํŠธ)์„ ์ œ๊ณตํ•˜์ง€๋งŒ, RN 0.69 ๋ฒ„์ „ ์ด์ „ ํ™˜๊ฒฝ์—์„œ๋Š” ์ž„ํฌํŠธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ๋ณด์™„ํ•˜๊ธฐ ์œ„ํ•ด ๋ช‡ ๊ฐ€์ง€ ํ•˜์œ„ ํ˜ธํ™˜์šฉ ์„ค์ •์„ ์ค€๋น„ํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์œ„ ํ˜ธํ™˜ ์„ค์ •์„ ์ถฉ๋ถ„ํžˆ ํ–ˆ๊ธฐ ๋–„๋ฌธ์—, ์ด๋Š” ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ํ•„์ˆ˜ ์š”๊ฑด์€ ์•„๋‹™๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ƒˆ๋กœ์šด ์•„ํ‚คํ…์ฒ˜(Fabric, TurboModule)๊ฐ€ React Native ๊ฐœ๋ฐœ์ž๋“ค์˜ ๋‹ค์–‘ํ•œ ๊ธฐ์ˆ ์  ์„ฑ๋Šฅ ์š”์ฒญ์— ๋Œ€ํ•œ Facebook์˜ ๋Œ€๋‹ต์ธ ๊ฒƒ์„ ์ƒ๊ฐํ•˜๋ฉด, ์•ž์œผ๋กœ ๋” ๋งŽ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ”„๋กœ์ ํŠธ์™€ ReactNative ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐœ๋ฐœ๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค.

```typescript
/// index.tsx
const isTurboModuleEnabled = global.__turboModuleProxy != null;

const SegwayBleManagerModule = isTurboModuleEnabled
? require('./NativeSegwayBleManager').default
: NativeModules.SegwayBleManager;
```

์œ„์˜ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋ธŒ๋ฆฟ์ง€ ์—ญํ• ์„ ํ•˜๋Š” ์ฝ”๋“œ์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ๋Š” Global ๋ณ€์ˆ˜์˜ ํ”„๋กœํผํ‹ฐ๋กœ ํ„ฐ๋ณด๋ชจ๋“ˆํ”„๋ก์‹œ๊ฐ€ ์„ ์–ธ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  (์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๋ช…์‹œ์ ์œผ๋กœ ์„ ์–ธํ•˜์ง€ ์•Š๋Š” ๋”๋ธ” ์–ธ๋”๋ฐ” ๋ณ€์ˆ˜์ด๋ฉฐ, C++ ๋ชจ๋“ˆ์—์„œ ์ฃผ์ž…๋จ), ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— New Architecture๊ฐ€ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•œ ํ›„, ํ™œ์„ฑํ™”๋˜์–ด ์žˆ๋‹ค๋ฉด NativeModules์—์„œ ์ธ๋ฑ์Šค๋กœ ๋ณดํ†ต์˜ ๋ฆฌ์•กํŠธ๋„ค์ดํ‹ฐ๋ธŒ๋กœ ๊ตฌํ˜„๋œ ์„ธ๊ทธ์›จ์ด ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์˜ค๋Š” ํ˜•ํƒœ๋ฅผ ์ทจํ•˜๊ณ , (์ด ๋ถ€๋ถ„์€ ํƒ€์ž… ์„ธ์ดํ”„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.) ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด ํ„ฐ๋ณด๋ชจ๋“ˆ์„ ๊ตฌํ˜„ํ•˜๋Š” ์„ธ๊ทธ์›จ์ด ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์˜ค๋Š” ํ˜•ํƒœ๋ฅผ ์ทจํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‘ ์•„ํ‚คํ…์ณ์˜ ์„ฑ๋Šฅ์—๋Š” ์ฐจ์ด๊ฐ€ ์žˆ์ง€๋งŒ ๋‹ค๋ฅธ ๋ชจ๋“  ๋™์ž‘๊ณผ ๋ฐ์ดํ„ฐ ์œ ํ˜•์€ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.
```groovy
android {
sourceSets {
main {
jniLibs.srcDirs += ["lib"]
//noinspection GroovyImplicitNullArgumentCall
if (isNewArchitectureEnabled()) {
java.srcDirs += [
"src/newarch",
// This is needed to build Kotlin project with NewArch enabled
"${project.buildDir}/generated/source/codegen/java"
]
} else {
java.srcDirs += ["src/oldarch"]
}
}
}
}
```

์œ„ ์ฝ”๋“œ๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ ๋นŒ๋“œ ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค. isNewArchitectureEnabled๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ ์ƒˆ ์•„ํ‚คํ…์ฒ˜ ๋ณ€์ˆ˜๊ฐ€ true๋กœ ์„ค์ •๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•œ ๋‹ค์Œ, src ํด๋”์˜ ์ƒˆ arch ๋””๋ ‰ํ† ๋ฆฌ์—์„œ NativeModuleSpec ์ถ”์ƒ ํด๋ž˜์Šค์™€ ReactNativeCodeGen์˜ ๊ตฌ์„ฑ ํŒŒ์ผ์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. false๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ์„ ์–ธํ•œ ์ด์ „ ์•„์น˜์— ์žˆ๋Š” ์ถ”์ƒ ํด๋ž˜์Šค๋ฅผ ์ž„ํฌํŠธํ•ฉ๋‹ˆ๋‹ค. ๋‘ ํด๋ž˜์Šค์˜ ์ด๋ฆ„๊ณผ ์ฃผ์š” ์†์„ฑ์€ ์ •ํ™•ํžˆ ๋™์ผํ•˜์ง€๋งŒ ๋‚ด๋ถ€ ๊ตฌํ˜„์€ ํ„ฐ๋ณด ๋ชจ๋“ˆ๊ณผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

```diagram
android
โ”œโ”€ build.gradle
โ”œโ”€ gradle.properties
โ””โ”€ src
โ”œโ”€ main
โ”‚ โ”œโ”€ AndroidManifest.xml
โ”‚ โ”œโ”€ java
โ”‚ โ”‚ โ””โ”€ com
โ”‚ โ”‚ โ””โ”€ gBike
โ”‚ โ”‚ โ””โ”€ segwayBleManager
โ”‚ โ”‚ โ”œโ”€ SegwayBleManagerModule.kt
โ”‚ โ”‚ โ””โ”€ SegwayBleManagerPackage.kt
โ”‚ โ””โ”€ newArch
โ”‚ โ””โ”€ SegwayBleManagerSpec.kt
โ””โ”€โ”€โ”€โ”€ oldArch
โ””โ”€ SegwayBleManagerSpec.kt
/// no need to think about to implement which class.
```

์œ„์˜ ๋‹ค์ด์–ด๊ทธ๋žจ์€ ํ•ด๋‹น ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ ์‹ค์ œ ๊ตฌ์กฐ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ๋‘ ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ด๋ฆ„์€ ๋ชจ๋‘ SegwayBleManagerSpec.kt์ด๋ฉฐ, ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ์ ์ ˆํ•œ arch ๋””๋ ‰ํ† ๋ฆฌ์— ์ ‘๊ทผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ„๋‹จํ•œ ํด๋ž˜์Šค ์ด๋ฆ„๋งŒ ์‚ฌ์šฉํ•˜์—ฌ SegwayBleManagerModule.kt๋ฅผ ์ž„ํฌํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

## ์ฐจ๋Ÿ‰ ๋ฐ IoT ๋ชจ๋“ˆ ์ƒํƒœ

์ด ์ฝ”๋“œ๋Š” ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋กœ ์ž‘์„ฑ๋˜์—ˆ์œผ๋ฉฐ ์ฐจ๋Ÿ‰ ์ •๋ณด ๋ฐ IoT ๋””๋ฐ”์ด์Šค ์ •๋ณด์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ง€์›๋˜๋Š” ์ด๋ฒคํŠธ ์ด๋ฆ„์— ๋Œ€ํ•œ ์—ด๊ฑฐ๋„ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

`Scooter` ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์Šค์ฟ ํ„ฐ ๋ฒˆํ˜ธ, ๋””๋ฐ”์ด์Šค MAC ์ฃผ์†Œ, ๋””๋ฐ”์ด์Šค ํ‚ค, IMEI์™€ ๊ฐ™์€ ์Šค์ฟ ํ„ฐ์— ๋Œ€ํ•œ ์†์„ฑ์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

```typescript
export interface Scooter {
number: string;
deviceMac: string;
deviceKey: string;
iotImei: string;
}
```

`VehicleInfo` ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋ฐฐํ„ฐ๋ฆฌ ๋ฐฑ๋ถ„์œจ ๊ฐ’, ์†๋„ ๋ชจ๋“œ, ํ˜„์žฌ ์†๋„, ์ด ์ฃผํ–‰ ๊ฐ€๋Šฅ ๊ฑฐ๋ฆฌ, ๋‚จ์€ ์ฃผํ–‰ ๊ฐ€๋Šฅ ๊ฑฐ๋ฆฌ ๋“ฑ ์ฐจ๋Ÿ‰ ์ •๋ณด์— ๋Œ€ํ•œ ์†์„ฑ์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ Android์—์„œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ Java์—์„œ๋Š” ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ณ  iOS์—๋Š” ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ผ๋ถ€ ์‚ฌ์šฉ ์ค‘๋‹จ๋œ ํ”„๋กœํผํ‹ฐ๋„ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ํ”„๋กœํผํ‹ฐ๋Š” `powerPercent` ๋ฐ `speedMode`์™€ ๊ฐ™์€ ์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ๋กœ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค.

```typescript
export interface VehicleInfo {
powerPercent: number;
speedMode: number;
currentSpeed: number;
totalRange: number;
remainingRange: number;
}
```

`IoTInformation` ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋ฐฐํ„ฐ๋ฆฌ์˜ ์ตœ์ €์ „์•• ๋ฐ ์ตœ๊ณ ์ „์••, ์ถฉ์ „ ์ƒํƒœ, ๋ฒ„์ „ ๋ฒˆํ˜ธ์™€ ๊ฐ™์€ IoT ๋””๋ฐ”์ด์Šค์˜ ์ •๋ณด์— ๋Œ€ํ•œ ์†์„ฑ์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜์ธ๋ด‡์˜ ๋ชจ๋“ˆ ํŠน์„ฑ ์ƒ iOS์™€ Android์˜ ์ธํ„ฐํŽ˜์ด์Šค์™€ ๋ฐ์ดํ„ฐํƒ€์ž…์ด ์™„์ „ํžˆ ์ผ์น˜ํ•˜์ง€๋Š” ์•Š์•„, ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” @deprecated ํ”„๋กœํผํ‹ฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉฐ, ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์‚ฌ์šฉ ์‹œ์— JSDoc์„ ํ†ตํ•ด ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ๊ฐ `majorVersionNumber`, `minorVersionNumber`, `updateTimes`์™€ ๊ฐ™์€ ์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ๋กœ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค.

```typescript
export interface IoTInformation {
lowBatteryVoltage: number;
highBatteryVoltage: number;
powerStatus: number;
majorVersionNumber: number;
minorVersionNumber: number;
versionRevisions: number;
modifiedTimes: number;
updateTimes: number;
isLocked: boolean;
voltage: number;
}
```

๋งˆ์ง€๋ง‰์œผ๋กœ `EventNames` ์ด๋„˜ ํƒ€์ž…์€ ์ง€์›๋˜๋Š” ์ด๋ฒคํŠธ ์ด๋ฆ„์„ ์ •์˜ํ•˜๋ฉฐ, ์ด๋Š” ๋„ค์ดํ‹ฐ๋ธŒ ๋ชจ๋“ˆ์˜ ์ด๋ฒคํŠธ ์ด๋ฆ„๊ณผ ๋™์ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

```typescript
export interface IoTInformation {
lowBatteryVoltage: number;
highBatteryVoltage: number;
powerStatus: number;
majorVersionNumber: number;
minorVersionNumber: number;
versionRevisions: number;
modifiedTimes: number;
updateTimes: number;
isLocked: boolean;
voltage: number;
}
```

## ์ธํ„ฐํŽ˜์ด์Šค ์ƒ์„ธ ์ •๋ณด

๋ชจ๋“ˆ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค:

### `getConstants()`

์ด ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์Œ ์†์„ฑ์„ ๊ฐ€์ง„ ์ƒ์ˆ˜ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค:

- `supportedEvents`: ์ง€์›๋˜๋Š” ์ด๋ฒคํŠธ ์œ ํ˜• ๋ฐฐ์—ด
- `moduleName`: ๋ชจ๋“ˆ์˜ ์ด๋ฆ„

### `init(secretKey: string, operatorCode: string, isDebug: boolean): Promise<boolean>`

์ด ๋ฉ”์„œ๋“œ๋Š” ๋น„๋ฐ€ ํ‚ค, ์˜คํผ๋ ˆ์ดํ„ฐ ์ฝ”๋“œ, ๊ทธ๋ฆฌ๊ณ  ๋ชจ๋“ˆ์ด ๋””๋ฒ„๊ทธ ๋ชจ๋“œ๋กœ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š”์ง€์˜ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ํ”Œ๋ž˜๊ทธ๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“ˆ์„ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ดˆ๊ธฐํ™”์— ์„ฑ๊ณตํ–ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ถ€์šธ ๊ฐ’์œผ๋กœ ํ™•์ธ๋˜๋Š” ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

### `connect(deviceMac: string, deviceKey: string, iotImei: string): void`

์ง€์ •๋œ MAC ์ฃผ์†Œ, ๋””๋ฐ”์ด์Šค ํ‚ค, IoT IMEI๋กœ ์„ธ๊ทธ์›จ์ด ์ฐจ๋Ÿ‰์— ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

### `disconnect(): Promise<boolean>`

์„ธ๊ทธ์›จ์ด ์ฐจ๋Ÿ‰๊ณผ์˜ ์—ฐ๊ฒฐ์„ ๋Š๊ณ  ์—ฐ๊ฒฐ ๋Š๊ธฐ ์„ฑ๊ณต ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ถ€์šธ ๊ฐ’์œผ๋กœ ํ™•์ธ๋˜๋Š” ํ”„๋กœ๋ฏธ์Šค๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

### `unLock(): Promise<boolean>`

์„ธ๊ทธ์›จ์ด ์ฐจ๋Ÿ‰์˜ ์ž ๊ธˆ์„ ํ•ด์ œํ•˜๊ณ  ์ž ๊ธˆ ํ•ด์ œ๊ฐ€ ์„ฑ๊ณตํ–ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ถ€์šธ ๊ฐ’์œผ๋กœ ํ™•์ธ๋˜๋Š” ํ”„๋กœ๋ฏธ์Šค๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

### `lock(): Promise<boolean>`

์„ธ๊ทธ์›จ์ด ์ฐจ๋Ÿ‰์„ ์ž ๊ทธ๊ณ  ์ž ๊ธˆ์ด ์„ฑ๊ณตํ–ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ถ€์šธ ๊ฐ’์œผ๋กœ ํ™•์ธ๋˜๋Š” ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.

### `openBatteryCover(): Promise<boolean>`

์„ธ๊ทธ์›จ์ด ์ฐจ๋Ÿ‰์˜ ๋ฐฐํ„ฐ๋ฆฌ ์ปค๋ฒ„๋ฅผ ์—ด๊ณ  ์ž‘์—… ์„ฑ๊ณต ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ถ€์šธ ๊ฐ’์œผ๋กœ ํ•ด์„๋˜๋Š” ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.

### `openSaddle(): Promise<boolean>`

์„ธ๊ทธ์›จ์ด ์ฐจ๋Ÿ‰์˜ ์•ˆ์žฅ์„ ์—ด๊ณ  ์ž‘์—… ์„ฑ๊ณต ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ถ€์šธ ๊ฐ’์œผ๋กœ ํ•ด์„๋˜๋Š” ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.

### `openTailBox(): Promise<boolean>`

์„ธ๊ทธ์›จ์ด ๋น„ํžˆํด์˜ ํ…Œ์ผ ๋ฐ•์Šค๋ฅผ ์—ด๊ณ  ์ž‘์—… ์„ฑ๊ณต ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ถ€์šธ ๊ฐ’์œผ๋กœ ํ•ด์„๋˜๋Š” ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค.

### `queryVehicleInformation(listener): void`

์„ธ๊ทธ์›จ์ด ์ฐจ๋Ÿ‰์— ํŽŒ์›จ์–ด ๋ฒ„์ „, ์‹œ๋ฆฌ์–ผ ๋ฒˆํ˜ธ, ๋ฐฐํ„ฐ๋ฆฌ ์ž”๋Ÿ‰ ๋“ฑ ๋””๋ฐ”์ด์Šค์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ฟผ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

### `queryIoTInformation(listener): void`

์„ธ๊ทธ์›จ์ด ์ฐจ๋Ÿ‰ ๋””๋ฐ”์ด์Šค์˜ ๋„คํŠธ์›Œํฌ ์ƒํƒœ, ์‹ ํ˜ธ ์„ธ๊ธฐ, IMEI์™€ ๊ฐ™์€ IoT ์ •๋ณด๋ฅผ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.

## Contributing

See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.

## License

MIT

---

Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ android {

sourceSets {
main {
jniLibs.srcDirs += ["lib"]
jniLibs.srcDirs += ["libs"]
//noinspection GroovyImplicitNullArgumentCall
if (isNewArchitectureEnabled()) {
java.srcDirs += [
Expand Down
Loading

0 comments on commit f6789d4

Please sign in to comment.