所以我刚开始使用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做什么?
答案 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)
}