I am connecting to a peripheral using Core Bluetooth on iOS 13 and swift 5. I have no issues connecting or discovering services and characteristics. However, I can't seem to save the said services and characteristics for later use.
Here is my main CentralManager class that connects to the peripheral and accesses its services:
class CentralManager : NSObject{
private var centralManager : CBCentralManager!
var peripheralZero : CBPeripheral!
override init(){
super.init()
centralManager = CBCentralManager(delegate: self, queue: nil)
}
func startScanning(){
if centralManager.state == .poweredOn{
centralManager.scanForPeripherals(withServices: nil, options: nil)
}
}
}
// MARK: - CBCentralManager Delegate Methods
extension CentralManager: CBCentralManagerDelegate{
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == .poweredOn{
print("central powered on")
}else{
print("Central does not support bluetooth")
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber){
if(peripheral.identifier == ParticlePeripheral.DeviceUUID! as UUID){
centralManager.stopScan()
peripheralZero = peripheral //Here I save the found peripheral
peripheral.delegate = self
centralManager.connect(self.peripheralZero, options: nil)
}
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
print("connection successful")
peripheralZero.discoverServices(nil)
}
}
//MARK: - CBPeripheral Delegate Methods
extension CentralManager: CBPeripheralDelegate{
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
if let services = peripheralZero.services { // this executes to nil but if I instead use:
// if let services = peripheral.services
// it works
for service in services{
print(service)
peripheral.discoverCharacteristics(nil, for: service)
}
}
}
}
from Apple's documentation in regards to the services property of the peripheral:
If you haven't yet called the discoverServices(_:) method to discover the services of the peripheral, or if there was an error in doing so, the value of this property is nil.
Since I have already called discoverServices shouldn't I be able to retrieve them using my peripheralZero variable? Regardless of where I try to access it in my code, the value is nil. I'm guessing the way I'm saving the peripheral is where the issue is being caused, but I really have no idea. I'm new to swift so any help would be greatly appreciated!
extension XXTrain: CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
let cState = central.state
switch cState {
case .poweredOn:
print(">>central.state is .poweredOn")
centralManager.scanForPeripherals(withServices: services)
@unknown default: break
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
discoveredPeripherals[peripheral.identifier] = peripheral
myPeripheral = peripheral
centralManager.connect(peripheral)
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
print(" -- Connected: \((peripheral.state == .connected) ? "YES" : "NO"), \(String(describing: peripheral.name)), UUID: \(peripheral.identifier)")
peripheral.delegate = self
peripheral.discoverServices(services)
}
}
extension XXTrain: CBPeripheralDelegate {
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
guard let services = peripheral.services else { return }
for service in services {
print(" >> Discover Services Found : \(service.uuid) service")
peripheral.discoverCharacteristics(nil, for: service)
}
}
what I found was the order/placement of
peripheral.delegate = self
is important to be placed in didConnect
instead of in disDiscover
and
myPeripheral = peripheral
where it is "to hold a strong reference" to be placed in didDiscover
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.