Post not yet marked as solved
First of all the question what is the best way of using core bluetooth in the central role to send data to send data to a bluetooth LE devices. The data it sends needs to be processed and that takes enough time to cause problems on the UI thread if it runs on it. The user will initiate the process with the phone app open and then either keep using the app or close the app and expect the data to continue sending to the device.I have found 2 really bad ways of doing it which seem to workPut the bluetooth CBCentralManager objet on the main queue and risk blocking the UIIgnore the indications from the iOS bluetooth stack that its not ready to transmit and risk loosing data.This seems to have its roots in both iOS threading/dispatch queues as well as iOS Bluetooth internals.The bluetooth LE iOS application connects to a bluetooth LE device as central role.While using a serial queue for bluetooth, and using a different one than the main thread would be preferable. There is a problem: The callback: -(void)peripheralIsReadyToSendWriteWithoutResponse:(CBPeripheral *)peripheral { [self sendNextBluetoothLePacket]; }stop getting called. There is another way to check if the peripheral is ready to send more data, CBPeripheral has a member variable canSendWriteWithoutResponse which returns true if its ok to send. This variable also begins retuning false and never goes back to true.My app does have the core-bluetooth background mode selected in its info.plist so it should quality as one of those background modes. What I find is that when my app goes in the background the app does continue process data. I see log messages from polling loops that run every 100 milliseconds.If I trigger bluetooth LE writes from those polling loops I am able to keep sending data. The problem is I am unable to determine a safe rate to send the data and either its very slow or data is sometimes lost.Im not sure how to best deal with this. Any suggestions would be appreciated. It seems like no matter what I do when I go in to the background I loose my ability to determine if its safe to send data.The ideal solution would be to find a way to put CBCentralManager on its own serial queue but create that queue in such a way that the queue was not stopped when the app goes in to the background. If someone knows how to do that I believe it would solve my problem.The way my current code is goes like this. When the bluetooth service is created in the applicationDidFinishLaunchingWithOptions callback to my AppDelegate self.cm = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{CBCentralManagerOptionShowPowerAlertKey:@(0)}];Or with the serial queue which should work but is not dispatch_queue_t bt_queue = dispatch_queue_create("BT_queue", 0); self.cm = [[CBCentralManager alloc] initWithDelegate:self queue:bt_queue options:@{CBCentralManagerOptionShowPowerAlertKey:@(0)}];When its time to send some data I use one of these [self.cbPeripheral writeValue:data forCharacteristic:self.rxCharacteristic type:CBCharacteristicWriteWithoutResponse];If I just keep calling this writeValue with no delay in between without trying to check if its safe to send data. It will eventually fail.Extra background execution time is requested once the connection is established with this code - (void) centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral { UIApplication *app = [UIApplication sharedApplication]; if (self.globalBackgroundTask != UIBackgroundTaskInvalid) { [app endBackgroundTask:self.globalBackgroundTask]; self.globalBackgroundTask = UIBackgroundTaskInvalid; } self.globalBackgroundTask = [app beginBackgroundTaskWithExpirationHandler:^{ [app endBackgroundTask:_globalBackgroundTask]; _globalBackgroundTask = UIBackgroundTaskInvalid; }];Any thoughts on this or suggestions as to how I could give CBCentralManager a queue that was not on the UI thread and would not get shut down when the app goes in to the background would be greatly appreciated. If thats not possible I need to try and pick one of the workarounds.
Post not yet marked as solved
Hi Everyone, Do any of you know if the Ultra WideBand chipset (U1) will become available to developers in the near future? I'd be curious to see what type access may be granted and explore a sandbox is available. Any insight or information is much appreciated.Thank you
Post not yet marked as solved
Currently, the MDM capability is to lock modification of bluetooth. This prevents the user from toggling bluetooth on and off and prevents them from pairing new devices. Our use case is to enforce bluetooth on so that Apple Classroom always works properly, but we do not want to restrict the users from pairing new devices. Our hope is that there will be a way to control bluetooth through the MDM in a similar way to wifi is currently handled. This being an option to force it on(rather than prevent toggling if it is already off), and still allow the user to connect to new networks(in this case pair new devices). Is this something that is being considered to better support schools using Apple Classroom?Thanks!
Post not yet marked as solved
Does iOS 13 support Bluetooth 5 long range for iPads and iPhones? There was a post a few years ago about iOS 11 that was never answered, so hopefully a repost for iOS13 will get some answers this time.
Post not yet marked as solved
Hi,I am trying to scan for extended advertising packets using my iPad Air (A2152). I've noticed that my device supports Bluetooth 5.0 but I can't find my BLE 5.0 peripheral using Core Bluetooth. I have found an API to test if my devices support this feature and I have written code to test its. if (@available(iOS 13.0, *)) { if ([CBCentralManager supportsFeatures:CBCentralManagerFeatureExtendedScanAndConnect]) { NSLog(@"YES"); } else { NSLog(@"NO"); } } else { NSLog(@"Not iOS 13"); }I get answer "NO".More over, I was trying to use the PacketLogger for Xcode to find out the problem. My investigation has gone to place when I see that there are sending packets to set extended scan parameters with code "Reserved for future use". It's strange for me why this value is set. It is looking like software issues (with Core Bluetooth) rather than the unability by my device to scan for advertising extensions.What you can see at attached image. Next one, I don't know about if my device is supports "LE 2 Mbps bitrate". We can see that iPad is scanning using LE 1 Mbps. How to check if it's possible to scanning using LE 2 Mbps? It seems to me each device which supports Bluetooth 5.0 should be able to scan using LE 2 Mbps.To sum up, I have a several questions for you.1. About Core Bluetooth, is there any API which should I use to enable scanning for extended advertising? I haven't found any but I would like to be certain about its.2. If first question has negative answer. What is problem with my device or framework or something else? What is caused that scanning for extended advertising is impossible using my iPad A2152?3. I'm wondering about how to check Bluetooth bitrate in my device. How to do it? Is it possible by users? Or maybe anywhere in product's specification exists this information?4. Last one, maybe there are any devices which supports extended advertising. Could you tell which ones?Best Regards
Post not yet marked as solved
Hi,I have been working with CoreBluetooth for a while now and I've never run into this error before. This error occurred when I tried connecting to my desired peripheral. I've pasted the error message below:Domain=CBATTErrorDomain Code=14 "Peer removed pairing information" UserInfo={NSLocalizedDescription=Peer removed pairing information}I've tried to connect with the peripheral using a third-party app on the Android platform, and it works fine. However, third-party application on iOS isn't able to connect to this peripheral. It timeout when connecting on the iOS platform with the third-party app.I'm not sure what the source of this error is, or how to go about solving this error?Thanks!
Post not yet marked as solved
Is absolute mouse positioning supported over bluetooth in IOS ?
I've successfully created a bluetooth mouse emulator (using a Bluefruit NRF52832) which is working with the Assistive Touch bluetooth device feature added in iOS 13. Currently I can only emulate relative mouse positions. Eg. I can only signal the mouse to (pseudo code here)
'movemouse up 10 units'
'movemouse right 10 units', etc..
What I'm hoping to do is'move the mouse in absolute coordinates. eg
'movemouse to X,Y' (where X.Y are absolute screen coordinates'
Is it possible to use Absolute Mouse coordinates via bluetooth with IoS ? .. Any references, code fragments appreciatedjc
Additional details.. What I tried was changing the HID report frame in the Bluefruit Arduino package from Adafruit (line 138 in BleHIDAdafruit.cpp ).
from
SELECT ALL | TOGGLE FULL SIZE
HIDINPUT ( HIDDATA | HIDVARIABLE | HIDRELATIVE ),
to
SELECT ALL | TOGGLE FULL SIZE
HIDINPUT ( HIDDATA | HIDVARIABLE | HID_ABSOLUTE ),
which I believe is the right thing to do.. the mouse no longer moves on my IPAD. Any thoughts ?
Note I've tried asking this in the Adafruit forums with no response.
Post not yet marked as solved
I have an app that uses CoreBluetooth to connect to and read/write data via Storyboards. It works great.
I'm trying to port over to swiftUI and, while the code compiles, it doesn't do anything. I have a feeling I'm not setting up the CentralManager correctly or my class that contains all the Bluetooth stuff isn't being initialized.
Any suggestions?
In the old storyboard based code I had the following lines to kick everything off.
var centralManager: CBCentralManager?
....
centralManager = CBCentralManager(delegate: self, queue: nil)
What is the equivalent in SwiftUI?
Post not yet marked as solved
"Coded PHY" not found in API
How to solve this problem?
In addition, I checked other questions, only iPhone8 and iPhoneX can realize Long Range, right?
Post not yet marked as solved
Hello,
Our app gets rejected by Apple multiple times because of the use of location in UIBackgroundModes:
Your app declares support for location in the UIBackgroundModes key in your Info.plist file but still does not have any features that require persistent location. Apps that declare support for location in the UIBackgroundModes key in your Info.plist file must have features that require persistent location. Specifically, we were unable to locate features within the app that needs to use location in the background. Our answer in the Resolution Center was this:
This app is monitoring UUID’s to detect iBeacons in the background. The proces is as following: When the device is in range of an iBeacon, the app is activated in the background by a call on the delegate function ‘didEnterRegion’ from CLLocationManager.
The app starts ranging for iBeacons to detect the Major and Minor.
The app uses that information to know which desk this is and connects with the BLE Dongle in the desk.
Finally it sends the preferred height of the user to the BLE Dongle, which will result in the desk moving to that height. This all is happening in the background, without requiring the user to open the app. The "location" setting in the UIBackgroundModes key is needed to detect the iBeacon. So in summary, our app needs to detect an iBeacon in the background and for that needs the location background mode. But Apple keeps persisting that we don't need it.
When we remove the background mode and test the app in background, the process of detecting beacons is stopped.
In the info.plist it's like this:
		<key>UIBackgroundModes</key>
<array>
<string>bluetooth-central</string>
<string>location</string>
</array>
The bluetooth-central background mode is needed to connect with a BLE device.
Is there something wrong with our setup, or do we need some different way of explaining this to Apple?
Post not yet marked as solved
Hi!
Before iOS 13.0, the only way how to connect to BT classic device was External Accessory framework and the device had to be MFi licensed.
Now that I can use Core Bluetooth to connect to BT classic device (custom manufactured device that should support GATT over BR/EDR), does manufacturer of the device still need to join the MFi Program?
Post not yet marked as solved
I am pretty sure iOS 13.4 (beta and later) did support Coded PHY (Long Range). Tested devices are iPhone SE2 and iPhone 11 Pro.
However, it seems iOS 14 removed the support of Coded PHY, accidentally or on purpose, I don't know?
The same PHY update request returns "1M PHY" in iOS 14, but "Coded PHY" in iOS 13 (13.4 beta and later).
Anyone knows why?
Samson
Post not yet marked as solved
Hi,
Our PC/SC IFD Handler plugin loaded and running inside of com.apple.ifdhandler system process stops working on BigSur because the TCC engine denies com.apple.ifdhandler access to bluetooth. Our IFD Handler communicates via BLE to the SmartCardReader.
Here the relevant messages from the log
AUTHREQATTRIBUTION: msgID=4121.1, attribution={responsible={identifier=com.apple.ifdreader, pid=4115, auid=0, euid=0, responsiblepath=/System/Library/CryptoTokenKit/com.apple.ifdreader.slotd/Contents/MacOS/com.apple.ifdreader, binarypath=/System/Library/CryptoTokenKit/com.apple.ifdreader.slotd/Contents/MacOS/com.apple.ifdreader}, requesting={identifier=com.apple.ifdbundle, pid=4121, auid=0, euid=0, binarypath=/System/Library/CryptoTokenKit/com.apple.ifdreader.slotd/Contents/XPCServices/com.apple.ifdbundle.xpc/Contents/MacOS/com.apple.ifdbundle}, },
standard 15:21:59.836608+0100 tccd AUTHREQSUBJECT: msgID=4121.1, subject=com.apple.ifdreader,
15:21:59.836956+0100 tccd Refusing TCCAccessRequest for service kTCCServiceBluetoothAlways from client Sub:{com.apple.ifdreader}Resp:{identifier=com.apple.ifdreader, pid=4115, auid=0, euid=0, responsiblepath=/System/Library/CryptoTokenKit/com.apple.ifdreader.slotd/Contents/MacOS/com.apple.ifdreader, binary_path=/System/Library/CryptoTokenKit/com.apple.ifdreader.slotd/Contents/MacOS/com.apple.ifdreader} in background session
We tried to add com.apple.security.device.bluetooth entitlement to our plugin and also we added NSBluetoothAlwaysUsageDescription and NSBluetoothPeripheralUsageDescription to its Info.plist file but nothing works
Does anyone know how to allow platform binary to access bluetooth? if not, all plugins written that runs inside of platform process will not be able to access bluetooth.
I am trying to work with L2CAP channels over BLE. The service discovery, PSM lookup (via characteristics) and such all work fine.
The channel connects and I am able to exchange a couple of packets before the input stream is closed unexpectedly.
Meanwhile, the console reports the following CoreBluetooth messages:
error WARNING: Unknown error: 431
error WARNING: Unknown error: 436
As far as I can tell these error codes are undocumented and the L2CAP documentation is scarce at best. Does anyone know what they mean?
Post not yet marked as solved
Does anyone know how to adjust the Bluetooth settings so that my AirPods do not automatically connect to my Pro? I’ll be watching something on my computer than the sound goes out because it has connected to by AirPods.
Post not yet marked as solved
Hello,
We have made an iOS app that sends data from our peripheral device to the iPhone continuously in the background for our intended purpose(collecting health data) without dramatically decreasing battery life..
According to Guideline 2.5.4: "Multitasking apps may only use background services for their intended purposes: VoIP, audio playback, location, task completion, local notifications, etc. If your app uses location background mode, include a reminder that doing so may dramatically decrease battery life."
Are we breaking App Store guidelines by sending data from our peripheral to the phone continuously, even though we're adhering to the guidelines?
Post not yet marked as solved
Hi everyone,
I am an embedded linux programmer who knows C and Go programming, so don’t know much about mobile, iOS or Swift. I read some answers here which tells don’t use FTP and I guess BLE is not the best way trasferring file. I need to transfer some configuration files and firmware updates but I don’t know what is the most delicate way to do achive this? Can you give me hand to this newbie here?
Post not yet marked as solved
Hello,
I am writing an app that connects to an Arduino Nano with BLE. I would like the app to read data sent from the Arduino (the peripheral). My code connects to the Arduino using a specific UUID, but I think it is failing to detect a service from the Arduino. Here is my BluetoothViewController:
//
// BluetoothViewController.swift
import UIKit
import CoreBluetooth
//local central device object
class BluetoothViewController: UIViewController, CBPeripheralDelegate, CBCentralManagerDelegate {
//properties
private var centralManager: CBCentralManager!
private var peripheral: CBPeripheral!
var feedbackAmt = String() // from session setup view controller
//label to display stage of gait cycle
@IBOutlet weak var StateLabel: UILabel!
//characteristics
private var StateVar: CBCharacteristic?
override func viewDidLoad() {
super.viewDidLoad()
centralManager = CBCentralManager(delegate: self, queue: nil)
}
//func tells the delegate the central manager's state updated (required)
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == .poweredOn {
//can start scanning peripherals
centralManager.scanForPeripherals(withServices: [ArduinoPeripheral.ArduinoServiceUUID], options: nil)
StateLabel.text = "Scanning for devices..."
}
}
//result of scan - call to this method reflects a detected advertisement packet of a BLE peripheral in range
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
//found peripheral so stop scanning
self.centralManager.stopScan()
//copy the peripheral instance
self.peripheral = peripheral
self.peripheral.delegate = self
//connect to peripheral
self.centralManager.connect(self.peripheral, options: nil)
}
//if successfully connected
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
//check if this is the desired peripheral
if peripheral == self.peripheral {
//start service discovery for desired service
peripheral.discoverServices([ArduinoPeripheral.ArduinoServiceUUID])
StateLabel.text = "Connected!"
}
}
//handle service discovery event
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
//cycle through available services
if let services = peripheral.services {
for service in services {
//find the service from arduino
if service.uuid == ArduinoPeripheral.ArduinoServiceUUID {
//start discovery of the service's characteristics
peripheral.discoverCharacteristics([ArduinoPeripheral.ArduinoCharacteristicUUID], for: service)
StateLabel.text = "Service found"
return
}
}
}
}
//handle discovery of characteristics
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
if let characteristics = service.characteristics {
for characteristic in characteristics {
if characteristic.uuid == ArduinoPeripheral.ArduinoCharacteristicUUID {
StateVar = characteristic
StateLabel.text = "Characteristic found"
}
}
}
}
//subscribe to characteristic for value change / notification
func subscribeToNotifications(peripheral: CBPeripheral, characteristic: CBCharacteristic) {
peripheral.setNotifyValue(true, for: characteristic)
StateLabel.text = "Subscribed"
}
//notification update
func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) {
if let error = error {
// Handle error
print(error)
return
}
// Successfully subscribed to or unsubscribed from notifications/indications on a characteristic
}
//read value
func readValue(characteristic: CBCharacteristic) {
self.peripheral.readValue(for: characteristic)
}
//value returned from readValue
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if let error = error {
// Handle error
print(error)
return
}
StateLabel.text = "Value updated"
}
}
Where the Arduino characteristic UUUID and service UUID are defined in another swift file. I know it is connecting to the Arduino because the label says "Connected" when debugging, but it seems to get stuck on the line: "for service in services" and I am not sure why.
Thank you for the help!
Post not yet marked as solved
I am connecting to a remote peripheral and am experiencing sometimes disconnection with reason 13.
"Peer failed to respond to ATT value indication"
can someone explain what this error means and why is it caused?
I believe that I'm not "acking" an indication sent by the remote peripheral to me. but how is ack on indications done in swift?
thanks in advance
Post not yet marked as solved
Simple question really, can Airtags be used as iBeacons? seem like a really simple solution for wayfingint in complicated buildings. can they?