1

I have an IoT device which is sending iBeacon advertisements and want to detect these signals on my react-native application.

I found this library react-native-kontaktio. It works fine on android, but on ios it does not look like the "didDiscoverDevices" event gets triggered since the console.log is not showing up in my terminal. The app is running and i get no error message.

To configure this library for iOS i did the following:

  1. yarn add react-native-kontaktio
  2. cd ios
  3. pod install

I have also included these permissions in info.plist: NSBluetoothAlwaysUsageDescription, NSLocationAlwaysAndWhenInUseUsageDescription

This is my react-native version: react-native-cli: 2.0.1, react-native: 0.66.4.

This is the code which is working on android, but not on iOS.

 import React, {useEffect, useState} from 'react';
    import {
      Alert,
      DeviceEventEmitter,
      NativeEventEmitter,
      Platform,
      PermissionsAndroid,
      SafeAreaView,
      Text,
      StyleSheet,
      Button,
    } from 'react-native';

    import Kontakt, {KontaktModule} from 'react-native-kontaktio';
    
    const {connect, init, startDiscovery, startScanning} = Kontakt;
    
    const kontaktEmitter = new NativeEventEmitter(KontaktModule);
    
    const isAndroid = Platform.OS === 'android';
    const isIOS = Platform.OS === 'ios';
    
    const App = () => {
      /**
       * Android Marshmallow (6.0) and above need to ask the user to grant certain permissions.
       * This function does just that.
       */
      const requestLocationPermission = async () => {
        try {
          const granted = await PermissionsAndroid.request(
            PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
            {
              title: 'Location Permission',
              message:
                'This example app needs to access your location in order to use bluetooth beacons.',
              buttonNeutral: 'Ask Me Later',
              buttonNegative: 'Cancel',
              buttonPositive: 'OK',
            },
          );
          if (granted === PermissionsAndroid.RESULTS.GRANTED) {
            return true;
          } else {
            // permission denied
            return false;
          }
        } catch (err) {
          console.warn(err);
          return false;
        }
      };
    
      const beaconSetup = async () => {
        if (isAndroid) {
          // Android
          const granted = await requestLocationPermission();
          if (granted) {
            await connect();
            await startScanning();
          } else {
            Alert.alert(
              'Permission error',
              'Location permission not granted. Cannot scan for beacons',
              [{text: 'OK', onPress: () => console.log('OK Pressed')}],
              {cancelable: false},
            );
          }
        } else {
          // iOS
          console.log('IOS', isIOS);
          await init();
          await startDiscovery();
        }
    
    // Add beacon listener
    if (isAndroid) {
      DeviceEventEmitter.addListener(
        'beaconsDidUpdate',
        ({beacons, region}) => {
          console.log('beaconsDidUpdate', beacons, region);
          console.log('REGION: ', region);
          console.log('BEACONS', beacons);
        }
      );
    } else {
      console.log('IOS ADD LISTENER');
      kontaktEmitter.addListener('didDiscoverDevices', ({beacons}) => {
        console.log('didDiscoverDevices', beacons);
        console.log('IOS DISCOVERED BEACON');
      });
    }
  };

      useEffect(() => {
        beaconSetup();
        return () => {
          DeviceEventEmitter.removeAllListeners();
        };
      }, []);
cc_9313
  • 219
  • 2
  • 8
  • Do you ask for location permission on iOS? Do you receive permission? Where do you set the uuid for the iBeacon you are looking for? – Paulw11 Jan 10 '22 at 12:34
  • Thank you for commenting. I just solved the problem. I called startRangingBeaconsInRegion instead of startDiscovery method and then it worked. I understood this after i read this sentence in documentation: "Discovery (i.e. didDiscoverDevices) can only detect Kontakt.io beacons. Ranging and monitoring also works with beacons of other manufacturers." – cc_9313 Jan 10 '22 at 12:40

1 Answers1

0

I just solved the problem.

I called startRangingBeaconsInRegion(region) instead of startDiscovery() method and then it worked. I understood this after I read this sentence in documentation: "Discovery (i.e. didDiscoverDevices) can only detect Kontakt.io beacons. Ranging and monitoring also works with beacons of other manufacturers."

Tyler2P
  • 2,324
  • 26
  • 22
  • 31
cc_9313
  • 219
  • 2
  • 8