访问BluetoothManagerDelegate类

时间:2016-08-17 02:37:30

标签: ios swift xcode bluetooth

所以我刚开始使用Swift语言(v2.2)使用XCode(v7.3),我正在尝试编写一个单页应用程序,通过按下按钮连接到目标BLE设备。

我在以下网站上关注了核心蓝牙框架的简短教程:http://hatemfaheem.blogspot.com/2014/12/how-would-you-scan-for-nearby-ble.html

让我创建了以下类结构:

class BLEManager{
    var centralManager:CBCentralManager
    var bleHandler:BLEHandler
    init() {
        self.bleHandler = BLEHandler()
        self.centralManager = CBCentralManager(delegate: self.bleHandler, queue: nil
    }
}

class BLEHandler : NSObject, CBCentralManagerDelegate {
    override init() {
        super.init()
    }
    func CentralManagerDidUpdateState(central: CBCentralManager) {
        var status:String
        switch(central.state) {
        case .PoweredOn
            status = "Powered On"
            //ble_show()
        case .PoweredOff
            status = "Powered Off"
            //ble_hide()
        }//Note: several cases have been omitted to reduce length
        print(status)
    }
}

var bleManager = BLEManager()

在我的ViewController.swift文件的ViewController类中插入这些类定义并声明BLEManager类的实例后,我可以看到控制台中显示字符串“Powered On”和“Powered Off”,因为我打开了蓝牙在运行应用程序时在我的iPhone上打开和关闭。

问题是当我调用上面代码“ble_show()”和“ble_hide”中的函数时出现错误(这就是为什么它们被注释掉了)。我假设问题是因为这些函数是总体ViewController类的成员,你不能从嵌套类中调用这些函数:BLEHandler。

ble_show()和ble_hide()函数只是为按钮设置“隐藏”标志,以便向用户显示它。我希望这些按钮仅在用户打开蓝牙时才可用。所以BLEHandler类需要以某种方式访问​​在ViewController类中声明的这些按钮,但我似乎不明白如何做到这一点。我尝试在BLEHandler类中移动所有函数声明和UIButton声明,但是当我这样做时,XCode真的不喜欢它。

我的部分问题是我正在同时学习Swift,XCode和Core蓝牙框架,所以如果有人能够解释如何尽可能彻底地完成我正在尝试的内容,这将非常有帮助。我习惯在一个简单的main()函数的环境中进行编程,而不是使用一个类作为main()(这就是我目前对ViewController类的处理方式)。

如果我理解正确,CBCentralManagerDelegate会将我的代码的某些部分注册到一个事件,该事件会在蓝牙状态发生变化时调用我的CentralManagerDidUpdateState()成员函数。但是,如何在发生这些事件时告诉我的ViewController做什么?

1 个答案:

答案 0 :(得分:1)

通过将蓝牙管理器与视图控制器分离(这是一个很好的设计),您无法直接更新视图控制器中的项目。您可以使用NSNotification或协议/代理通知视图控制器蓝牙状态更改。

由于可能有很多对象对蓝牙事件感兴趣,我会在这种情况下使用NSNotification。

在ViewController类中,您可以为特定通知注册观察者:

override func viewDidLoad() {
    super.viewDidLoad()

    let notificationCenter = NSNotificationCenter.defaultCenter()

    notificationCenter.addObserver(self, selector: #selector(ViewController.bluetoothChanged(_:)), name: "bleStateChange", object: nil)
}

@objc func bluetoothChanged(notification: NSNotification) {

    if let status = notification.userInfo["statusString"] as? String {
        print("Bluetooth status = \(status)")
    }
}

BLEManager中,您需要发布通知:

func CentralManagerDidUpdateState(central: CBCentralManager) {
    var status:String
    switch(central.state) {
        case .PoweredOn
            status = "Powered On"
            //ble_show()
        case .PoweredOff
            status = "Powered Off"
            //ble_hide()
    }//Note: several cases have been omitted to reduce length
    print(status)
    let notificationCenter = NSNotificationCenter.defaultCenter()
    let userInfo = ["statusString":"powered off","centralState":central.state.rawValue] as [String:AnyObject]
    notificationCenter.postNotificationName("bleStateChange", object: nil, userInfo: userInfo)
}