fix(mobile): make Bluetooth survive iOS Guided Access (kiosk lock)#39
Merged
Conversation
Under iOS Guided Access, the speedometer registered nothing and users could get locked out of starting Guided Access entirely. Root cause is a single conflict: CoreBluetooth's system Bluetooth alert vs. Guided Access. iOS suppresses system dialogs during a Guided Access session, and a pending one blocks Guided Access from starting — so the portal never connects (dead gauge), and the lingering modal jams Guided Access. react-native-ble-plx 3.5.1 exposes no JS option to suppress that alert, so this is fixed in-app + docs (no native patch): - Surface BLE adapter problems (Bluetooth off / permission denied / unsupported / error) on the home speedometer screen via a new BleStatusBanner, with an Open Settings shortcut. Previously these only appeared on the Live-log screen, so the gauge sat silently dead. - Add prewarmBle() and call it at launch (physical device only) so the iOS Bluetooth permission/power prompts fire on the home screen, not mid-session inside Guided Access. - Pure bleStatus phase->banner mapping with unit tests. - New docs/guides/ios-guided-access.md (kiosk setup + troubleshooting), linked from README and the TestFlight guide. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug report
Root cause
All three symptoms trace to one iOS conflict: CoreBluetooth's system Bluetooth dialog vs. Guided Access.
react-native-ble-plxshows iOS's system Bluetooth permission/power alert when BT is off or not-yet-authorized. That single modal explains everything:react-native-ble-plx@3.5.1exposes no JS option to suppress that alert (CBCentralManagerOptionShowPowerAlertKeyisn't surfaced), so this is fixed in-app + docs, with no native patch.Changes
Mobile
ble/bleStatus.ts(+ unit tests) — pureBlePhase → bannermapping forpoweredOff/unauthorized/unsupported/error.components/BleStatusBanner.tsx— renders that banner on the home speedometer screen, with an Open Settings shortcut for the permission case. Previously these states only showed on the Live-log screen, so under Guided Access the gauge sat silently dead with no explanation.ble/blePortal.ts→prewarmBle(), called fromapp/_layout.tsxat launch on a physical device, so the iOS Bluetooth permission/power prompts fire on the home screen — not mid-session inside Guided Access.Docs
docs/guides/ios-guided-access.md— kiosk setup (turn BT on + connect once before locking down) and troubleshooting for both the dead gauge and the "Guided Access could not be started" error.README.mdanddocs/guides/ios-testflight.md.Trade-off
The launch-time prewarm means a one-time Bluetooth permission prompt (and a "Bluetooth is off" alert, if applicable) now appears at app startup on a real device — intentional, to keep those prompts out of Guided Access sessions.
Validation
npm run typecheck— clean across workspaces.npm test— 186 mobile + 49 protocol tests pass, including the newbleStatustests.🤖 Generated with Copilot