Is this even possible? Instead of any pairing dialog appearing, my central code get the "Authentication is insufficient" error when reading the characteristic.
My peripheral (in the macOS app) code uses the .notifyEncryptionRequired property and uses .readEncryptionRequired and .writeEncryptionRequired permissions. No descriptors are set, but I think they get added automatically since this characteristic notifies. 2900 and 2902 descriptors are set by the peripheral/CoreBluetooth.
If the Mac and iPhone are using the same Apple ID does that affect pairing?
Core Bluetooth
RSS for tagCommunicate with Bluetooth 4.0 low energy devices using Core Bluetooth.
Posts under Core Bluetooth tag
177 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
We are observing some unexpected behavior in our app when using ASK.
Our app is able to successfully discover and set up an accessory via ASK. After the setup completes, the connection to the accessory is managed through CBCentralManager and works as expected.
However, when we attempt to discover another accessory afterward, the picker is shown and indicates that accessory discovery is in progress. After approximately 10 seconds, the CBCentralManager delegate reports the Bluetooth state as poweredOff. Once this happens, the state never transitions back to poweredOn.
At this point, the only way to reconnect to the device or continue discovery is to relaunch the app.
We are wondering if anyone else has encountered similar behavior, or if this is a known or documented limitation/behavior when using ASK in combination with CBCentralManager.
I am implementing BLE scanning and connection using CoreBluetooth in a Flutter application with native iOS Swift code.
BLE scanning and connection work correctly in the foreground and for a short time after the app is sent to the background. However, after some time in the background, BLE scanning stops and the device is no longer discovered. The app appears to be suspended by iOS.
Key Observation:
When location services are actively in use (navigation arrow visible in the iOS status bar), BLE scanning and reconnection work reliably in the background.
When location services are not actively running, BLE scanning stops in the background even though the app has “Always Allow” location permission.
Expected Result
BLE scanning and connection should continue to function in the background using the Bluetooth LE background mode, without relying on active location updates.
Actual Result
BLE scanning starts successfully
App enters background
After some time, scanning stops
Device is no longer discovered
BLE works again only if location services are actively running
BLE Connection Behavior
One-time scan connects successfully to a BLE medical device
App is sent to background
Existing connection does not disconnect
However, new scans or reconnections fail once the app is suspended
Relevant Native iOS Code (AppDelegate)
import Flutter
import UIKit
import CoreBluetooth
@main
@objc class AppDelegate: FlutterAppDelegate {
private var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
if let identifiers =
launchOptions?[UIApplication.LaunchOptionsKey.bluetoothCentrals] as? [String] {
print("App relaunched for BLE state restoration: \(identifiers)")
}
NotificationCenter.default.addObserver(
self,
selector: #selector(appDidEnterBackground),
name: UIApplication.didEnterBackgroundNotification,
object: nil
)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
@objc private func appDidEnterBackground() {
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
self.endBackgroundTask()
}
}
private func endBackgroundTask() {
if backgroundTaskID != .invalid {
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
}
}
Questions for DTS:
Is it expected behavior that CoreBluetooth background scanning effectively stops once the app is suspended, even when the Bluetooth LE background mode is enabled?
Why does BLE background scanning appear to work reliably only when location services are actively running?
Is iOS internally associating BLE background execution with active location updates?
For continuous BLE reconnection (medical device use case), is the recommended approach to rely solely on CoreBluetooth state restoration instead of continuous background scanning?
Is it considered best practice to avoid long-running BLE scans in the background and instead wait for system-delivered BLE events?
Additional Notes
Issue is reproducible on real devices
Not using private APIs or unsupported background execution methods
Objective is to follow Apple-recommended, App Store–compliant behavior
How does core bluetooth work on tvOS? Is it available for use? Any docs would be helpful?
For our research study, it is essential that the app can advertise BLE packets even when the app is no longer in the foreground (for example, when it is in the app switcher / recents state).
Is it supported to advertise BLE packets while the app is in the background or recents state?
If so, what are the specific requirements or limitations we should be aware of (background modes, payload size, timing, etc.)?
Are there any constraints that would prevent consistent BLE advertising for research use cases?
Recently, I've noticed that background Bluetooth scanning stops when I move an app to the background on an iPhone 17 device with Bluetooth 6. I'm curious about a solution. Background Bluetooth scanning doesn't stop on devices older than iOS 26, or on devices that were updated from an iPhone 17 or earlier to iOS 26.
I'm scanning for peripherals, and keep references to multiple CBUUIDs - one for each peripheral.
I then start a connection to the peripheral.
I never get a callback to say the connection succeeded, failed, or disconnected.
I have a Mini-Moreph Bluetooth sniffer. The sniffer shows that the iPhone never tried to connect to any of the peripherals.
The iPhone HCI logs show that a create connection request was sent, but a cancel connection request was sent 0.018 seconds later. No feedback was given to my application through CoreBluetooth.
I've filed this through Feedback Assistant, but expect nothing will come of the report.
Hello Apple Forums,
We are developing an iOS application that connects to a custom BLE accessory and sends control commands to it.
Our system architecture is as follows:
A separate hardware device collects data and sends it to our backend server via Wi-Fi.
The backend evaluates state changes and determines when the BLE accessory should update its display.
The iOS app acts purely as a BLE command executor for this accessory.
Our goal is to:
Maintain a BLE connection with the accessory while the app is in the background.
Receive state-change events from our backend server.
Upon receiving such events, send a BLE command to the accessory to update its state.
We understand that iOS does not allow arbitrary background execution. We would like to confirm whether there is any supported mechanism, entitlement, or program that allows:
Long-running background execution for BLE control, or
Server-originated events (other than APNs) to trigger background BLE actions.
If this is not supported, we would appreciate confirmation that APNs (silent push) is the only supported way to trigger such background BLE actions, or guidance on any recommended alternative architectures.
Thank you for your guidance.
I am looking to extend the range for a device and the only option from a Bluetooth perspective is Coded PHY but I have not heard of any intent to support it from Apple. Does Apple intend to support Coded PHY and if so what is the roadmap?
Hi, we have developed an application that streams data from two BLE peripherals at a rate of 14.5kbps per peripheral. Until now, our devices streamed in near real time with no lag on all Apple devices with Bluetooth 5.0 or greater. Since the release of the iPhone 17 series and the iPad A16, we have reports from users of the data being streamed at significantly lower rates than expected.
Any help here would be greatly appreciated as our customers are being affected by this change.
I built an iOS app and debugged it using my iPhone 11. It works fine. My app uses Bluetooth because the physical data logger reads data via Bluetooth. I published it to the Apple store. After installing it on the iPhone 13 pro. The app works, but the device is not selected.
Hello Apple Bluetooth team,
We are developing a real-time call translation system that streams raw PCM audio over BLE between iPhone and custom earbuds.
This works reliably on iPhone 14 / 15 / 16, but on iPhone 17 (Bluetooth 6, N1 chip) we see severe and repeatable BLE packet loss, affecting both microphone uplink and TTS downlink.
Our audio stream
16 kHz, 16-bit mono PCM
20 ms frames (~640 bytes)
continuous bidirectional BLE streaming
What happens on iPhone 17
BLE packets are frequently dropped
entire audio frames are missing
results in ASR gaps and broken TTS playback
occurs even with strong RSSI and no RF interference
Same firmware, same BLE protocol, same MTU and connection interval work normally on older iPhones.
Questions
We would like to know:
Did Bluetooth 6 / N1 change BLE throughput, buffering, or scheduling?
Are there new limits on sustained notify / write-without-response traffic?
Is BLE audio now arbitrated differently against Wi-Fi / A2DP on iPhone 17?
Is BLE still expected to support low-latency continuous audio streaming on iPhone 17, or is this no longer a safe assumption?
Any guidance or new best practices would be greatly appreciated.
Best regards,
Valenti Zhang
I'm developing an App, a function is through the bluetooth firmware upgrade. there is a problem now. when I send data via bluetooth, App into the background, the data sent to immediately stop, peripheralIsReadyToSendWriteWithoutResponse will not be invoked, At the same time canSendWriteWithoutResponse always returns false. When I open the App again, peripheralIsReadyToSendWriteWithoutResponse still will not be invoked, canSendWriteWithoutResponse or returns false. I have set Acts as a Bluetooth LE accessory and Uses Bluetooth LE accessories. Is there a good way to send data to the device when my App goes into the background?
Hello,
Is there a 2-device limit for CoreBluetooth on visionOS 2.1?
My app connects to 4 BLE peripherals on iOS but fails at the 3rd device on Vision Pro. The 3rd call to centralManager.connect() is successful and the peripheral enters .connecting state, but didConnect never fires and it stays in .connecting forever. No errors reported.
First 2 devices work perfectly. Same code on iOS connects all 4.
Has anyone else had this problem? Is there any documentation I can refer to that states something like this?
Environment: visionOS 2.1, CoreBluetooth, Apple Vision Pro. My BLE Peripherals are running on nRF52840.
When using CBPeripheralManager in the peripheral role on iPhone 17 series devices (iPhone 17 Air, iPhone 17 Pro) running iOS 26.1 and above, the delegate method peripheralManager:central:didSubscribeToCharacteristic: is never called when a third-party BLE central device attempts to connect and subscribe to a characteristic. This functionality works correctly on all previous iPhone models and iOS versions.
(This worked previously for the same iPhone 17 Air/Pro when running iOS 26.0.1.)
We are observing a reproducible issue on some (not all) iPad models equipped with A16, where BLE streaming from multiple peripherals at ≥33–40 Hz results in uneven packet distribution, burst delivery, and application-level lag.
The same application, peripherals, firmware, iOS version, and physical environment do not exhibit this behaviour on A14-based iPads (iPad 10).
Affected Hardware:
• iPad 11" with A16
• iOS versions: identical across tested devices
• Issue affects some devices of the same model, not all
Internal field data
• ~25 affected
• ~5 unaffected
• Customers actively prefer iPad 10 (A14) due to stability
When two or more BLE peripherals stream data concurrently at frequencies ≥33–40 Hz, affected iPads exhibit:
• Uneven packet arrival timing
• Burst delivery instead of uniform intervals
• Increasing latency over time
• Observable application-level lag
This does not present as simple packet loss. Instead, packets arrive in clusters, breaking real-time assumptions.
At ≤30–33 Hz, the issue does not reproduce.
We tested:
• One affected iPad 11
• One unaffected iPad 11
• Same iOS version
• Same app build
• Same peripherals
• Same firmware
• Same physical location
• Same Wi-Fi state
Only the affected device reproduces the issue.
This rules out:
• App logic
• Peripheral firmware
• iOS version
• Environmental RF noise
• Wi-Fi coexistence configuration
Evidence Available
We can provide:
• Screenshots from a minimal test app showing packet counts
• CSV files of packet timestamps
• Source code for the BLE test app
• Side-by-side comparison logs (affected vs unaffected device)
All evidence is from the same app, built solely to measure packet timing.
Additional Technical Notes
• Issue persists after factory reset
• Occurs without third-party BLE libraries (CoreBluetooth only)
• Occurs regardless of foreground/background state
• Not correlated with MTU size
• Appears threshold-based (~33–40 Hz)
• Appears device-specific, not model-wide
Hello All,I am trying to communicate with BLE device which is using HID service through my iOS App using Core Bluetooth.While discovering all Services , i cannot look HID Service but i can look other services. As per previous versions , Core Bluetooth doesn't expose HID peripheral service capabilities to apps.Currently i am using Xcode 8 and iOS 10 version for development. Is there any update on exposing HID peripheral service in latest versions. If yes, how can i achive this?I will appreciate any help!!
Greetings.I have an app today that uses multipeer connectivity extensively. Currently, when the user switches away from the app, MPC disconnects the session(s) - this is by design apparently (per other feedback). I'd like to hear if anyone has experimented with iOS9 multitasking / multipeer and whether MPC sessions can stay alive?Thanks
Topic:
App & System Services
SubTopic:
Networking
Tags:
Background Tasks
Multipeer Connectivity
Core Bluetooth
This is not a question but rather a small bit of documentation on how Accessory Setup Kit actually works. I spent a couple days figuring this out so I thought let's share my findings. The example app is very light and the documentation definitely has room for improvement so here are a couple important notes.
Findings:
If you're running > iOS 18 and add any property to your Info.plist file you're no longer able to scan for devices by using CBCentralManager.scanForPeriphals. This will no longer return discoverable devices. Below iOS 18 these properties in the Info.plist are ignored by the OS and you can safely use the "legacy" method of connecting to bluetooth devices.
If you're running > iOS 26 the removeAccessory will show a prompt to the user. If you're running < 26 you can silently remove the accessory and start each session with a clean state.
If you create CBCentralManager before you start the ASK session you'll not get the state = PoweredOn.
If you have 0 accessories connected to your application CBCentralManager will never enter the state = PoweredOn when you create the CBCentralManager. Pre-ASK this would be the trigger for iOS to ask the user permission. This is no longer necessary with ASK.
If you have have 1 or more accessories authorized to your app this will be returned in the session.accessories after the session has started. This is an important indicator to determine app behavior.
If you have 1 or more accessories CBCentralManager.scanForPeripherals will ONLY return previously authorized AND discoverable devices. Use this for when you want to connect to a previously authorized device.
If you have 1 or more accessories and the CBCentralManager.scanForPeripherals returns nothing you can (safely) assume the user attempts to onboard a new device.
So for my application I take the following steps:
Check for iOS version, if > iOS 18 start ASK session.
Are there previously authorized devices?
-- yes: run CBCentralManger.scanForPeripherals
-- no: show the picker
Did the scan return any devices?
-- yes: show UI to select device or connect with first available device in the list
-- no: show the picker
Feel free to add any of your findings and @Apple please update the documentation!
Hi!
We have created an app that communicates with devices over BLE, and it is currently out in Testflight. It works as expected for almost everyone, but for some users we get a strange behaviour.
We start by scanning for devices with
scanForPeripherals(withServices:options:),
then connect, and finally initiate pairing by subscribing and writing to a pair of characteristics, which both require encryption.
The issue is that for these users, the following code:
func peripheral(
_ peripheral: CBPeripheral,
didDiscoverCharacteristicsFor service: CBService,
error: Error?
) {
guard error == nil else {
LogManager.shared.log(
"❌ Error discovering characteristics: \(error!)"
)
return
}
for characteristic in service.characteristics ?? [] {
if characteristic.uuid == controlPointUUID {
controlPointCharacteristic = characteristic
LogManager.shared.debugLog(
"Control Point characteristic found."
)
} else if characteristic.uuid == statusUUID {
statusCharacteristic = characteristic
LogManager.shared.debugLog("Notify characteristic found.")
}
}
if statusCharacteristic != nil {
LogManager.shared.debugLog("Call Set notify.")
peripheral.setNotifyValue(true, for: statusCharacteristic!)
}
}
func peripheral(
_ peripheral: CBPeripheral,
didUpdateNotificationStateFor characteristic: CBCharacteristic,
error: Error?
) {
if error != nil {
LogManager.shared.log(
"❌ Failed to subscribe to \(characteristic.uuid): \(error.debugDescription)"
)
produces this error:
> > [22:31:34.632] ❌ Failed to subscribe to F1D0FFF2-DEAA-ECEE-B42F-C9BA7ED623BB: Optional(Error Domain=CBATTErrorDomain Code=15 "Encryption is insufficient." UserInfo={NSLocalizedDescription=Encryption is insufficient.})
So in essence, we can't perform pairing and enable encryption, because we have insufficient encryption.
I know that the system caches some key material after pairing. When I do "Forget device" and then pair again, I don't need to put my device in pairing mode for the pairing pin to appear, which is not the case for devices that have not been paired before.
Given that I can't reproduce the problem locally, it's hard to debug using the console. What I've been trying to do is figure out how to reset Bluetooth, which should hopefully remove old keys and whatever else might be there.
The top hit when searching for 'clear corebluetooth cache macos' is on stackexchange, and writes:
Turn off Bluetooth
Delete com.apple.Bluetooth.plist from /Library/Preferences
Delete files named com.apple.Bluetooth.somehexuuidstuff.plist from ~/Library/Preferences/ByHost (note that this is the user preference folder, not the system one)
Turn on Bluetooth
The answer is from December 2013, so it's not surpising that things don't work out of the box, but anyways:
My ByHost folder does not contain any plist files with Bluetooth in them, and deleting the one in /Library/Preferences did not do anything, and judging from the content, it does not contain anything valuable.
I have tried "sudo grep -r 'Bluetooth' ." in both /Library/Preferences/ and ~/Library/Preferences/ and looked at the resulting hits, but I can't seem to find anything meaningful.
As a sidenote, does anyone know what is going on with Apple's entitlement service? We applied for an entitlement in August and have yet to receive a response.