React Native

Integrate the Colocator React Native library into your React Native app

Adding the dependency

Install and link the module using the terminal

$ npm install react-native-colocator-library --save
$ react-native link react-native-colocator-library

Integration

Autolinking doesn't complete the integration process and there are a few more steps to do

Android

In the build.gradle file of your project add

allprojects {
    repositories {
        maven { url "http://maven.crowdconnected.net/" }
    }
}

iOS

In Build Settings of your project, in BuildOptions category, set Enable Bitcode to “No”

In Project Navigator, right click on Frameworks folder and choose “Add files to «Project Name»…”

Check “Copy items if needed” then go to node_modules ➜ react-native-colocator-library ➜ ios ➜ Carthage ➜ Build ➜ iOS

Add CCLocation.framework, Result.framework, ReSwift.framework, SocketRocket.framework, SwiftProtobuf.framework and TrueTime.framework

In Project Navigator, select “RNColocatorLibrary.xcodeproj” from Libraries folder. Go to Build Settings and add the following as recursive in Header Search Paths

  • $(inherited)
  • $(SRCROOT)/../../../React
  • $(SRCROOT)/../../react-native/React
  • ${SRCROOT}/../../../ios/Pods/Headers

In the same section, add the following as non-recursive in Framework Search Paths

  • $(inherited)
  • $(PROJECT_DIR)/Carthage/Build/iOS

Getting Permission

Android

Request location permission in App.js

import { PermissionsAndroid } from 'react-native';

const granted = await PermissionsAndroid.check( PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION );

if (granted) {
  console.log( "You can use the ACCESS_FINE_LOCATION" )
} else {
  console.log( "ACCESS_FINE_LOCATION permission denied" )
}

iOS

Add the Background Modes in info.plist file of your iOS project

<key>UIBackgroundModes</key>
<array>
    <string>location</string>
    <string>fetch</string>
    <string>remote-notification</string>
</array>

Add Permission Descriptors in info.plist file of your iOS project

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>YOUR_TEXT_GOES_HERE</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>YOUR_TEXT_GOES_HERE</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>YOUR_TEXT_GOES_HERE</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>YOUR_TEXT_GOES_HERE</string>

If you will use Colocator for Indoor Services, also add the next items in info.plist

<key>UIBackgroundModes</key>
<array>
    <string>bluetooth-central</string>
    <string>bluetooth-peripheral</string>
</array>
<key>NSBluetoothAlwaysUsageDescription</key>
<string>YOUR_TEXT_GOES_HERE</string>
<key>NSMotionUsageDescription</key>
<string>YOUR_TEXT_GOES_HERE</string>

For more details about these permissions in the iOS section

Location Permission

Request location permission in App.js

import Geolocation from '@react-native-community/geolocation';

if(Platform.OS === "ios") {
   geolocation.requestAuthorization()
}

Bluetooth Permission - Used for Indoor Location Service

Request Bluetooth permission in App.js

RNColocatorLibrary.triggerBluetoothPermissionPopUp()

Motion Permission - Used for Indoor Location Service

Request Motion permission in App.js

RNColocatorLibrary.triggerMotionPermissionPopUp()

Enabling Location Gathering

Import the library

In JS files import the library using the following line

import RNColocatorLibrary from 'react-native-colocator-library';

In iOS files import the library using the following line

#import <CCLocation/CCLocation-Swift.h>

Start the library

In iOS, the library must be started within the - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method of the AppDelegate.m.

[CCLocation.sharedInstance startWithApiKey:APP_KEY urlString:@"colocator.net:443/socket"];

It may additionally be started elsewhere in your JS file to fit in with your onboarding flow.

RNColocatorLibrary.start(YOUR_APP_KEY)

Background Refresh

We use background refresh to periodically check whether we should enable location tracking. Please enable this by registering for Background Refresh events in AppDelegate.m:

[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:60];

and calling the library when one occurs:

-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    // At background refresh, the CCLocation library should be notified to update its state
    [CCLocation.sharedInstance updateLibraryBasedOnClientStatusWithClientKey:CC_API_KEY isSilentNotification:false completion:^(BOOL result) {}];
}

Silent Push Notifications

We use Silent Push Notifications to enable location tracking at a given time. Please enable this in AppDelegate.m by:

  1. Ensuring the app has notification permission
  2. Registering for remote notifications
[[UIApplication sharedApplication] registerForRemoteNotifications];
  1. Sending the APNS Token as an alias:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    // For CCLocation messaging feature, send device token to the library as an alias
    NSString * deviceTokenString = [[[[deviceToken description]
     stringByReplacingOccurrencesOfString: @"<" withString: @""]
     stringByReplacingOccurrencesOfString: @">" withString: @""]
     stringByReplacingOccurrencesOfString: @" " withString: @""];
    [CCLocation.sharedInstance addAliasWithKey:@"apns_user_id" value:deviceTokenString];
}
  1. Calling the library when one is received:
NSDictionary *apsInfo = [userInfo objectForKey:@"apsInfo"];
NSString *source = [apsInfo objectForKey:@"source"];
if ([source isEqualToString:@"colcoator"]) {
    [CCLocation.sharedInstance receivedSilentNotificationWithUserInfo:userInfo clientKey:CC_API_KEY completion:^(BOOL result) {}];
}

Disabling Location Gathering

If required you can stop the library in your js file

RNColocatorLibrary.stop()

Sending an Alias

Aliases are key-value pairs. They are primarily used to send alternative IDs for a device, for example a unique Push Notification identifier. Go to the Push Notification Integrations page for more details

RNColocatorLibrary.addAlias("YOUR_KEY", "YOUR_VALUE")

Indoor Location Service

For indoor location and positioning, a few more steps need to be implemented

Setting the Event Listener

Receive location updates:

  • Set up the Native Event Emitter
const colocatorEmitter = new NativeEventEmitter(RNColocatorLibrary);
  • Add subscription for location events
subscription = colocatorEmitter.addListener(
   'LocationResponse', (response) => // Your code here
);

LocationResponse containts field “floor” starting with version 2.7.1

Location Callbacks - Only for Indoor Navigation Purposes

The latest location can be sent back to the device either as a one-off or a stream of updates. This is primarily used for displaying the location of the device on a map.

Request one location:

RNColocatorLibrary.requestLocation()

Request a stream of location updates:

RNColocatorLibrary.registerLocationListener()

Stopping Location Updates

Please make sure you unregister from location callbacks when the user is not using the indoor map screen or navigation.

This is important for battery and performance optimization.

Stop the stream of updates:

RNColocatorLibrary.unregisterLocationListener()