I'm new to Swift and Mac/iOs programming in general. I'm running this sample on a Macbook Pro with BLE support and with Bluetooth turned on, using Xcode 7.3.
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)
}
The code prints out "Unknown" over and over, even after many minutes. I've also tried setting up a delegate but the didUpdateState callback doesn't called. I've also tried to run this from the command line and Swift interpreter and get the same result.
I must be missing something very basic. How can I get it to report that the CBCentralManager is powered on?
Near as I can tell, if you don't use one of the two initializers listed in the documentation, this is the result -- you want to use either:
init(delegate:queue:)
or:
init(delegate:queue:options:)
Xcode doesn't complain if you just call:
CBCentralManager()
but if you do that, it seems like you'll stay in CBCentralManagerState.Unknown
indefinitely.
If you want to experiment, make a playground and paste this code, and try it with the two initializer variants I've listed:
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();
You'll see with the delegate, it starts in Unknown
, and almost immediately the delegate gets called with a state change to PoweredOn
, and every subsequent timer fire shows PoweredOn
.
Do the same thing without the delegate, with the empty initializer, and the delegate method will never be called (no surprise) and the timer fires will continue to show Unknown
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With