NOTE: Apple's CoreBluetooth library, which this project uses, only supports Bluetooth LE 4.0+. We're hoping to get future updates that support other versions of Bluetooth.
ReactiveCoreBluetooth is a library that wraps Apple's CoreBluetooth framework by providing ReactiveCocoa signals instead of delegates. This library is currently a work-in-progress that provides basic Bluetooth LE device management. There is a sample app included in this repo that shows how to make use of this wrapper.
#import "ReactiveCoreBluetooth.h"
@property (nonatomic) BluetoothLEService* bluetoothLEService;
-(void) viewDidLoad
{
self.bluetoothLEService = [[BluetoothLEService alloc] init];
[bluetoothLEService.availableDevicesSignal subscribeNext:^(NSArray* devices) {
for (CBPeripheral* p in devices)
{
NSLog(@"%@", p.name);
}
}];
[bluetoothLEService.peripheralConnectedSignal subscribeNext:^(CBPeripheral* device) {
NSLog(@"Connected to %@", device.name);
}];
[bluetoothLEService.peripheralDisconnectedSignal subscribeNext:^(CBPeripheral* device) {
NSLog(@"Disconnected from %@", device.name);
}];
[bluetoothLEService.scanningForDevicesSignal subscribeNext:^(NSNumber* x) {
BOOL isScanning = [x boolValue];
if (isScanning)
{
NSLog("Scanning for devices...");
}
else
{
NSLog("Not scanning for devices.");
}
}];
[bluetoothLEService.bluetoothStateSignal subscribeNext:^(NSNumber* x) {
CBCentralManagerState state = (CBCentralManagerState)[x integerValue];
NSString* status;
switch (state)
{
case CBCentralManagerStatePoweredOff:
status = @"Off";
break;
case CBCentralManagerStatePoweredOn:
status = @"On";
break;
case CBCentralManagerStateResetting:
status = @"Resetting";
break;
case CBCentralManagerStateUnauthorized:
status = @"Unauthorized";
break;
case CBCentralManagerStateUnknown:
status = @"Unknown";
break;
case CBCentralManagerStateUnsupported:
status = @"Unsupported";
break;
default:
status = @"Error: State Unknown";
break;
}
NSLog(@"Bluetooth status: %@", status);
}];
[bluetoothLEService scanForAvailableDevices];
}
We prefer to use ReactiveCocoa signals and blocks to manage asynchronous eventing instead of delegates. If you don't like implementing delegates everywhere, this is the Bluetooth LE library for you!
Add the following line to your Podfile:
pod 'ReactiveCoreBluetooth'
Then run the following in the same directory as your Podfile:
pod install
To start scanning for devices, call scanForAvailableDevices
. You can listen on the scanningForDevicesSignal
to determine if the device is currently scanning. To receive notifications about when the list of available devices changes, listen on the availableDevicesSignal
. To stop scanning for devices, call stopScanningForDevices
.
To capture device connections, subscribe to the peripheralConnectedSignal
. To capture device disconnections, subscribe to the peripheralDisconnectedSignal
.
Listen on the bluetoothStateSignal
.
The cacheDurationForDevices
setting allows you to change how long to wait while trying to connect to a device. The default is 5 seconds.
The cachePollingInterval
setting allows you to change how frequently the cache is polled for expired devices. The default is 3 seconds.
The connectOnDiscovery
setting allows you to specify whether you want to connect to the device before it is added to the available devices signal. Some BLE devices need a connection to provide a name, while others might behave differently or cease advertising themselves once a connection is initiated.
Matt Bowman (matt at citrrus dot com)
Copyright 2013 Citrrus, LLC.
Licensed under the MIT license.