简体   繁体   English

iOS 13 Core 蓝牙保存的外围服务在被发现后显示为零

[英]iOS 13 Core Bluetooth saved peripheral services showing nil after already being discovered

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.我在 iOS 13 和 swift 5 上使用 Core Bluetooth 连接到外围设备。我在连接或发现服务和特性方面没有问题。 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:这是我连接到外围设备并访问其服务的主要 CentralManager 类:

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.如果您还没有调用discoverServices(_:) 方法来发现外设的服务,或者如果这样做有错误,则该属性的值为nil。

Since I have already called discoverServices shouldn't I be able to retrieve them using my peripheralZero variable?既然我已经调用了discoverServices,难道我不应该能够使用我的peripheralZero 变量来检索它们吗? Regardless of where I try to access it in my code, the value is nil.无论我尝试在代码中的何处访问它,该值都是 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!我是 swift 的新手,所以任何帮助将不胜感激!

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重要的是放在didConnect而不是disDiscover

myPeripheral = peripheral

where it is "to hold a strong reference" to be placed in didDiscoverdidDiscover放置“持有强引用”的didDiscover

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM