Core Bluetooth
Scan for, connect to, and exchange data with Bluetooth Low Energy (BLE) devices.
Covers the central role (scanning and connecting to peripherals), the peripheral
role (advertising services), background modes, and state restoration.
Use accessorysetupkit for privacy-preserving accessory discovery and setup;
use this skill for direct Core Bluetooth GATT communication.
Contents
- Setup
- Central Role: Scanning
- Central Role: Connecting
- Discovering Services and Characteristics
- Reading, Writing, and Notifications
- Peripheral Role: Advertising
- Background BLE
- State Restoration
- Common Mistakes
- Review Checklist
- References
Setup
Info.plist Keys
Bluetooth Authorization
Core Bluetooth has no explicit permission request API. Add
NSBluetoothAlwaysUsageDescription, create the manager when the app is ready for
Bluetooth access, then check manager.authorization and manager.state.
Treat .denied and .restricted as terminal until the user changes Settings;
wait for .poweredOn before scanning, connecting, advertising, or publishing
services.
Central Role: Scanning
Creating the Central Manager
Always wait for the poweredOn state before scanning.
Scanning for Peripherals
Scan for specific service UUIDs to save power. Pass nil to discover all
peripherals (not recommended in production).
Central Role: Connecting
Discovering Services and Characteristics
Implement CBPeripheralDelegate to walk the service/characteristic tree.
Reading, Writing, and Notifications
Reading a Value
Writing a Value
Subscribing to Notifications
Peripheral Role: Advertising
Publish services from the local device using CBPeripheralManager.
Background BLE
Background Central Mode
Add bluetooth-central to UIBackgroundModes. In the background:
- Scanning must specify one or more service UUIDs;
nilscans are foreground-only - Scan options, including
CBCentralManagerScanOptionAllowDuplicatesKey, have no effect
Background Peripheral Mode
Add bluetooth-peripheral to UIBackgroundModes. In the background:
- Without this mode, published service contents are disabled while suspended
- The local name is not advertised
- Service UUIDs move to the overflow area and require explicit service scans
State Restoration
State restoration allows the system to re-create your central or peripheral manager after your app is terminated and relaunched for a BLE event.
Central Manager State Restoration
Peripheral Manager State Restoration
Common Mistakes
Review Checklist
-
NSBluetoothAlwaysUsageDescriptionadded to Info.plist - All BLE operations gated on
centralManagerDidUpdateStatereturning.poweredOn - Discovered peripherals retained with a strong reference
- Scanning uses specific service UUIDs (not
nil) in production -
CBPeripheralDelegateset before callingdiscoverServices - Characteristic properties checked before read/write/notify
- Write payloads stay within
maximumWriteValueLength(for:) -
.withoutResponsewrites honorcanSendWriteWithoutResponse - Background mode (
bluetooth-centralorbluetooth-peripheral) added if needed - State restoration identifier set if app needs relaunch-on-BLE-event support
-
willRestoreStatedelegate method implemented when using state restoration - Scanning stopped after discovering the target peripheral
- Disconnection handled with optional automatic reconnect logic
- Write type matches characteristic properties (
.withResponsevs.withoutResponse)
References
- Extended patterns (reconnection strategies, data parsing, SwiftUI integration): references/ble-patterns.md [blocked]
- Core Bluetooth framework
- CBCentralManager
- CBPeripheral
- CBPeripheralManager
- CBService
- CBCharacteristic
- CBUUID
- CBCentralManagerDelegate
- CBPeripheralDelegate
- NSBluetoothAlwaysUsageDescription
- CBManagerAuthorization
- scanForPeripherals(withServices:options:)
- startAdvertising(_:)
- writeValue(_:for:type:)
- maximumWriteValueLength(for:)
- canSendWriteWithoutResponse
- Configuring background execution modes


