【问题标题】:Core Bluetooth CBCentralManager always reports state as Unknown on Mac核心蓝牙 CBCentralManager 在 Mac 上总是将状态报告为未知
【发布时间】:2016-08-17 08:25:05
【问题描述】:

总的来说,我是 Swift 和 Mac/iOs 编程的新手。我正在使用 Xcode 7.3 在支持 BLE 并打开蓝牙的 Macbook Pro 上运行此示例。

import Foundation
import CoreBluetooth

func printState(state: CBCentralManagerState) {
    switch state {
    case CBCentralManagerState.PoweredOn:
        print("Powered on")
    case CBCentralManagerState.PoweredOff:
        print("Powered off")
    case CBCentralManagerState.Resetting:
        print("Resetting")
    case CBCentralManagerState.Unauthorized:
        print("Unauthorized")
    case CBCentralManagerState.Unknown:
        print("Unknown")
    default:
        print ("Unsupported")
    }

}

var myCentralManager = CBCentralManager(delegate:nil, queue:nil)
while true {
    printState(myCentralManager.state)
    sleep(1)
}

代码一遍又一遍地打印出“未知”,即使在几分钟后也是如此。我也尝试过设置委托,但没有调用 didUpdateState 回调。我也尝试从命令行和 Swift 解释器运行它并得到相同的结果。

我一定遗漏了一些非常基本的东西。如何让它报告 CBCentralManager 已开机?

【问题讨论】:

    标签: ios macos bluetooth


    【解决方案1】:

    据我所知,如果您不使用文档中列出的两个初始化程序之一,这就是结果——您想使用其中一个:

    init(delegate:queue:)
    

    或:

    init(delegate:queue:options:)
    

    如果您只是调用,Xcode 不会抱怨:

    CBCentralManager()
    

    但如果你这样做,你似乎会无限期地留在CBCentralManagerState.Unknown

    如果您想进行实验,请创建一个 Playground 并粘贴此代码,然后使用我列出的两个初始化变量进行尝试:

    import Cocoa
    import CoreBluetooth
    import XCPlayground
    
    @objc
    public class BluetoothWatcher: NSObject, CBCentralManagerDelegate {
        var cbcm: CBCentralManager!;
        var timer: NSTimer!;
    
        override init() {
            super.init();
    
            /*:
                When you initialize a central manager, the delegate seems important. If you comment out the initializer with the delegate and uncomment the other one, it'll stay in state unknown indefinitely.
            */
            //cbcm = CBCentralManager(delegate: self, queue:nil);
            cbcm = CBCentralManager();
    
            checkStateInOneSecond();
        }
    
        public func centralManagerDidUpdateState(central: CBCentralManager) {
            print( "State updated: \(stateString())" );
        }
    
        func checkStateInOneSecond() {
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (Int64)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), {
                self.checkState();
            });
        }
    
        public func checkState() {
            print( "Timer fired, state: \(stateString())" );
            checkStateInOneSecond();
        }
    
        func stateString() -> String {
            switch(cbcm.state) {
            case .Resetting:
                return "resetting"
            case .PoweredOn:
                return "powered on";
            case .PoweredOff:
                return "powered off";
            case .Unknown:
                return "unknown";
            case .Unsupported:
                return "unsupported";
            case .Unauthorized:
                return "unauthorized";
            }
        }
    }
    
    
    XCPlaygroundPage.currentPage.needsIndefiniteExecution = true;
    var watcher = BluetoothWatcher();
    

    你会看到委托,它从Unknown开始,几乎立即委托被调用,状态更改为PoweredOn,随后的每个计时器触发都显示PoweredOn

    在没有委托的情况下使用空初始化器执行相同的操作,并且永远不会调用委托方法(不足为奇)并且计时器触发将继续显示Unknown

    【讨论】:

    • 得到了它与代表的合作。我之前尝试过这个,但它不起作用,因为我没有调用 dispatch_main
    • 这完全正确。感谢您为我节省了更多用头撞桌子的时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-27
    • 1970-01-01
    • 1970-01-01
    • 2015-01-26
    • 2018-05-14
    • 2014-11-25
    相关资源
    最近更新 更多