react-native-ble-advertiser
react-native-ble-advertiser copied to clipboard
BLEAdvertiser returns null in IOS
Whenever I use BLEAdvertiser on IOS is returns null values. I am a n00b so I am would be very happy to hear I missed a permissions setting or something but I cannot for the life of me get this to work. It works perfectly in Android. Here is my code:
import React, {Component} from 'react';
import { Alert, SafeAreaView, StyleSheet, View, Text, TouchableOpacity, FlatList, Platform, } from 'react-native';
import {NativeEventEmitter, NativeModules} from 'react-native';
import {RCTBluetoothManager} from 'react-native';
import update from 'immutability-helper'; import BLEAdvertiser from 'react-native-ble-advertiser'; import UUIDGenerator from 'react-native-uuid-generator'; import {PermissionsAndroid} from 'react-native';
// Uses the Apple code to pick up iPhones const APPLE_ID = 0xFFFF; const MANUF_DATA = [0X42]; // No scanner filters (finds all devices inc iPhone). Use UUID suffix to filter scans if using. const SCAN_MANUF_DATA = Platform.OS === 'android' ? null : MANUF_DATA; //const SCAN_MANUF_DATA = MANUF_DATA;
if (Platform.OS === 'android'){ BLEAdvertiser.setCompanyId(APPLE_ID); }
//BLEAdvertiser.setCompanyId(APPLE_ID);
export async function requestLocationPermission() { try { if (Platform.OS === 'android') { const fineLocationGranted = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, ); const bleAdvertiseGranted = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.BLUETOOTH_ADVERTISE, ); const bleScanGranted = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN, ); const bluetoothConnectGranted = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT, ); const finLocGrantMessage = fineLocationGranted == PermissionsAndroid.RESULTS.GRANTED ? 'Location Permission granted':'Location Permission denied'; const bleAdvGrantMessage = bleAdvertiseGranted == PermissionsAndroid.RESULTS.GRANTED ? 'BLE Advertise Permission granted':'BLE Advertise Permission denied'; const bleScanGrantMessage = bleScanGranted == PermissionsAndroid.RESULTS.GRANTED ? 'BLE Scan Permission granted':'BLE Scan Permission denied'; const bluetoothConGrantMessage = bluetoothConnectGranted == PermissionsAndroid.RESULTS.GRANTED ? 'Bluetooth Connect Permission granted':'Bluetooth Connect Permission Denied'; console.log(finLocGrantMessage); console.log(bleAdvGrantMessage); console.log(bleScanGrantMessage); console.log(bluetoothConGrantMessage); }
const blueoothActive = await BLEAdvertiser.getAdapterState()
.then((result) => {
console.log('[Bluetooth]', 'Bluetooth Status', result);
return result === 'STATE_ON';
})
.catch((error) => {
console.log('[Bluetooth]', 'Bluetooth Not Enabled');
return false;
});
if (!blueoothActive) {
await Alert.alert(
'The Gate App requires bluetooth to be enabled',
'Would you like to enable Bluetooth?',
[
{
text: 'Yes',
onPress: () => BLEAdvertiser.enableAdapter(),
},
{
text: 'No',
onPress: () => console.log('Do Not Enable Bluetooth Pressed'),
style: 'cancel',
},
],
);
}
} catch (err) { console.warn(err); } }
class Entry extends Component { constructor(props) { const uuid = '123e4567-e89b-12d3-a456-426655440000'; super(props); this.state = { //uuid: '', uuid: uuid, isLogging: false, devicesFound: [], }; }
addDevice(_uuid, _name, _mac, _rssi, _date) { const index = this.state.devicesFound.findIndex(({uuid}) => uuid === _uuid); if (index < 0) { this.setState({ devicesFound: update(this.state.devicesFound, { $push: [ { uuid: _uuid, name: _name, mac: _mac, rssi: _rssi, start: _date, end: _date, }, ], }), }); } else { this.setState({ devicesFound: update(this.state.devicesFound, { [index]: { end: {$set: _date}, rssi: {$set: _rssi || this.state.devicesFound[index].rssi}, }, }), }); } }
componentDidMount() { requestLocationPermission(); //const eventEmitter = new NativeEventEmitter(NativeModules.BLEAdvertiser); //eventEmitter.addListener('onDeviceFound', (event) => { // BLEAdvertiser.setCompanyId(APPLE_ID); //}); console.log("Running start() in the componentDidMount function");
}
// componentDidMount() { // requestLocationPermission(); // UUIDGenerator.getRandomUUID((newUid) => { // this.setState({ // uuid: newUid.slice(0, -2) + '00', // }); // }); //}
componentWillUnmount() { if (this.state.isLogging) { this.stop(); } }
start() {
const eventEmitter = new NativeEventEmitter(NativeModules.BLEAdvertiser);
//eventEmitter.addListener('onDeviceFound', (event) => {
// console.log("I stopped eating chickens because they are alive")
//});
console.log(this.state.uuid, 'Starting Advertising');
BLEAdvertiser.broadcast(this.state.uuid, MANUF_DATA, {
advertiseMode: BLEAdvertiser.ADVERTISE_MODE_BALANCED,
txPowerLevel: BLEAdvertiser.ADVERTISE_TX_POWER_HIGH,
connectable: false,
includeDeviceName: false,
includeTxPowerLevel: false,
})
.then((sucess) => console.log(this.state.uuid, 'Adv Successful', sucess))
.catch((error) => console.log(this.state.uuid, 'Adv Error', error));
console.log(this.state.uuid, 'Starting Scanner');
BLEAdvertiser.scan(SCAN_MANUF_DATA, {
scanMode: BLEAdvertiser.SCAN_MODE_LOW_LATENCY,
})
.then((sucess) => console.log(this.state.uuid, 'Scan Successful', sucess))
.catch((error) => console.log(this.state.uuid, 'Scan Error', error));
this.setState({
isLogging: true,
});
}
stop() { /* console.log(this.state.uuid, 'Removing Listener'); this.onDeviceFound.remove(); delete this.onDeviceFound; */ console.log(this.state.uuid, 'Stopping Broadcast'); BLEAdvertiser.stopBroadcast() .then((sucess) => console.log(this.state.uuid, 'Stop Broadcast Successful', sucess)) .catch((error) => console.log(this.state.uuid, 'Stop Broadcast Error', error));
console.log(this.state.uuid, 'Stopping Scanning');
BLEAdvertiser.stopScan()
.then((sucess) => console.log(this.state.uuid, 'Stop Scan Successful', sucess))
.catch((error) => console.log(this.state.uuid, 'Stop Scan Error', error));
this.setState({
isLogging: false,
});
}
short(str) { return ( str.substring(0, 4) + ' ... ' + str.substring(str.length - 4, str.length) ).toUpperCase(); }
render() { return ( <SafeAreaView> <View style={styles.body}> <View style={styles.sectionContainer}> <Text style={styles.sectionTitle}>Gate Opener Demo</Text> <Text style={styles.sectionDescription}> Broadcasting:{' '} <Text style={styles.highlight}> {this.short(this.state.uuid)} </Text> </Text> </View>
<View style={styles.sectionContainer}>
{this.state.isLogging ? (
<TouchableOpacity
onPress={() => this.stop()}
style={styles.stopLoggingButtonTouchable}>
<Text style={styles.stopLoggingButtonText}>Stop</Text>
</TouchableOpacity>
) : (
<TouchableOpacity
onPress={() => this.start()}
style={styles.startLoggingButtonTouchable}>
<Text style={styles.startLoggingButtonText}>Start</Text>
</TouchableOpacity>
)}
</View>
<View style={styles.sectionContainerFlex}>
<Text style={styles.sectionTitle}>Devices Around</Text>
<FlatList
data={this.state.devicesFound}
renderItem={({item}) => (
<Text style={styles.itemPastConnections}>
{this.short(item.uuid)} {item.mac} {item.rssi}
</Text>
)}
keyExtractor={(item) => item.uuid}
/>
</View>
<View style={styles.sectionContainer}>
<TouchableOpacity
onPress={() => this.setState({devicesFound: []})}
style={styles.startLoggingButtonTouchable}>
<Text style={styles.startLoggingButtonText}>Clear Devices</Text>
</TouchableOpacity>
</View>
</View>
</SafeAreaView>
);
} }
const styles = StyleSheet.create({ body: { height: '100%', }, sectionContainerFlex: { flex: 1, marginTop: 12, marginBottom: 12, paddingHorizontal: 24, }, sectionContainer: { flex: 0, marginTop: 12, marginBottom: 12, paddingHorizontal: 24, }, sectionTitle: { fontSize: 24, marginBottom: 8, fontWeight: '600', textAlign: 'center', }, sectionDescription: { fontSize: 18, fontWeight: '400', textAlign: 'center', }, highlight: { fontWeight: '700', }, startLoggingButtonTouchable: { borderRadius: 12, backgroundColor: '#665eff', height: 52, alignSelf: 'center', width: 300, justifyContent: 'center', }, startLoggingButtonText: { fontSize: 14, lineHeight: 19, letterSpacing: 0, textAlign: 'center', color: '#ffffff', }, stopLoggingButtonTouchable: { borderRadius: 12, backgroundColor: '#fd4a4a', height: 52, alignSelf: 'center', width: 300, justifyContent: 'center', }, stopLoggingButtonText: { fontSize: 14, lineHeight: 19, letterSpacing: 0, textAlign: 'center', color: '#ffffff', }, listPastConnections: { width: '80%', height: 200, }, itemPastConnections: { padding: 3, fontSize: 18, fontWeight: '400', }, });
export default Entry;
Make sure you added the following line to Podfile:
pod 'react-native-ble-advertiser', :path => '../node_modules/react-native-ble-advertiser/ios'