Skip to content

feat: Location enrichment#316

Open
Shahroz16 wants to merge 5 commits intomainfrom
feat/location-module
Open

feat: Location enrichment#316
Shahroz16 wants to merge 5 commits intomainfrom
feat/location-module

Conversation

@Shahroz16
Copy link
Collaborator

@Shahroz16 Shahroz16 commented Mar 9, 2026

Summary

Adds support for the Customer.io Location module in the Flutter SDK.

  • New CustomerIOLocationPlatform with setLastKnownLocation() and requestLocationUpdate() APIs
  • LocationTrackingMode enum (off, manual, onAppStart) and LocationConfig for configuration
  • CustomerIO.location accessor for the location platform
  • Native bridge implementations (Android Kotlin NativeModuleBridge + iOS Swift FlutterPlugin)

Optional dependency

Location is fully opt-in. Customers who don't need it pay no cost:

  • iOS: Add the location subspec in Podfile (pod 'customer_io/location'). Uses a Swift compiler flag (-DCIO_LOCATION_ENABLED) set by the subspec — deterministic, no #if canImport ambiguity.
  • Android: Add customerio_location_enabled=true to gradle.properties. Controls a BuildConfig flag that gates all location code at build time. When disabled, R8 eliminates dead code entirely.

Note

Medium Risk
Adds a new cross-platform location module and wires it into SDK initialization/build configuration, which could affect initialization behavior and native builds when enabled; changes are gated behind explicit opt-in flags/subspecs.

Overview
Adds opt-in Location module support to the Flutter Customer.io plugin, exposing CustomerIO.location APIs (setLastKnownLocation, requestLocationUpdate) and new config types (LocationConfig, LocationTrackingMode) that are passed through CustomerIOConfig.toMap().

On Android, bumps the native SDK to 4.17.0 and introduces a customerio_location_enabled Gradle property that generates BuildConfig.CIO_LOCATION_ENABLED and conditionally includes the io.customer.android:location dependency and module wiring during initialize.

On iOS, adds a location CocoaPods subspec that pulls CustomerIO/Location and enables -DCIO_LOCATION_ENABLED, plus a new CustomerIOLocation channel handler and conditional initialization to attach the location module only when configured.

Written by Cursor Bugbot for commit f4ead00. This will update automatically on new commits. Configure here.

Shahroz16 and others added 3 commits March 9, 2026 01:21
Integrate native Android and iOS location modules into the Flutter SDK.
Adds platform interface, method channel, native bridges, config classes,
and dependency declarations for the location feature.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Location is now opt-in: iOS uses a CocoaPods subspec with #if canImport
guards, Android uses compileOnly with try-catch for NoClassDefFoundError.
Customers who don't need location no longer pull in the dependency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…onal location

iOS: Replace #if canImport(CioLocation) with #if CIO_LOCATION_ENABLED
compiler flag set via podspec subspec's pod_target_xcconfig. This is
deterministic regardless of CocoaPods linking mode.

Android: Replace NoClassDefFoundError try-catch with BuildConfig flag
controlled by customerio_location_enabled gradle property. Dependency is
conditionally included as implementation or compileOnly based on the
property. No runtime exception handling needed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Shahroz16 Shahroz16 requested a review from a team as a code owner March 9, 2026 06:15
@github-actions
Copy link
Contributor

github-actions bot commented Mar 9, 2026

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.


  • amiapp_flutter: ()

rootProject.hasProperty() returns true even for
customerio_location_enabled=false. Use findProperty().toBoolean()
to correctly respect the property's actual value.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

private func requestLocationUpdate() {
CustomerIO.location.requestLocationUpdate()
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iOS location access lacks error handling unlike Android

Medium Severity

The iOS CustomerIOLocation calls CustomerIO.location.setLastKnownLocation(location) and CustomerIO.location.requestLocationUpdate() directly without any error handling. In contrast, the Android side wraps ModuleLocation.instance().locationServices in runCatching and returns null on failure, gracefully no-oping. If the location module isn't added during initialization (e.g., a user enables the location subspec but omits LocationConfig in Flutter config), the iOS code could crash at runtime while Android handles it safely.

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

'screenViewUse': screenViewUse?.name,
'inApp': inAppConfig?.toMap(),
'push': pushConfig.toMap(),
'location': locationConfig?.toMap(),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Config toMap() output breaks existing test assertion

Low Severity

Adding 'location': locationConfig?.toMap() to toMap() always includes a 'location' key in the output map, even when locationConfig is null. The existing test in customer_io_config_test.dart (line 116: expect(config.toMap(), expectedMap)) creates a config without locationConfig, so the actual map now contains 'location': null while the expected map has no 'location' key. This causes the test to fail since Dart map equality considers a missing key different from a key with a null value.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant