728x90
BLE의 정의 및 참고 사이트
https://tlseoqja.tistory.com/38
코드
Swift가 아닌 Object-C를 사용해서 코드를 작성하였다.
1. BLE 권한 추가
ios 폴더의 프로젝트 폴더의 Info.plist 파일을 열어서 블루투스 사용 권한을 넣어준다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
...
<key>NSBluetoothAlwaysUsageDescription</key>
<string>use BLE Advertising</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>use BLE Advertising</string>
...
</dict>
</plist>
2. 모듈 파일 생성
x-Code에서 프로젝트의 ios 폴더를 열고, Header 파일과 Metal 파일을 생성해준다.
※ x-Code가 아닌 VS에서 파일을 생성할 경우 파일이 정상적으로 실행되지 않는다.
위의 과정을 거치면 확장자 .h 파일과 확장자 .m 파일이 생성된다.
728x90
3. Header File ( RCTBLEModule.h )
#import <React/RCTBridgeModule.h>
@interface RCTBLEModule : NSObject <RCTBridgeModule>
@end
3-2. Metal File ( RCTBLEModule.m )
uuid를 packet에 따라 변동해서 사용하기 위해 React Native 코드에서 data를 전달받은 후 startAdvertising 하는 코드이다.
※ CoreBluetooth 모듈에서 LocalNameKey와 ServiceUUIDsKey를 제외한 데이터의 변경은 허용하지 않는다.
#import <React/RCTBridgeModule.h>
#import <CoreBluetooth/CoreBluetooth.h>
@interface RCTBLEModule : NSObject <RCTBridgeModule, CBPeripheralManagerDelegate>
@property (nonatomic, strong) CBPeripheralManager *peripheralManager;
@property (nonatomic, strong) NSDictionary *advertisementData;
@end
@implementation RCTBLEModule
RCT_EXPORT_MODULE(IOSBLEModule);
RCT_EXPORT_METHOD(IOSstartAdvertising:(NSString *) data) {
self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
self.advertisementData = @{
// CBAdvertisementDataLocalNameKey: data,
CBAdvertisementDataServiceUUIDsKey:@[[CBUUID UUIDWithString:data]]
};
[self.peripheralManager startAdvertising: self.advertisementData];
NSLog(@"BLE Advertising Success");
}
RCT_EXPORT_METHOD(IOSstopAdvertising) {
[self.peripheralManager stopAdvertising];
}
@end
3-3. React Native에서 iOS 코드 사용하기
src/module/nativeModule.ts
import { NativeModules } from "react-native";
...
export interface IIOSBLEModule {
IOSstartAdvertising: (data: string) => void;
IOSstopAdvertising: () => void;
}
export default {
...
...NativeModules.IOSBLEModule as IIOSBLEModule,
};
src/hooks/useBluetooth.ts
import { useState, useEffect, useCallback } from "react";
import nativeModules from "../module/nativeModules";
import BackgroundTimer from "react-native-background-timer";
const {
startAdvertising,
stopAdvertising,
IOSstartAdvertising,
IOSstopAdvertising,
} = nativeModules;
const useBluetooth = () => {
const [isTransmitter, setIsTransmitter] = useState(false);
const transmitterMs = 5000;
// 광고 데이터 송신 시작 함수
const onStartAdvertising = useCallback((hexString: string, uuid: string) => {
setIsTransmitter(true);
try {
if( Platform.OS === "android" ) {
startAdvertising(hexString);
} else {
// iOS Advertising 시작
IOSstartAdvertising(uuid);
}
} catch (error) {
console.log(error);
}
}, []);
// 지정한 시간 후에 BLE 광고를 종료한다.
useEffect(() => {
if (isTransmitter) {
const timer = BackgroundTimer.setTimeout(() => {
setIsTransmitter(false);
// 광고 데이터 송신 종료 함수
if ( Platform.OS === "android" ) {
stopAdvertising();
} else {
// iOS Advertising 종료
IOSstopAdvertising();
}
}, transmitterMs);
return () => BackgroundTimer.clearTimeout(timer);
}
}, [isTransmitter, transmitterMs]);
return {
onStartAdvertising,
};
};
export default useBluetooth;
App.tsx
import { TouchableOpacity, View, Text } from "react-native";
import useBluetooth from "./src/hooks/useBluetooth";
const ViewStyle = {
flex: 1,
justifyContent: "center",
alignItems: "center",
};
const ButtonStyle = {
backgroundColor: "red",
padding: 10,
border: "1px solid black",
borderRadius: 5
};
const TextStyle = {
color: "white",
};
const App = () => {
const { onStartAdvertising } = useBluetooth();
const bleAdvertising = () => {
const manufacturerData = "1111111111";
const uuid = "11111111-1111-1111-1111-111111111111";
onStartAdvertising(manufacturerData, uuid);
};
return (
<View
style={ViewStyle}
>
<TouchableOpacity
onPress={bleAdvertising}
style={ButtonStyle}
>
<Text style={TextStyle}>BLE 광고</Text>
</TouchableOpacity>
</View>
);
};
export default App;
728x90
'📱Mobile > React Native' 카테고리의 다른 글
[React Native] react-native-geolocation-service 라이브러리를 사용해보자 (0) | 2024.01.18 |
---|---|
[React Native] 앱 종료 시에도 React Native 코드 실행 (0) | 2023.12.18 |
[React Native] Android BLE Advertising (0) | 2023.09.14 |
[React Native] Kakao Login 구현하기 (2) | 2023.03.28 |
[React Native] Naver Login 구현하기 (0) | 2023.03.28 |
댓글