簡體   English   中英

在swift中聽一個事件舞會藍牙外圍設備

[英]listening for an event prom bluetooth peripheral in swift

我有一個可以使用藍牙低功耗的Dash按鈕。 我可以掃描並找到它,連接它並發現它的服務。

現在我想聽聽它是否按下了按鈕。但是我覺得這個部件有一些嚴重的問題。 我是斯威夫特的新人,所以如果你能幫助我解決它,我真的很感激。

這是我的快捷代碼:

import CoreBluetooth
import UIKit

struct DisplayPeripheral{
    var peripheral: CBPeripheral?
    var lastRSSI: NSNumber?
    var isConnectable: Bool?
}

class PeripheralViewController: UIViewController {

    @IBOutlet weak var statusLabel: UILabel!
    @IBOutlet weak var bluetoothIcon: UIImageView!
    @IBOutlet weak var scanningButton: ScanButton!

    var centralManager: CBCentralManager?
    var peripherals: [DisplayPeripheral] = []
    var viewReloadTimer: Timer?
    let BEAN_NAME = "Security Tag"
    let BEAN_SCRATCH_UUID = CBUUID(string: "90946c81-e466-4a43-9974-949e465d35a1")
    let BEAN_SERVICE_UUID = CBUUID(string: "00001c00-d102-11e1-9b23-000efb0000a7")

    var selectedPeripheral: CBPeripheral?

    @IBOutlet weak var tableView: UITableView!

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        //Initialise CoreBluetooth Central Manager
        centralManager = CBCentralManager(delegate: self, queue: DispatchQueue.main)
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        viewReloadTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(PeripheralViewController.refreshScanView), userInfo: nil, repeats: true)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        viewReloadTimer?.invalidate()
    }

    func updateViewForScanning(){
        statusLabel.text = "Scanning BLE Devices..."
        bluetoothIcon.pulseAnimation()
        bluetoothIcon.isHidden = false
        scanningButton.buttonColorScheme(true)
    }

    func updateViewForStopScanning(){
        let plural = peripherals.count > 1 ? "s" : ""
        statusLabel.text = "\(peripherals.count) Device\(plural) Found"
        bluetoothIcon.layer.removeAllAnimations()
        bluetoothIcon.isHidden = true
        scanningButton.buttonColorScheme(false)
    }

    @IBAction func scanningButtonPressed(_ sender: AnyObject){
        if centralManager!.isScanning{
            centralManager?.stopScan()
            updateViewForStopScanning()
        }else{
            startScanning()
        }
    }

    func startScanning(){
        peripherals = []
        self.centralManager?.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey: true])
        updateViewForScanning()
        let triggerTime = (Int64(NSEC_PER_SEC) * 10)
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(triggerTime) / Double(NSEC_PER_SEC), execute: { () -> Void in
            if self.centralManager!.isScanning{
                self.centralManager?.stopScan()
                self.updateViewForStopScanning()
            }
        })
    }

    func refreshScanView()
    {
        if peripherals.count > 1 && centralManager!.isScanning{
            tableView.reloadData()
        }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let destinationViewController = segue.destination as? PeripheralConnectedViewController{
            destinationViewController.peripheral = selectedPeripheral
        }
    }
}

extension PeripheralViewController: CBCentralManagerDelegate{
    func centralManagerDidUpdateState(_ central: CBCentralManager){
        //if (central.state == CBCentralManagerState.poweredOn){
            startScanning()
        //}else{
            // do something like alert the user that ble is not on
        //}
    }

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

        for (index, foundPeripheral) in peripherals.enumerated(){
            if foundPeripheral.peripheral?.identifier == peripheral.identifier{
                peripherals[index].lastRSSI = RSSI
                return
            }
        }

        let isConnectable = advertisementData["kCBAdvDataIsConnectable"] as! Bool
        if(peripheral.name == BEAN_NAME)
        {
            print(peripheral.name)
            print(peripheral.identifier)
            print("is?",isConnectable)
            let displayPeripheral = DisplayPeripheral(peripheral: peripheral, lastRSSI: RSSI, isConnectable: isConnectable)
            peripherals.append(displayPeripheral)
        }

        tableView.reloadData()
    }


}

extension PeripheralViewController: CBPeripheralDelegate {
    func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
        print("Error connecting peripheral: \(error?.localizedDescription)")
    }

    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral)
    {
        print("Peripheral connected")
        performSegue(withIdentifier: "PeripheralConnectedSegue", sender: self)
        peripheral.discoverServices(nil)

    }
    func peripheral(peripheral: CBPeripheral, didDiscoverServices error: NSError?)
    {
        print("jdbsud")

        for service in peripheral.services!
        {
            let thisService = service as CBService

            if service.uuid == BEAN_SERVICE_UUID {
                peripheral.discoverCharacteristics(nil,for: thisService)
            }
        }
    }


}

extension PeripheralViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{

        let cell = self.tableView.dequeueReusableCell(withIdentifier: "cell")! as! DeviceTableViewCell
        cell.displayPeripheral = peripherals[indexPath.row]
        cell.delegate = self
        return cell
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
        return peripherals.count
    }
}

extension PeripheralViewController: DeviceCellDelegate{
    func connectPressed(_ peripheral: CBPeripheral) {
        if peripheral.state != .connected {
            selectedPeripheral = peripheral
            peripheral.delegate = self
            centralManager?.connect(peripheral, options: nil)
            //you can listen to the commands here


        }
    }

    }

我在func外設中打印了一些東西(外設:CBPeripheral,didDiscoverServices錯誤:NSError?)來檢查我是否進入那里,顯然我沒有輸入那部分代碼。

在努力解決問題后,我自己能夠解決它。

在找到服務后,我應該將這兩個函數添加到代碼中,它就像一個魅力:

  func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
    debugPrint("Enabling ...")

    for characteristic in service.characteristics! {
        let thisCharacteristic = characteristic as CBCharacteristic

        debugPrint("Characteristic: ", thisCharacteristic.uuid)

        if thisCharacteristic.uuid == BEAN_SCRATCH_UUID {
            debugPrint("Set to notify: ", thisCharacteristic.uuid)

            // Prepare to show data

            self.peripheral.setNotifyValue(true, for: thisCharacteristic)
       }
    }
}

func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
    if characteristic.uuid == BEAN_SCRATCH_UUID {
        let content = String(data: characteristic.value!, encoding: String.Encoding.utf8)

        debugPrint("Notified.")
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM