customer_io 4.4.0
customer_io: ^4.4.0 copied to clipboard
An official flutter plugin for Customer.io, an automated messaging platform for tech-savvy marketers.
Customer.io Flutter Plugin #
This is the official Customer.io Flutter plugin.
Getting started #
You'll find our complete SDK documentation here.
If a CocoaPods build reports that a generated dependency target is below the deployment range supported by Xcode, follow the deployment-target normalization guide.
Live Activities #
Enable the activity types you use via liveNotificationsConfig in your CustomerIOConfig. On iOS, Live Activities are opt-in: add the liveactivities pod subspec (CocoaPods) or set customerio_live_activities_enabled=true in android/gradle.properties (Swift Package Manager), plus a Widget Extension that renders the SDK's built-in templates.
iOS also requires NSSupportsLiveActivities in ios/Runner/Info.plist. Without it the system refuses to start any activity, so nothing appears even when everything else is configured:
<key>NSSupportsLiveActivities</key>
<true/>
For an activity of your own, set customType to your reverse-DNS identifier and start it with LiveActivityPayload.custom(data: {...}). You supply the view: CIOCustomAttributes in your iOS Widget Extension, and the createLiveNotification callback on Android.
AppDelegate-only apps keep the existing application(_:open:options:) integration: call
CustomerIOLiveActivities.handleWidgetUrl before forwarding its returned URL to the host router.
This remains the supported legacy behavior and avoids a second automatic observer reporting the
same tap.
For UIScene apps using Flutter's standard deep-link handling, the plugin automatically attributes
Live Activity taps. If a tap carries a redirect, it waits for Flutter UI in that scene and sends
the URL through Flutter's route-information channel. If Flutter declines the route, the plugin logs
the result and does not ask iOS to reopen the URL; reopening an app's own universal link can send it
to the website instead. Do not add another Customer.io URL handler to the host SceneDelegate.
When upgrading an existing UIScene app that added this handler manually, remove that call before
upgrading to avoid reporting the same tap twice.
If a UIScene app sets FlutterDeepLinkingEnabled to false and owns routing through another
plugin, keep the host scene lifecycle handler. Call CustomerIOLiveActivities.handleWidgetUrl
there before forwarding its returned URL to that router. Customer.io does not register an
automatic URL owner in this configuration.
Apps with a UIApplicationSceneManifest receive opened URLs through their scene lifecycle instead
of the AppDelegate callback. The host scene delegate must extend Flutter's FlutterSceneDelegate,
or forward the equivalent lifecycle callbacks through Flutter's scene lifecycle provider. The
Customer.io plugin then registers its scene routing owner; do not add another Customer.io URL
handler to the host SceneDelegate. The samples deliberately keep AppDelegate-only behavior by
default, while CI selects their scene manifests with
CIO_LIFECYCLE_INFOPLIST_SUFFIX=-Scene. Flutter exposes one consume-or-forward decision for all
cold connection options, so an occurrence that also contains a user activity, notification
response, or shortcut is not consumed by Customer.io. Customer.io still records the opened metric
when the occurrence contains exactly one tracking URL, then returns the complete original
occurrence to Flutter; it does not route the redirect from that mixed occurrence. Depending on
which other input Flutter handles first, its router may also receive the original
cio-live-activity URL; treat that internal URL as unhandled.
Warm URL callbacks are offered to every engine associated with the scene, while Flutter gives cold
connection options to the first engine that claims them. CI proves scene launch and callback
delivery, but real URL delivery into the Flutter engine remains part of device-level validation.
Android needs no equivalent step.
iOS application lifecycle #
Existing AppDelegate-only applications remain supported and require no new Customer.io
configuration when built with toolchains that still permit that lifecycle. Apps built with Xcode
27 must adopt UIScene to launch. The plugin uses scene routing when the app declares Apple's
standard UIApplicationSceneManifest; no Customer.io-specific lifecycle key is required.
Keep CioAppDelegateWrapper as the application delegate. It continues to own SDK initialization,
APNs token registration, and the global notification-center delegate. Flutter's scene delegate owns
UI activation callbacks. In UIScene hosts, the plugin passes Customer.io Live Activity URLs to the
released native URL handler and leaves ordinary links and user activities to Flutter.
AppDelegate-only hosts keep the existing manual URL handler described above.
When UIScene and Flutter deep linking are enabled, the plugin also becomes the native SDK's
deep-link callback during plugin registration. The native callback is synchronous but Flutter's
routing result is asynchronous, so the plugin claims the handoff and offers every SDK destination
to Flutter, including http and https URLs. Flutter's standard navigation APIs report a delivered
route as handled, so the host's Dart router owns unknown-route and browser-opening policy. The plugin
uses UIApplication.open only when the navigation channel reports the route as unhandled or no
foreground engine becomes available. This plugin callback and a native SDKConfigBuilder
deepLinkCallback cannot be combined because the native SDK has one callback slot.
This replaces the native SDK's AppDelegate continuation fallback only in that UIScene configuration;
set FlutterDeepLinkingEnabled to false when the host owns a different scene router.
Applications that declare UIScene must use Flutter 3.44.8 or newer and use
FlutterSceneDelegate, or forward its lifecycle callbacks through Flutter's scene lifecycle
provider. Customer.io cannot receive or diagnose callbacks that a custom scene delegate does not
forward. This release's compatibility scope is one simultaneous window scene, matching the native
and Flutter samples' UIApplicationSupportsMultipleScenes=false configuration. Multiple
simultaneous window scenes are not supported. Hosts that enable them retain ownership of Flutter's
scene-to-engine registration and any window-specific routing. Older Flutter registrars log an error
and leave scene routing unclaimed.
Contributing #
Thanks for taking an interest in our project! We welcome your contributions.
The checked-in public API baseline is generated with the exact Flutter version
in scripts/api-extraction-flutter-version.txt and dart_apitool 0.22.1. The
pin avoids the unsupported Dart 3.13 analyzer AST in newer Flutter releases.
Run ./scripts/extract_api.sh with that Flutter version when an intentional
public API change requires a new baseline.
We value an open, welcoming, diverse, inclusive, and healthy community for this project. We expect all contributors to follow our code of conduct.