Skip to content

feat(darwin): notify central of background connection events#264

Draft
jonasbark wants to merge 1 commit into
Navideck:mainfrom
jonasbark:ios-background-connect-notify-options
Draft

feat(darwin): notify central of background connection events#264
jonasbark wants to merge 1 commit into
Navideck:mainfrom
jonasbark:ios-background-connect-notify-options

Conversation

@jonasbark

Copy link
Copy Markdown
Contributor

Summary

Pass the three "notify on background event" options to manager.connect(_:options:) on Apple platforms so that CoreBluetooth surfaces connection / disconnection / characteristic-notification events that occur while the app is suspended, relaunching the app into the background to handle them:

  • CBConnectPeripheralOptionNotifyOnConnectionKey
  • CBConnectPeripheralOptionNotifyOnDisconnectionKey
  • CBConnectPeripheralOptionNotifyOnNotificationKey

The change consolidates the three previous manager.connect(...) call sites into a single connect(peripheral, options:); the existing iOS 17+ CBConnectPeripheralOptionEnableAutoReconnect is merged into the same dictionary, so that path is behaviorally unchanged.

Motivation

I maintain a fitness app (BikeControl) that stays connected to a smart trainer/sensors for the duration of a workout. Users routinely background the app (lock the phone, switch to music, etc.). Combined with the bluetooth-central background mode and the CoreBluetooth state restoration that already landed in 2.0/2.1, these options let the central keep reacting to peripheral events — most importantly reconnecting to a previously paired peripheral — while suspended, instead of going silent until the user foregrounds the app.

I've been carrying this as a one-line fork of universal_ble for a while. Everything else in that fork (the Windows shared-mode / hresult_error fixes and addServicesInScanResponse) has since landed upstream — this is the only patch left, so I'd love to upstream it and retire the fork.

Open question — should this be opt-in? 🟡

I've marked this a draft because these keys have a user-visible side effect: when the app is suspended, the system may show the user an alert for these events (and NotifyOnNotificationKey fires per characteristic notification). That's exactly what I want for a reconnect-while-backgrounded use case, but it's a behavior change for existing consumers, so enabling it unconditionally for everyone is probably not the right default.

I'd appreciate guidance on the API shape you'd prefer:

  1. Opt-in connect option — add a flag (e.g. an Apple-specific connection option, mirroring the existing PeripheralAndroidOptions advertising pattern) threaded through the pigeon connect signature, iOS/macOS-only. I'm happy to do the full cross-platform plumbing + pigeon regen if you point me at the shape you'd like.
  2. Always-on (this diff as-is) — if you consider these desirable defaults for the library's connection model.

Happy to iterate either way.

Testing

  • Builds against main (Apple side, SPM layout).
  • Behavior verified in production in BikeControl on iOS: backgrounded reconnection to a paired trainer now wakes the app to handle the event.

🤖 Generated with Claude Code

Set CBConnectPeripheralOptionNotifyOnConnection/Disconnection/Notification
on connect() so CoreBluetooth surfaces connection, disconnection and
notification events that occur while the app is suspended (relaunching it
into the background to handle them). This keeps a backgrounded central —
e.g. a fitness app reconnecting to a previously paired trainer — responsive
without the user having to foreground the app.

Consolidated to a single manager.connect(options:) call; the iOS 17+
auto-reconnect option is merged into the same dictionary, so behavior on
that path is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request modifies the Swift connection logic in UniversalBlePlugin to unconditionally enable background connection options (CBConnectPeripheralOptionNotifyOnConnectionKey, CBConnectPeripheralOptionNotifyOnDisconnectionKey, and CBConnectPeripheralOptionNotifyOnNotificationKey) when connecting to a peripheral. Feedback indicates that enabling these options by default can trigger intrusive system alerts when the app is suspended, and recommends making them configurable or opt-in instead.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +222 to +226
var options: [String: Any] = [
CBConnectPeripheralOptionNotifyOnConnectionKey: true,
CBConnectPeripheralOptionNotifyOnDisconnectionKey: true,
CBConnectPeripheralOptionNotifyOnNotificationKey: true,
]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Enabling CBConnectPeripheralOptionNotifyOnConnectionKey, CBConnectPeripheralOptionNotifyOnDisconnectionKey, and CBConnectPeripheralOptionNotifyOnNotificationKey unconditionally will cause iOS to display system alerts (popups/notifications) to the user whenever these events occur while the app is suspended. This is an intrusive behavior change for existing users of the library who do not expect or want these alerts.\n\nThese options should be opt-in and configurable (e.g., via platform-specific connection options passed from the Dart layer) rather than enabled by default.

    var options: [String: Any] = [:]

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