使用 CoreBluetooth 在 iOS 上更改间隔时间读取信标 RSSI

Change interval time reading beacon RSSI on iOS with CoreBluetooth

我尝试读取信标 (estimote) 的 RSSI 的频率超过每秒一次。我知道使用 Core Location nd 方法 locationManager (manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon] inRegion region: CLBeaconRegion) 是不可能的。

我找到了使用 Core Bluetooth 的建议。我的实现如下所示:

class Bluetooth : NSObject, CBCentralManagerDelegate, CBPeripheralDelegate {
    var manager: CBCentralManager!
    lazy var peripherals = [NSUUID:CBPeripheral]()


    static let sharedInstance = Bluetooth()

    private override init() {
        super.init()
        manager = CBCentralManager()
        manager.delegate = self
    }

    func centralManagerDidUpdateState(central: CBCentralManager) {
        switch(central.state) {
            case .PoweredOn:
                print("powered on")
                manager.scanForPeripheralsWithServices(nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey: NSNumber(bool: true)])
                break
            default:
                print("Unknown status")
        }
    }

    func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {   
        //fot testo only one becon
        if(peripheral.name == "EST" && peripherals.count == 0) {            
            manager.connectPeripheral(peripheral, options: nil)         
            peripherals[peripheral.identifier] = peripheral
            peripherals[peripheral.identifier]?.delegate = self     
            manager.stopScan()
        }
    }

    func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) {
        print("Connect peripheral \(peripheral.name) \(peripheral.identifier)")
        peripheral.delegate = self
        peripheral.readRSSI()
    }

    func peripheral(peripheral: CBPeripheral, didReadRSSI RSSI: NSNumber, error: NSError?) {
        let currentTime = CACurrentMediaTime();
        print("\(currentTime) \(RSSI)")
        peripheral.readRSSI()
    }
}

我在 beacon 上将广告间隔设置为 100 毫秒,毕竟似乎 peripheral (peripheral: CBPeripheral, didReadRSSI RSSI: NSNumber, error: NSError?) 每秒调用的频率不超过一次。

有没有办法每 100 毫秒读取一次 RSSI?

还有一个额外的问题——在上面的代码中,方法 peripheral (peripheral: CBPeripheral, didReadRSSI RSSI) 只运行了大约 10 次,然后就停止了。我和信标 "hung up" 是否需要重新与他联系?

我用于测试 iPhone 6s 加上 iOS9。

两个提示:

  1. 配置您的信标,使其以 10 Hz 而非 1Hz 的频率传输。每次检测到广告时,您只会收到对 CoreBluetooth 的回调。如果它每秒只广播一次,那么您只能经常获得 RSSI 读数。

  2. 删除调用connectPeripheral的代码。如果您连接到蓝牙 LE 设备,它会停止广播,您将无法再获得广播回调。

请注意,使用此技术无法保证您读取的是信标相对于附近任何其他蓝牙设备的 RSSI 值,因为 CoreBluetooth 不允许您读取信标标识符。因此,只有当附近有一个蓝牙设备时,它才能可靠地工作。