Beacons y React Native

Integrar beacons en una aplicación desarrollada con React Native

Image for post
Image for post

Requisitos

Objetivo

Configurando React Native Beacon Manager

Image for post
Image for post
Mi cara tras casi un día pegándome con la librería
npm install @nois/react-native-beacons-manager// 2react-native link react-native-beacons-manager
self.locationManager.allowsBackgroundLocationUpdates = true;
Privacy - Location When In Usage Description
Privacy - Bluetooth Peripheral Usage Description

Código para gestionar el beacon (iOS) — App en Foreground

import Beacons from 'react-native-beacons-manager';const region = {  identifier: 'identifier',  uuid: 'uuid',  major: number,  minor: number};export default function() {  Beacons.requestWhenInUseAuthorization();  Beacons.startMonitoringForRegion(region);  Beacons.startRangingBeaconsInRegion(region);  Beacons.startUpdatingLocation();}
const region = {identifier: 'identifier',uuid: 'uuid'};
componentDidMount() {  Beacons.BeaconsEventEmitter.addListener(    ‘beaconsDidRange’,    data => {      const {        region: { identifier },        beacons      } = data;      this.setState({ beacons });

}
);

Beacons.BeaconsEventEmitter.addListener(

'regionDidEnter',

event => {
// code }
);
Beacons.BeaconsEventEmitter.addListener(

'regionDidExit',

event => {
// code });}
renderRow = rowData => {
return (
<View>
<Text>
UUID: {rowData.uuid ? rowData.uuid : ‘NA’}
</Text>
<Text>
Major: {rowData.major ? rowData.major : ‘NA’}
</Text>
<Text>
Minor: {rowData.minor ? rowData.minor : ‘NA’}
</Text>
<Text>
RSSI: {rowData.rssi ? rowData.rssi : ‘NA’}
</Text>
<Text>
Proximity: {rowData.proximity ? rowData.proximity : ‘NA’}
</Text>
<Text>
Distance: {rowData.accuracy ? rowData.accuracy.toFixed(2) : ‘NA’}m
</Text>
</View>
);
}
render() { const { beacons } = this.state; return ( <FlatList data={ beacons } keyExtractor={item => `b--${item.uuid}`} renderItem={({ item } ) => this.renderRow(item)} /> );}
Image for post
Image for post

Código para gestionar el beacon (iOS) — Background

Image for post
Image for post

⚠️ ¡Importante! Antes de seguir

Habilitar los Background Modes

Image for post
Image for post
From docs of react native background modes

Location Always Usage

Privacy — Location Always Usage Description
Privacy - Location Always and When In Use Usage Description
import Beacons from 'react-native-beacons-manager';const region = {identifier: 'identifier',uuid: 'uuid',major: number,minor: number};export default function() {Beacons.requestAlwaysAuthorization();Beacons.startMonitoringForRegion(region);Beacons.startRangingBeaconsInRegion(region);Beacons.startUpdatingLocation();}
Image for post
Image for post
[BeaconsDemo] AppDelegate: didFinishLaunchingWithOptions enter
[BeaconsDemo] AppDelegate: After jsBundleURLForBundleRoot
[BeaconsDemo] AppDelegate: didFinishLaunchingWithOptions end
// iOS send the event and it is caught by RNiBeacon.m but it has no listeners yet
[BeaconsDemo] regionDidExit
[BeaconsDemo] no listeners in RnIBeacon.m

// First line of javascript --
[BeaconsDemo] start observing
[BeaconsDemo] requestAlwaysAuth
Image for post
Image for post
NSDate *now = [NSDate date];NSDictionary *regionDict = [self convertBeaconRegionToDict: region];NSDictionary *event = @{  @”region”: regionDict,  @”type”: @”didExit”,  @”date”: [NSNumber        numberWithUnsignedInteger:now.timeIntervalSince1970]};[[NSUserDefaults standardUserDefaults] setObject:event forKey:regionDict[@”uuid”]];[[NSUserDefaults standardUserDefaults] synchronize];
RCT_EXPORT_METHOD(startMonitoringForRegion:(NSDictionary *) dictstartMonitoringResolver:(RCTPromiseResolveBlock)resolvestartMonitoringRejecter:(RCTPromiseRejectBlock)reject){  [self.locationManager startMonitoringSignificantLocationChanges];  [self.locationManager startMonitoringForRegion:[self   

convertDictToBeaconRegion:dict]];
NSDictionary *lastEvent = [[NSUserDefaults standardUserDefaults] objectForKey:[dict objectForKey:@”uuid”]]; resolve(lastEvent);}
Beacons.startMonitoringForRegion(region).then(lastEvent => {  if (lastEvent) {    const now = new Date();    if (now.getTime() / 1000 — lastEvent.date < 60) {      if (lastEvent.type === ‘didEnter’) {        regionDidEnter(lastEvent.region);      } else {        regionDidExit(lastEvent.region);      }  }}});

Conclusión

¿Quieres recibir más artículos como este?

Entre paseo y paseo con Simba desarrollo en Symfony y React

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store