chore(geofence): add support for geofencing feature - #620
Conversation
Wire the optional geofence module without enabling behavior yet: build flags (customerio_geofence_enabled gradle property, geofence podspec subspec), the geofence opt-in config key, and the exported CustomerIOGeofence class. Enabling geofence also pulls in Location, which geofence depends on, and turns on the Location build flag on both platforms so geofence-only builds get the full Location module. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tion (#612) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n screen (#614) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sample app builds 📱Below you will find the list of the latest versions of the sample apps. It's recommended to always download the latest builds of the sample apps to accurately test the pull request. |
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 040e30c. Configure here.
| static func module(from config: [String: Any], geofenceEnabled: Bool = false) -> LocationModule? { | ||
| let locationConfig = config["location"] as? [String: Any] | ||
| guard locationConfig != nil || geofenceEnabled else { return nil } | ||
| let trackingModeValue = locationConfig?["trackingMode"] as? String |
There was a problem hiding this comment.
Geofence with location off
Medium Severity
When geofence is configured alongside location.trackingMode set to OFF, initialization still registers the location module in off mode and adds geofence. Geofence depends on location fixes, so monitoring can appear enabled while the location module will not supply them.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 040e30c. Configure here.
Geofence is a compileOnly dependency when disabled, but NativeGeofenceModule always compiles, so its io.customer.geofence references reach R8 with the classes absent — same as location. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Live Notifications and geofence add parallel modules, so every conflict resolved as keep-both: - CustomerIOReactNativePackage.kt: both module imports - NativeCustomerIO.swift: register both modules, geofence keeps its allowBackgroundDelivery default - customerio-reactnative.podspec: both optional subspecs - example Podfile / storage.ts: sample app opts into both - data-pipelines.ts: both config blocks on CioConfig - api report regenerated with api-extractor Both sides had already bumped the natives to the same versions (Android 4.20.0 / iOS 4.7.0), so those merged clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>


Summary
Adds on-device geofencing to the React Native SDK, merging
feature/geofence-on-deviceintomain. Ported to match the native iOS/Android and Flutter SDKs: an opt-in geofence module (implies Location),CustomerIO.geofence.refreshFromCurrentLocation()+locationModeconfig, iOSallowBackgroundDelivery, and example-app integration.Changes
Includes previously approved/merged PRs (oldest first):
Note
Native version pins (iOS
4.7.0/ Android4.20.0) land via #609 before this merges — do not merge until the geofence-enabled native SDKs are released.Note
Medium Risk
Touches background location, geofence cold-wake bootstrap on iOS, and init ordering between location/geofence modules; behavior is gated behind opt-in flags but misconfiguration could affect privacy-sensitive location handling.
Overview
Adds an optional geofence module to the React Native SDK, aligned with the native iOS/Android and Flutter SDKs. Customers opt in at build time (
customerio_geofence_enabledon Android,geofenceCocoaPods subspec on iOS) and at runtime via ageofenceblock onCioConfig; enabling geofence also turns on Location (dependency + init wiring).Public API:
CustomerIO.geofence.refreshFromCurrentLocation(),CioGeofenceLocationMode(AUTOMATIC/MANUAL), and iOS-onlyios.allowBackgroundDelivery(defaults on when geofence is configured). JS uses a new TurboModule spec; native bridges register the geofence module only when the feature flag is set.Native init: Android and iOS register
ModuleGeofence/GeofenceModulewhengeofenceconfig is present, and auto-register Location when geofence is configured without explicitlocationconfig. iOS sampleAppDelegatecallsGeofenceModule.bootstrapForBackgroundDeliveryfor cold-wake delivery before JS starts.Example app: Enables geofence in Gradle/Podfile, adds background-location permissions and UI on the location screen (state-aware “Always” / background grant + calls to
refreshFromCurrentLocation), defaultgeofence: {}in storage with merge-over-persisted config, and location tracking mode in settings.Reviewed by Cursor Bugbot for commit 446e7af. Bugbot is set up for automated code reviews on this repo. Configure here.