> For the complete documentation index, see [llms.txt](https://docs.sentiance.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sentiance.com/implementing-features/insights/smart-geofences.md).

# Smart Geofences

***

{% hint style="info" %}
To learn about the Smart Geofences feature, check out [this page](/getting-started/features-catalog/smart-geofences.md).\
\
Smart Geofences can be configured for an entire population, but not at the individual user level. At the moment, creating geofences directly through the SDK is not supported. Instead, you can provide Sentiance with the list of geofences to configure.
{% endhint %}

## Prerequisites

The Smart Geofences feature relies on additional library dependencies alongside the core SDK dependency. To start using this feature, you must first add these dependencies to you project.

<details>

<summary>iOS</summary>

This feature is included in the main SDK framework. No additional dependencies are needed.

</details>

<details>

<summary>Android</summary>

Open your app <mark style="color:$success;">**`build.gradle`**</mark> file and add the smart geofences dependency.

{% code title="app/build.gradle" %}

```kotlin
dependencies {
    implementation(platform("com.sentiance:sdk-bom:<sentiance-version>"))
    implementation("com.sentiance:sdk-smart-geofences")
}
```

{% endcode %}

</details>

<details>

<summary>React Native</summary>

This feature is included after installing the following modules:

* [@sentiance-react-native/core](https://www.npmjs.com/package/@sentiance-react-native/core)
* [@sentiance-react-native/smart-geofences](https://www.npmjs.com/package/@sentiance-react-native/smart-geofences)

</details>

<details>

<summary>Flutter</summary>

This feature can be added by installing the following packages:

* [sentiance\_core](https://pub.dev/packages/sentiance_core)
* [sentiance\_smart\_geofences](https://pub.dev/packages/sentiance_smart_geofences)

</details>

## Utilize the Smart Geofences APIs

In this section, you’ll find examples showing how to subscribe for geofence entry and exit events, how to force-update the geofence list, and how to check the geofence monitoring status.

### Listen to Smart Geofence Entry and Exit Events

{% hint style="info" %}
Checkout [Real-time Listeners](/sdk/appendix/real-time-listeners.md) to read more about implementing the SDK's Listeners
{% endhint %}

You can subscribe to receive geofence entry and exit event notification as they are detected.

{% tabs %}
{% tab title="iOS" %}

```swift
// Create an instance of the delegate that will handle the events.
private let smartGeofenceEventDelegate = MySmartGeofenceEventDelegate()

// Set the delegate on the Sentiance SDK. Note that the SDK holds a weak
// reference to this delegate.
Sentiance.shared.smartGeofenceEventsDelegate = smartGeofenceEventDelegate

// Define the delegate class that will handle the events.
class MySmartGeofenceEventDelegate: SmartGeofenceEventDelegate {
    func onSmartGeofenceEvent(_ smartGeofenceEvent: SmartGeofenceEvent) {
        // Handle the events here.
    }
}
```

{% endtab %}

{% tab title="Android" %}
{% code overflow="wrap" fullWidth="false" %}

```kotlin
import com.sentiance.sdk.smartgeofences.api.SmartGeofenceApi

SmartGeofenceApi.getInstance(mContext).setSmartGeofenceEventListener { event ->
    // Handle the events here.
}
```

{% endcode %}
{% endtab %}

{% tab title="React Native" %}
To get smart geofence entry/exit event updates even when your app is in the background, place the following code inside your app's entrypoint **index.js** file. If you're only interested in these updates when your app is foregrounded, place this code inside the appropriate UI code instead.

```javascript
import {addSmartGeofenceEventListener} from "@sentiance-react-native/smart-geofences";
import SentianceCore from "@sentiance-react-native/core";

await SentianceCore.ensureInitialized();

// If you're subscribing to event updates only in the foreground, make sure
// to call subscription.remove() inside your component's componentWillUnmount() function
const subscription = addSmartGeofenceEventListener(smartGeofenceEvent => {
    // Handle the events here.
});
```

{% endtab %}

{% tab title="Flutter" %}
Create a **background.dart** file under your project's **lib** folder with the following code:

{% code title="background.dart" %}

```dart
import 'package:sentiance_smart_geofences/sentiance_smart_geofences.dart';
import 'package:sentiance_core/sentiance_core.dart';

@pragma('vm:entry-point')
void registerSmartGeofenceEventListener() async {
  WidgetsFlutterBinding.ensureInitialized();
  await SentianceCore.ensureInitialized();

  SentianceSmartGeofences.registerSmartGeofenceEventListener((smartGeofenceEvent) {
    // Handle the events here.
  });
}
```

{% endcode %}

Add the following code, depending on your target platform.

For **iOS**, add the following to your app delegate class:

{% code title="AppDelegate.swift" %}

```swift
import Flutter
import sentiance_smart_geofences

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {

    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
    
        // Other code
        
        // Make sure the SDK is initialized before calling this
        SentianceSmartGeofencesPlugin.initializeListener(
            withEntryPoint: "registerSmartGeofenceEventListener",
            libraryURI: "package:your_app_package_name/background.dart"
        )
        
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
}
```

{% endcode %}

For **Android**, add this code to your custom application class:

{% code title="MainApplication.kt" %}

```kotlin
import android.app.Application
import com.sentiance.smart_geofences_plugin.SmartGeofencesPlugin

class MainApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        
        // Other code

        val dartLibrary = "package:your_app_package_name/background.dart"
        // Make sure the SDK is initialized before calling this
        SmartGeofencesPlugin.initializeListener(this, dartLibrary, "registerSmartGeofenceEventListener")
    }
}
```

{% endcode %}

{% hint style="info" %}
If you're calling other Smart Geofences plugin APIs or other 3rd party plugin APIs inside your `registerSmartGeofenceEventListener` Dart function, then you need to register these plugins with the Sentiance SDK. See [this](/sdk/appendix/flutter/declaring-3rd-party-plugins.md) for more details.
{% endhint %}
{% endtab %}
{% endtabs %}

### Refresh the List of Monitored Geofences

The SDK regularly refreshes the list of monitored geofences. You can request an immediate refresh as follows:

{% tabs %}
{% tab title="iOS" %}

```swift
Sentiance.shared.refreshSmartGeofences { result, error in
    if let result {
        print("Geofences refreshed")
    }
    if let error {
        print("Error happened with smart geofence refreshing:" + error.description)
    }
}
```

{% endtab %}

{% tab title="Android" %}
{% code fullWidth="false" %}

```kotlin
import com.sentiance.sdk.smartgeofences.api.SmartGeofenceApi

SmartGeofenceApi.getInstance(mContext).refreshGeofences()
    .addOnSuccessListener {
        Log.d(TAG, "Geofences refreshed")
    }.addOnFailureListener {
        Log.d(TAG, "Failed to refresh geofences. Error: ${it.reason}")
    }
```

{% endcode %}
{% endtab %}

{% tab title="React Native" %}

```javascript
import {refreshGeofences} from "@sentiance-react-native/smart-geofences";

try {
     await refreshGeofences();
     console.log('Geofences refreshed');
} catch (error) {
     const refreshError = error.userInfo;
     console.error('Failed to refresh geofences. Error: ' + refreshError.reason);
}
```

{% endtab %}

{% tab title="Flutter" %}

```dart
import 'package:sentiance_smart_geofences/sentiance_smart_geofences.dart';

final sentianceSmartGeofences = SentianceSmartGeofences();

void refreshGeofences() async {
  String result;

  try {
    await sentianceSmartGeofences.refreshGeofences();
    result = "Geofences refreshed successfully.";
  } on SmartGeofencesRefreshError catch (e) {
    result = "Failed to refresh geofences, reason: ${e.reason.name} - details: ${e.details}";
  } catch (e) {
    result = "An unexpected error occurred: $e";
  }

  print(result);
}
```

{% endtab %}
{% endtabs %}

### Get the Current Smart Geofences Detection Mode

You can check the smart geofences detection mode as follows:

{% tabs %}
{% tab title="iOS" %}

```swift
let detectionMode = Sentiance.shared.smartGeofenceDetectionMode
print("Detection mode is:" + String(describing: detectionMode))
```

{% endtab %}

{% tab title="Android" %}
{% code fullWidth="false" %}

```kotlin
val detectionMode = SmartGeofenceApi.getInstance(this).detectionMode
Log.d(TAG, "Detection mode is: $detectionMode")
```

{% endcode %}
{% endtab %}

{% tab title="React Native" %}

```javascript
import {getDetectionMode} from "@sentiance-react-native/smart-geofences";

const detectionMode = await getDetectionMode();
console.log('Detection mode is:', detectionMode);
```

{% endtab %}

{% tab title="Flutter" %}

```dart
import 'package:sentiance_smart_geofences/sentiance_smart_geofences.dart';

final sentianceSmartGeofences = SentianceSmartGeofences();

void getDetectionMode() async {
  final detectionMode = await sentianceSmartGeofences.getDetectionMode();
  print('Detection mode is: $detectionMode');
}
```

{% endtab %}
{% endtabs %}

When enabled, the detection mode can either be in the foreground (i.e when the app is visible), or both foreground and background, depending on the type of location permission that has been granted (i.e. "always" or "while-in-use").

When detection mode is disabled, it indicates a general issue with the SDK’s detection. You can check the SDK status to identify the cause.
