swift: pair with bluetooth device with button click

喜夏-厌秋 提交于 2019-12-08 09:14:30

问题


Until now the iPhone has paired to a bluetooth device when the app is opened, but I want to pair with a button click instead. I tried to put all the scanning and connection functions in a IBAction, but nothing happens when I push the button. In the first function after the IBAction I have a print output to check if it even enters the function, but I don't get the print. I also tried to put a delay after the manager.scanForPeripherals but didn't work either. What am I missing here? anyone know? Thanks for any replies! here is my code (without the delay):

var manager: CBCentralManager!
var device: CBPeripheral?
var characteristics: [CBCharacteristic]?
var serviceUUID = "1234"
var char1 = "FFE1"
let deviceName = "HMSoft"
var connected = CBPeripheralState.connected
var disconnected = CBPeripheralState.disconnected

 override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    manager = CBCentralManager(delegate: self, queue: nil)


}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.


}
 func centralManagerDidUpdateState(_ central: CBCentralManager) {
    switch central.state {
    case .poweredOn: break
        // manager.scanForPeripherals(withServices: nil, options: nil)
    case .unknown: break

    case .resetting: break

    case .unsupported: break

    case .unauthorized: break

    case .poweredOff:

        break

    }
}


   @IBAction func connectBluetooth(_ sender: Any) {

   manager.scanForPeripherals(withServices: nil, options: nil)

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {

    if let peripheralName = advertisementData[CBAdvertisementDataLocalNameKey] as? String {

        if peripheralName == self.deviceName {

            // save a reference to the sensor tag
            self.device = peripheral
            self.device!.delegate = self

            // Request a connection to the peripheral

            self.manager.connect(self.device!, options: nil)

            print("Check")
        }
    }
}

func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {

    peripheral.discoverServices(nil)
}


func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {

    if error != nil {

        return
    }


    if let services = peripheral.services {
        for service in services {

            if (service.uuid == CBUUID(string: serviceUUID)) {
                peripheral.discoverCharacteristics(nil, for: service)
            }
        }
    }

}


func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {

    device = peripheral
    characteristics = service.characteristics

}

func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
    if error != nil {

        return
    }
}

}


回答1:


When you initialise the CBCentralManager and set its delegate, the delegate will start receiving events.

So, if you only want the CBCentralManager to be active once the user has tapped a button, rather than as soon as the screen loads, the minimum you have to do is move the code that initialises the manager from viewDidLoad to the button action.

So:

Move manager = CBCentralManager(delegate: self, queue: nil) from viewDidLoad to @IBAction func connectBluetooth(_ sender: Any),

Remove the call to scanForPeripherals from the IBAction, and;

Uncomment // manager.scanForPeripherals(withServices: nil, options: nil) in centralManagerDidUpdateState.




回答2:


Don't put the function func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) inside the button.

Try instead this:

@IBAction func connectBluetooth(_ sender: Any) {
   manager = CBCentralManager(delegate: self, queue: nil)
   manager.scanForPeripherals(withServices: nil, options: nil)
}

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {

    if let peripheralName = advertisementData[CBAdvertisementDataLocalNameKey] as? String {

        if peripheralName == self.deviceName {

            // save a reference to the sensor tag
            self.device = peripheral
            self.device!.delegate = self

            // Request a connection to the peripheral

            self.manager.connect(self.device!, options: nil)

            print("Check")
        }
    }
}

It's quite important that the device know that BLE is on before you can scan.

func centralManagerDidUpdateState(_ central: CBCentralManager) {
        switch (central.state) {
        case .unsupported:
            print("BLE is unsupported")
        case .unauthorized:
            print("BLE is unauthorized")
        case .unknown:
            print("BLE is unknown")
        case .resetting:
            print("BLE is reseting")
        case .poweredOff:
            print("BLE is powered off")
        case .poweredOn:
            print("BLE is powered on")
            //must be called
        }
    }


来源:https://stackoverflow.com/questions/48996717/swift-pair-with-bluetooth-device-with-button-click

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!