npm package: @hkpuits/react-native-region-monitor
Description: A simple and easy to use geographical region monitoring API for React Native. Forked from martijndeh/react-native-region-monitor
Author: Martijn de Haan
Latest version: 2.2.3

[![npm](https://img.shields.io/npm/l/@hkpuits/react-native-region-monitor.svg)](https://github.com/benlui/react-native-region-monitor)
[![npm](https://img.shields.io/npm/v/@hkpuits/react-native-region-monitor.svg)](https://www.npmjs.com/package/@hkpuits/react-native-region-monitor)

# react-native-region-monitor

A simple and easy to use geographical region monitoring API for React Native on iOS and Android.

## **Getting started**

```
$ npm install @hkpuits/react-native-region-monitor --save
```
(OPTIONAL) If autolinking is not available for your React Native project
```
$ react-native link
```

## **Notes for Android implementation**

1. Add a file '{ProjectRoot}/RegionMonitorTask.js' for region monitoring in backgorund, default at the same level of index.js of your project, for customized callback for didEnter / didExit of a defined region
```js
module.exports = async (event) => {
  const { didEnter, didExit, region } = event;
  if (didEnter) {
	// do something
  } else if (didExit) {
    // do something
  }
};
```
2. Add permission in '{ProjectRoot}/android/app/AndroidManifest.xml'
```xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

```

## **Notes for iOS implementation**

1. It's important that you set `Privacy - Location Always Usage Description` (`NSLocationAlwaysUsageDescription`) and `Required background modes` (`UIBackgroundModes`) in your Info.plist. Otherwise, region monitoring will not function properly.

## **Usage**

Simply add a region and the library will automatically request the correct authorization and add the region afterwards.

```js
import regionMonitor from '@hkpuits/react-native-region-monitor';

const center = {
	latitude: 22.303858,
	longitude: 114.1795898,
};
const radius = 1000;
const identifier = 'MyRegionIdentifier';

regionMonitor.addCircularRegion(center, radius, identifier)
	.then(() => {
		// Added.
	})
	.catch((error) => {
		// Something failed.
	});
```

## **API Documentation**

#### `regionMonitor#addCircularRegion(center, radius, identifier)`
- `center` `Object` The coordinate which defines the center location of the circular region.
- `radius` `Integer` The radius of the region in meters. If the radius exceeds the maximum as defined by the platform OS, the radius is automatically clamped to the maximum value.
- `identifier` `String` A unique identifier of the region.

This method creates a new region object and starts monitoring the region. Monitored regions are persisted between app launches. This means you don't have to re-add regions every time your app starts.

If region monitoring authorization is not requested yet, this method automatically requests authorization which display the permission prompt to the user, see [`regionMonitor#requestAuthorization`](#regionmonitorrequestauthorization). This only works if the Info.plist is configured correctly. See [Info.plist](#infoplist) section.

This method returns a promise which resolves when the region was monitored successfully or rejects when this fails. In case location authorization is not requested, authorization is first requested, and if it allowed, the region is added. This might take a while as it requires user interaction.

Once a region is successfully added and the user enters or exits a region, the region changed callback is invoked. See [`regionMonitor#onRegionChange`](#regionmonitoronregionchangecallback) on how to set and use this callback. When adding a region and the user is already inside the region, the region changed callback is immediately invoked.

If a region with the same identifier is already being monitored, or is in the process of being added, adding the region fails. If you want to edit a region, you first have to remove it and then add it again.

On iOS, you can add up to 20 regions. This is a limit set by iOS. If you need to add more regions, there are alternative libraries which workaround this limitation.

##### Example

```js
const center = {
	latitude: 22.303858,
	longitude: 114.1795898,
};
const radius = 1000;
const identifier = 'MyRegionIdentifier';

regionMonitor.addCircularRegion(center, radius, identifier)
	.then(() => {
		// Added.
	})
	.catch((error) => {
		// Something failed.
	});
```

#### `regionMonitor#onRegionChange(callback)`
- `callback` `Function` The callback to invoke when the user enters or exits a region.

Registers a callback to be invoked whenever a user enters or exits a region. The callback is invoked with an `event` argument which contains `didEnter` and `didExit` booleans and a `region` object which contains an `identifier` property. The radius and center location are not available on the region object.

Both in the simulator and on an actual device it might take some seconds up till some minutes before a region change is noticed.

This method returns a function which you should invoke when you want to unregister the callback, for example, in your app's `componentWillUnmount`.

#### Example
```js
const off = regionMonitor.onRegionChange((event) => {
	const { didEnter, didExit, region } = event;

	if (didEnter) {
		console.log(`Enter region ${region.identifier}.`);
	}
	else if (didExit) {
		console.log(`Exit region ${region.identifier}.`);
	}
});

// Whenever you want to unregister.
off();
```

#### `regionMonitor#removeCircularRegion(identifier)`
- `identifier` `String` The identifier of the region to remove.

Removes a monitored region with `identifier`. This method returns a promise which resolves if the region was found and scheduled to be removed, and rejects if the region could not be found (if it was not monitored).

#### Example

```js
const identifier = 'MyRegionIdentifier';

regionMonitor.removeCircularRegion(identifier)
	.then(() => {
		// Region scheduled to be removed.
	})
	.catch((error) => {
		// Removing failed likely because the region is not monitored.
	});
```

#### `regionMonitor#clearRegions()`

Removes all monitored regions that have been previously registered. This method returns a promise which always resolves.

#### Example

```js
regionMonitor.clearRegions()
	.then(() => {
		// All regions scheduled to be removed.
	})
```

#### `regionMonitor#requestAuthorization()`

Requests the authorization required to initiate region monitoring. This method returns a promise which resolves if the authorization is allowed (or was already allowed) or rejects if region monitoring is not possible (either denied, restricted or not supported by the hardware).

Please note: the returned promise might take a while to resolve. This is because, if authorization is requested and a prompt is shown to the user, this promise resolves after the user allows the authorization (or rejects if the user denies the authorization).

If the user denied the authorization, the user can allow the authorization by going to the settings and changing the location permissions for the given app. It's not possible to prompt the user with an authorization prompt (again).

You don't have to call this method manually. When adding your first region by invoking [`regionMonitor#addCircularRegion(center, radius, identifier)`](#regionmonitoraddcircularregioncenter-radius-identifier) authorization is automatically requested if it has not been requested yet.

If your app's Info.plist is not configured correctly, this method returns a rejected promise. Please make sure to set `Privacy - Location Always Usage Description` in your app's Info.plist. See [Info.plist](#infoplist) for more information.

#### Example

```js
regionMonitor.requestAuthorization()
	.then(() => {
		// Allowed or already allowed.
	})
	.catch((error) => {
		// Authorization denied, restricted or region monitoring not supported.
	});
```