Core Bluetooth

RSS for tag

Communicate with Bluetooth 4.0 low energy devices using Core Bluetooth.

Core Bluetooth Documentation

Posts under Core Bluetooth tag

175 Posts
Sort by:
Post not yet marked as solved
0 Replies
222 Views
I've encountered a strange issue reading characteristics from a BLE device using CoreBluetooth ONLY ON iPHONE 12 AND iPHONE 12 PRO. The problem is that the BLE device receives a read characteristic request for an errored characteristic id. The BLE Device is using blue kitchen btstack (https://github.com/bluekitchen/btstack). We also filed a bug report on their side here Say i ask for a characteristic discovered with CBUUID "F97A6DA4-B3AA-44B0-8DE7-40D238BE5E02", the device receives a request for a "F97A6DA4-B3AA-44B0-8DE7-40D238BE5E09" id. The exact same swift code is working perfectly on MacOS, reading the right characteristic on the device. I is also perfectly fine, tested on various iOS versions on iPhone 8, SE (1st gen), 11, 13, 15. The only devices affected are the 12 & 12 Pro. I also tried using popular apps like light blue, or nRF Connect for iOS, and the iOS app has the same behavior on iPhone 12 & 12 Pro (that is wrong), but is ok on other iPhone devices. Has anyone encountered such a strange behavior and have any insight on how to solve that ?
Posted
by aactimage.
Last updated
.
Post not yet marked as solved
0 Replies
208 Views
Dear Apple support, We are working on one of the projects related to BLE, in which our BLE device is acting as a GATT client and our iPhone device (iPhone 13, OS17.3) is acting as a GATT server. Issue being faced: Whenever my BLE device subscribes to the ANCS notifications, and the moment the IOS device starts bombarding with the notifications available in notification center, the BLE device controller's heap memory becomes UNAVAILABLE in runtime for this notifications' queue and eventually making the BLE controller to reset. Thereafter, whenever user tries making a new connection session of BLE, again same thing repeats. Notifications allowed in BLE display : W-SMS, W-CALL, SMS, CALL, none other than this. Issue observed with : IF and ONLY 150 notifications and above available in notification center, otherwise our product works fine with iPhone with less number of notifications. We would like to know how we can curb the number of PRE-EXISTING type notifications available in the notification center flowing towards the BLE device? What best solution can be done at the IOS side, we also have IOS APP team for this project. What kind of APIs does Core Bluetooth framework can provide to the IOS developer in order to overcome this issue. Please suggest possible ways from the IPHONE device only to overcome this. BLE's software CANNOT BE CHANGED under any circumstances as the product is already in production and complaints are coming from end user (from the field). OUR GOAL : ONLY notifications which will be available in run time, i.e. AFTER SUCCESSFUL BLE connection established to be displayed in the BLE's display. We DON'T WANT older notifications to be displayed and flow towards BLE over ANCS. WE MUST make 'notification popup' option as ALLOW to be shared with our BLE device, otherwise SMS,CALL, W-SMS,W-CALL during live connection will not come on the BLE 's display.
Posted
by MM_GGN.
Last updated
.
Post not yet marked as solved
2 Replies
212 Views
I would like to know, do we have any support from iOS in order to turn on wifi and bluetooth using internal apis on tap of a button in my IOS App, I am struggling to find information over this, more precisely , I want to turn on wifi from my custom widget in I phone, is it possible then please share info.
Posted
by gmantrao.
Last updated
.
Post not yet marked as solved
0 Replies
218 Views
"When an iBeacon is received, a BLE scan API is called within didEnterRegion. However, if executed while the screen is off, Core Bluetooth's didDiscover does not function. Yet, if the screen is turned on once and then turned off again, didDiscover functions. Is there a way to make Core Bluetooth's didDiscover work while the screen is off?" Let me know if you need further assistance or clarification! func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) { if let beaconRegion = region as? CLBeaconRegion { startRanging(in: beaconRegion) } } func startRanging(in beaconRegion: CLBeaconRegion) { // バックグラウンドタスクを開始 bgTask = UIApplication.shared.beginBackgroundTask(expirationHandler: { [self] in print("バックグラウンドタスクの有効期限が切れ") // バックグラウンドタスクの有効期限が切れたときに、バックグラウンドタスクを終了 self.lm!.stopRangingBeacons(satisfying: beaconRegion.beaconIdentityConstraint) UIApplication.shared.endBackgroundTask(bgTask) // バックグラウンドタスクの識別子を無効 bgTask = .invalid }) // レンジング開始 self.lm!.startRangingBeacons(satisfying: beaconRegion.beaconIdentityConstraint) //サービス指定してCoreBluetoothを起動 self.centralManager.stopScan() self.centralManager.scanForPeripherals(withServices: [self.kServiceUUID], options: nil) // バックグラウンドタスク終了 let time = UIApplication.shared.backgroundTimeRemaining - 1.0 DispatchQueue.main.asyncAfter(deadline: .now() + time) { self.stopRanging(in: beaconRegion) } } func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { print("---- didDiscover ----") print("peripheral-->\(peripheral)") print("advertisementData-->\(advertisementData)") print("rssi-->\(RSSI)") print("---------------------") }
Posted
by tgrgenki.
Last updated
.
Post not yet marked as solved
0 Replies
286 Views
When I connect a speed and cadence sensor to my Apple Watch in Bluetooth settings I expect to see the following HKQuantity types in workoutBuilder:(HKLiveWorkoutBuilder *)workoutBuilder didCollectDataOfTypes HKQuantityTypeIdentifierCyclingSpeed, HKQuantityTypeIdentifierDistanceCycling, and HKQuantityTypeIdentifierCyclingCadence. However, after starting an HKWorkoutSession I only get updates for HKQuantityTypeIdentifierDistanceCycling. I know that these metrics are being updated because the Apple Workout app displays them. I have authorized my app to read and write these quantity types, so what could I be missing here? Are these quantities only available to the workout app, as I haven't found a third-party app that sees these metrics when the sensors are connected this way?
Posted Last updated
.
Post not yet marked as solved
0 Replies
207 Views
We are having an issue with BLE peripheral devices it is not connecting to the device when we kill the app and try to get connected devices on app start it always returns empty. we are calling this function to get connected devices BleManager.getConnectedPeripherals This is working fine on iOS 16 but on iOS we are having issue we are using this library for BLE communication: react-native-ble-manager Devices: iPhone XR, iPhone 11 OS: 17 React Native: 0.71.11
Posted Last updated
.
Post not yet marked as solved
0 Replies
181 Views
Hi, we have an app which emits an iBeacon, this works correctly except when the app goes in background. Is there any way to avoid this behaviour, maybe under some conditions (for example when we are inside a region created with another iBeacon?). Also we need to emit another advertisement (of type iBeacon or CBAdvertisementDataServiceUUIDsKey, since we cannot write into CBAdvertisementDataManufacturerDataKey) but separated from this first one, that is 2 advertisements in parallel, so the listeners will receive 2 different packets. After some test I see that only the 1st iBeacon is emitted. Any ideas? Thanks in advance
Posted
by gmurari.
Last updated
.
Post marked as solved
1 Replies
262 Views
Hello, whenever I want to add a CBMutableDescriptor, either with CBMutableDescriptor(type: CBUUID(string: "2901"), value: nil) or using the defined string CBUUIDCharacteristicUserDescriptionString: I get the following error message: *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Expecting NSData value type for Format descriptor' What am I doing wrong here? Thanks
Posted
by clemhousa.
Last updated
.
Post not yet marked as solved
1 Replies
313 Views
Since the Multipeer Connectivity framework no longer supports Bluetooth. (https://developer.apple.com/forums/thread/749346) Why does its official documentation still mention "In iOS, the framework uses infrastructure Wi-Fi networks, peer-to-peer Wi-Fi, and Bluetooth personal area networks for the underlying transport." ?(https://developer.apple.com/documentation/multipeerconnectivity) What is the purpose of using Bluetooth personal area networks for the underlying transport?
Posted Last updated
.
Post not yet marked as solved
1 Replies
361 Views
Hello, In this inquiry(https://developer.apple.com/forums/thread/747860), I came across this conclusion. “Apple disabled TCP/IP networking over Bluetooth completely. Apple’s peer-to-peer networking APIs now run exclusively over Wi-Fi." I have three questions I would like to ask. The Multipeer Connectivity Framework supports Wi-Fi networks, peer-to-peer Wi-Fi, and Bluetooth personal area networks. Since the framework abstracts away the underlying protocols, we cannot specify which protocol to choose. Can this framework still establish a pure Bluetooth connection now? (Not just using Bluetooth for the discovery phase). Given that the framework supports Bluetooth protocols, why does it not require Bluetooth permissions but only local network permissions? Does the Bluetooth protocol supported by the framework have the capability to discover traditional Bluetooth devices and services that the Core Bluetooth framework can discover?
Posted Last updated
.
Post not yet marked as solved
0 Replies
281 Views
hi I recently developed an iOS APP which will advertise in background, as I checked the developer document, device name and service uuid will be ignored when iOS APP goes to background. But I found an APP named Berkanan which can broadcast in backgound with device name and service uuid, and its device name length exceeds 8 bytes, does anyone know how it implements? thanks!
Posted
by Pandak.
Last updated
.
Post not yet marked as solved
1 Replies
229 Views
I'm trying an iAP2 connection (SPP open) with Bluetooth module and Apple product. But I don't know the iAP2 UUID for sure. Can someone tell me? And I'd like to know if MFi Program is required for iAP2 connection. I'd appreciate it if you could let me know the detailed procedure for iAP2 connection.
Posted
by dlehdyd.
Last updated
.
Post not yet marked as solved
0 Replies
232 Views
A device running with the following lines of code can receive a message from a peripheral. In this manner, though, I can only receive messages from one peripheral since the service and characteristic IDs are hardcoded in CentralViewModel.swift. So my question is how I can observe messages from multiple peripherals. Thanks. import SwiftUI struct ContentView: View { var body: some View { NavigationStack { VStack { NavigationLink(destination: CentralView()) { Text("Central") } .buttonStyle(.borderedProminent) .padding() } } } } // CentralView.swift // import SwiftUI struct CentralView: View { @StateObject var central: CentralViewModel = CentralViewModel() var body: some View { Text(central.message) .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) .padding(20) .onDisappear { central.stopAction() } } } // CentralViewModel.swift // import Foundation import CoreBluetooth class CentralViewModel: NSObject, ObservableObject { @Published var message: String = "" var serviceUUID: CBUUID! var characteristicUUID: CBUUID! var centralManager: CBCentralManager! var discoveredPeripheral: CBPeripheral? var transferCharacteristic: CBCharacteristic? var writeIterationsComplete = 0 //var connectionIterationsComplete = 0 let defaultIterations = 5 var data: Data = Data() override init() { super.init() self.serviceUUID = CBUUID(string: "994F8A12-FE8E-4CCB-BD7B-1AE989A32853") self.characteristicUUID = CBUUID(string: "F4BD0CA2-7581-40E2-A517-1CE275A3A749") centralManager = CBCentralManager(delegate: self, queue: nil, options: [CBCentralManagerOptionShowPowerAlertKey: true]) } func stopAction() { centralManager.stopScan() } private func cleanup() { guard let discoveredPeripheral = discoveredPeripheral, case .connected = discoveredPeripheral.state else { return } for service in (discoveredPeripheral.services ?? [] as [CBService]) { for characteristic in (service.characteristics ?? [] as [CBCharacteristic]) { if characteristic.uuid == characteristicUUID && characteristic.isNotifying { self.discoveredPeripheral?.setNotifyValue(false, for: characteristic) } } } centralManager.cancelPeripheralConnection(discoveredPeripheral) } private func writeData() { guard let discoveredPeripheral = discoveredPeripheral, let transferCharacteristic = transferCharacteristic else { return } while writeIterationsComplete < defaultIterations && discoveredPeripheral.canSendWriteWithoutResponse { writeIterationsComplete += 1 } if writeIterationsComplete == defaultIterations { discoveredPeripheral.setNotifyValue(false, for: transferCharacteristic) } } } extension CentralViewModel: CBCentralManagerDelegate { func centralManagerDidUpdateState(_ central: CBCentralManager) { switch central.state { case .poweredOn: print("Power on") startScanningForPeripherals() return case .poweredOff : print("Power off") return case .resetting: print("Resetting") return case .unauthorized: print("Unauthorized") return case .unknown: print("Unknown") return case .unsupported: print("Unsupported") return @unknown default: print("An unknown central manager state has occurred") return } } func startScanningForPeripherals() { self.centralManager.scanForPeripherals(withServices: [self.serviceUUID], options: nil) } func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { guard RSSI.intValue >= -50 else { return } if discoveredPeripheral != peripheral { print("Peripheral discovered") discoveredPeripheral = peripheral centralManager.connect(peripheral, options: nil) } } func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { peripheral.delegate = self peripheral.discoverServices([serviceUUID]) print("Service discovered") } } extension CentralViewModel: CBPeripheralDelegate { func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { if error != nil { cleanup() return } guard let peripheralServices = peripheral.services else { return } for service in peripheralServices { peripheral.discoverCharacteristics([characteristicUUID], for: service) } } func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { if let error = error { print("Error discovering characteristics: \(error.localizedDescription)") cleanup() return } guard let serviceCharacteristics = service.characteristics else { return } for characteristic in serviceCharacteristics where characteristic.uuid == characteristicUUID { transferCharacteristic = characteristic peripheral.setNotifyValue(true, for: characteristic) } } func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) { if let error = error { print("Error changing notification state: \(error.localizedDescription)") return } guard characteristic.uuid == characteristicUUID else { return } if characteristic.isNotifying { print("Notification began on \(characteristic)") } else { print("Notification stopped on \(characteristic). Disconnecting") cleanup() } } func peripheralIsReady(toSendWriteWithoutResponse peripheral: CBPeripheral) { print("Peripheral is ready to send data to YOU!") } func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { if let error = error { print("Error discovering characteristics: \(error.localizedDescription)") cleanup() return } guard let characteristicData = characteristic.value, let stringFromData = String(data: characteristicData, encoding: .utf8) else { return } print("Received \(characteristicData.count) bytes: \(stringFromData)") if stringFromData == "EOM" { message = String(data: data, encoding: .utf8) ?? "" writeData() } else { data.append(characteristicData) } } }
Posted
by Tomato.
Last updated
.
Post not yet marked as solved
0 Replies
158 Views
Multiple CBPeripheralManager startAdvertising broadcast CBCentralManager can search the first CBPeripheralManager broadcast but CBCentralManager can search the second CBPeripheralManager broadcast . first CBPeripheralManager broadcast is still not stop .
Posted
by zhw0421.
Last updated
.
Post not yet marked as solved
1 Replies
321 Views
Hi All, Please excuse my relatively basic question but I am new to swift programming and I am battling with a project. I currently have an app that receives data from an Arduino using ble and displays the data as an integer. I used this medium article From Arduino programming to iOS App development as a guide for most of the functionality but changed the sensor data being sent to better suit my project requirements. Based on the link above, I have all of the bluetooth handling in PeripheralUseCase.swift file and then I have the ConnectView file for the display: @ObservedObject var viewModel: ConnectViewModel @Environment(\.dismiss) var dismiss @State var isToggleOn: Bool = false @State var isPeripheralReady: Bool = false @State var lastPressure: Int = 0 var body: some View { VStack { Text(viewModel.connectedPeripheral.name ?? "Unknown") .font(.title) ZStack { CardView() VStack { Text("Surface") HStack { Button("Flats") { viewModel.flats() } .disabled(!isPeripheralReady) .buttonStyle(.borderedProminent) Button("FlatPoint") { viewModel.flatPoint() } .disabled(!isPeripheralReady) .buttonStyle(.borderedProminent) Button("Points") { viewModel.points() } .disabled(!isPeripheralReady) .buttonStyle(.borderedProminent) } } } ZStack { CardView() VStack { Text("\(lastPressure) kPa") .font(.largeTitle) HStack { Spacer() .frame(alignment: .trailing) Toggle("Notify", isOn: $isToggleOn) .disabled(!isPeripheralReady) Spacer() .frame(alignment: .trailing) } } } Spacer() .frame(maxHeight:.infinity) Button { dismiss() } label: { Text("Disconnect") .frame(maxWidth: .infinity) } .buttonStyle(.borderedProminent) .padding(.horizontal) } .onChange(of: isToggleOn) { newValue in if newValue == true { viewModel.startNotifyPressure() } else { viewModel.stopNotifyPressure() } let startTime = Date().timeIntervalSince1970 } .onReceive(viewModel.$state) { state in switch state { case .ready: isPeripheralReady = true case let .Pressure(temp): lastPressure = temp default: print("Not handled") } } } } struct PeripheralView_Previews: PreviewProvider { final class FakeUseCase: PeripheralUseCaseProtocol { var peripheral: Peripheral? var onWriteLedState: ((Bool) -> Void)? var onReadPressure: ((Int) -> Void)? var onPeripheralReady: (() -> Void)? var onError: ((Error) -> Void)? func writeLedState(isOn: String) {} func readPressure() { onReadPressure?(25) } func notifyPressure(_ isOn: Bool) {} } static var viewModel = { ConnectViewModel(useCase: FakeUseCase(), connectedPeripheral: .init(name: "iOSArduinoBoard")) }() static var previews: some View { ConnectView(viewModel: viewModel, isPeripheralReady: true) } } struct CardView: View { var body: some View { RoundedRectangle(cornerRadius: 16, style: .continuous) .shadow(color: Color(white: 0.5, opacity: 0.2), radius: 6) .foregroundColor(.init(uiColor: .secondarySystemBackground)) } } With the associated View Model: @Published var state = State.idle var useCase: PeripheralUseCaseProtocol let connectedPeripheral: Peripheral init(useCase: PeripheralUseCaseProtocol, connectedPeripheral: Peripheral) { self.useCase = useCase self.useCase.peripheral = connectedPeripheral self.connectedPeripheral = connectedPeripheral self.setCallbacks() } private func setCallbacks() { useCase.onPeripheralReady = { [weak self] in self?.state = .ready } useCase.onReadPressure = { [weak self] value in self?.state = .Pressure(value) } useCase.onWriteLedState = { [weak self] value in self?.state = .ledState(value) } useCase.onError = { error in print("Error \(error)") } } func startNotifyPressure() { useCase.notifyPressure(true) } func stopNotifyPressure() { useCase.notifyPressure(false) } func readPressure() { useCase.readPressure() } func flats() { useCase.writeLedState(isOn: "1") } func flatPoint() { useCase.writeLedState(isOn: "2") } func points() { useCase.writeLedState(isOn: "3") } } extension ConnectViewModel { enum State { case idle case ready case Pressure(Int) case ledState(Bool) } } What I am now trying to do is plot the data that is received from the Arduino in a line graph as it is received. Preferably the graph will scroll with time as well.
Posted
by tbuys.
Last updated
.
Post not yet marked as solved
0 Replies
345 Views
As per iOS SMS sending API, there is no option to send SMS programmatically without user consent. Developer needs to use the MessageUI framework to get iPhone user consent for sending SMS. In that case, if any third party SmartWatch connected through BLE with iPhone received SMS notification through ANCS and want to reply to that SMS, After typing and sending from Watch, user needs to perform this additional step in iPhone - give consent. But if we use Apple watch, this consent in iPhone is not required if Apple Watch is already paired with iPhone. After typing text in Apple Watch, can send SMS to receiver through utilizing iPhone's SMS service without any user interaction. What is the reason of this difference? For sending SMS, iPhone and Apple Watch needs to be paired. Similarly, even third party SmartWatch also performs BLE connection and pair together before sending SMS text from Watch to iPhone to forward to receiver. But in that case why another additional user consent is required in iPhone? If we consider iPhone and Apple Watch case, pairing with each other is considered as user consent for sending any SMS later from Watch utilizing iPhone. Then, why BLE pairing between iPhone and other third party Watch not considered as user consent and additional user consent is required for each time SMS sending?
Posted
by Unique_23.
Last updated
.
Post not yet marked as solved
2 Replies
343 Views
When calling CBCentralManager's connectPeripheral:options: with some Bluetooth devices I'm getting the "Bluetooth Pairing Request" alert on iOS and a similar "Connection Request from:" alert on macOS. Is there a way to determine upfront if the alert is going to be presented or not? Alternatively is there a way to prohibit presenting this alert (in which case the connect request could fail, which is totally fine)? I tried specifying these options: var manager: CBCentralManager ... manager.connect( peripheral, options: [ CBConnectPeripheralOptionNotifyOnConnectionKey: false, CBConnectPeripheralOptionNotifyOnDisconnectionKey: false, CBConnectPeripheralOptionNotifyOnNotificationKey: false ] ) but those didn't help (and by the doc they shouldn't help as they relate to the use case of app running in background, which is not applicable in my case – my app runs and calls connect when it is in foreground, the unwanted alert is displayed immediately).
Posted Last updated
.
Post not yet marked as solved
0 Replies
1.1k Views
Dear Apple support, We are working on one of the projects related to BLE, in which our BLE device is acting as a GATT client and my iPhone device (iPhone 13, 17.3) is acting as a GATT server. Issue being faced: Whenever my BLE device subscribes to the ANCS notifications, and the moment the IOS device starts bombarding with the notifications available in notification center, the BLE device controller's heap memory becomes UNAVAILABLE in runtime for this notifications' queue and eventually making the BLE controller to reset. Thereafter, whenever user tries making a new connection session of BLE, again same thing repeats. Notifications allowed : W-SMS, W-CALL, SMS, CALL, none other than this. Issue observed with : 150 notifications and above available in notification center, otherwise our product works fine with iPhone. We would like to know how we can curb the number of PRE-EXISTING type notifications available in the notification center flowing towards the BLE device? What best solution can be done at the IOS side, we also have IOS APP team for this project. What kind of APIs does Core Bluetooth framework can provide to the IOS developer in order to overcome this issue. Please suggest possible ways from the IPHONE device only to overcome this. BLE's software CANNOT BE CHANGED under any circumstances as the product is already in production and complaints are coming from end user (from the field). OUR GOAL : ONLY notifications which will be available in run time, i.e. AFTER SUCCESSFUL BLE connection established to be displayed in the BLE's display. We DON'T WANT older notifications to be displayed and flow towards BLE over ANCS. WE MUST make 'notification popup' option as ALLOW to be shared with our BLE device, otherwise SMS,CALL, W-SMS,W-CALL during live connection will not come on the BLE 's display.
Posted
by MM_GGN.
Last updated
.
Post not yet marked as solved
1 Replies
610 Views
Scenario: We have a museum where each exhibit has a UWB BLE accessory. A user moves around the museum with their phone application in the background. Once a user enters an exhibit area (Determined by UWB distances) a background task is initiated (audio/notification/widget). The Question: In our current understanding of the protocol, the user must pair to each exhibit anchor beforehand, significantly impairing the user experience and bloating their Bluetooth-paired device list. Is it possible now or potentially in the future to not require pairing for pre-approved devices? Alternatively, pairing to a hub that acts as an intermediary between the phone and accessories also seems like an appropriate compromise.
Posted Last updated
.