管理BLE中心对象的最佳方式

时间:2017-08-15 10:59:23

标签: ios swift bluetooth core-bluetooth

我正在开发一个能够做这样的事情的应用程序。

我的应用应该与BLE外设连接,我想继续监控连接。当断开连接时,它应该采取locatoin并更新地图。我需要跟踪断开连接,即使外围设备在我的应用程序中关闭了事件。

我有两个视图控制器。一个是更新我的谷歌地图。另一个是tableViewController,列出了可用的设备列表。我使用Singolton模式实现了BLE Manager。

class BleManager: NSObject , CBCentralManagerDelegate, CBPeripheralDelegate {

var centralManager: CBCentralManager?
var peripherals = Array<CBPeripheral>()
var periparal : CBPeripheral!

let dataSaver = DataSaver.sharedInstance
let locationMgr = LocationInfo.sharedInstance
var viewController  : CarList!


static let shared = BleManager()



//MARK:- Initialiser

private override init() {
    super.init()
        centralManager = CBCentralManager(delegate: self, queue: DispatchQueue.main)
}

init(vc : CarList) {
    super.init()
    viewController = vc
    //centralManager = CBCentralManager(delegate: self, queue: DispatchQueue.main)
}




//MARK:- BLE Activities

func startScanForDevices() {
    peripherals = []
    //self.centralManager?.scanForPeripherals(withServices: [CBUUID(string: "DFB0")], options: nil)
    self.centralManager?.scanForPeripherals(withServices: nil, options: nil)
    //self.centralManager?.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey : true])

}

func stopScanForDevices() {
    if centralManager != nil {
        centralManager?.stopScan()
    }
}

func connectToADevice(pheriperal : CBPeripheral){

    periparal = pheriperal
    // saving Connected Car in App LifeSycle
    connectedCar = pheriperal
    centralManager?.connect(pheriperal, options: nil)
    (viewController != nil) ? viewController.devTable.reloadData() : print("")


}


func disconnectFromApp(pheriperal : CBPeripheral){
    centralManager?.cancelPeripheralConnection(pheriperal)
}






//MARK:- BLE Central Delegates

func centralManagerDidUpdateState(_ central: CBCentralManager) {
    if (central.state == .poweredOn){
        startScanForDevices()
    }
    else if (central.state == .poweredOff){
        print("Powered Off")
        centralManager?.cancelPeripheralConnection(periparal)
    }
    else if (central.state == .resetting){
        print("resetting")
    }
    else if (central.state == .unauthorized){
        print("unauthorized")
    }
    else if (central.state == .unsupported){
        print("unsupported")
    }else{
        print("Unknown")
    }

}



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

    //peripherals.append(peripheral)
    //print("DEVICES LIST : \(peripherals)")

    updatePheriperals(device: peripheral)

    if viewController != nil {
        viewController.devTable.reloadData()

        if dataSaver.isAnyCarHasBeenSaved() == true && dataSaver.getMyCarIdentification() == peripheral.identifier.uuidString && peripheral.state == .disconnected{
            connectToADevice(pheriperal: peripheral)
            viewController.devTable.reloadData()
        }
    }else{
        if dataSaver.isAnyCarHasBeenSaved() == true && dataSaver.getMyCarIdentification() == peripheral.identifier.uuidString{
            connectToADevice(pheriperal: peripheral)

        }
    }

}

func updatePheriperals(device : CBPeripheral) {
    if peripherals.count != 0 {
        for dev in peripherals {
            if device.identifier != dev.identifier {
                peripherals.append(device)
            }
        }
    }else{
        peripherals.append(device)
    }
}


func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {

    print("\(ConnectionState(rawValue: peripheral.state.rawValue)?.name()) \(peripheral.name) from App.. Taking Geo cordinates")

    locationMgr.didFindLocation = false
    locationMgr.getCurrentLocation()

    if viewController != nil {
        viewController.devTable.reloadData()
    }else{
       print("Just Updating Locations")
    }

    showNotification(message: peripheral.name! + " has been Disconnected from Find My Car" )

    startScanForDevices()

}

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

    print("\(ConnectionState(rawValue: peripheral.state.rawValue)?.name()) \(peripheral.name) to App.. Removeing previous location")

    dataSaver.removeLocation()
    dataSaver.saveMyCarIdentification(myCar: peripheral.identifier.uuidString)

    (viewController != nil) ? viewController.devTable.reloadData() : print("Just Updating Locations")
    //print("Service UUIDs : \(peripheral)")
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: AppStrings.updateMapString), object: nil)

    showNotification(message: peripheral.name! + " has been connected to Find My Car" )
}






func centralManager(_ central: CBCentralManager, willRestoreState dict: [String : Any]) {
    print("Already Connected Pheriperals : \(dict[CBCentralManagerRestoredStatePeripheralsKey])")
}


func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
    print("Failed To Connect with \(peripheral.name)")

    centralManager?.cancelPeripheralConnection(peripheral)
}

在我的MapViewController中,我使用sharedInstance并开始扫描

即使在我的TableViewController中也是如此。

但有时当我尝试关闭外围设备时,我的BLE Central没有调用断开外设委托。

我也想知道如何处理背景扫描。国家预防和恢复(我对此一无所知。我只是想在后台以同样的方式在我的应用程序中放弃我的应用程序)

请帮忙

0 个答案:

没有答案