The CoreBluetooth namespace allows developers to work with Bluetooth Low Energy (Bluetooth LE) devices.
The Bluetooth LE model revolves around CoreBluetooth.CBPeer objects. There are two kinds of CoreBluetooth.CBPeer: CoreBluetooth.CBCentral objects that scan and consume data provided by CoreBluetooth.CBPeripheral objects that correspond to data-providing Bluetooth LE devices.
Generally, the iOS device will be in the CoreBluetooth.CBCentral role, but it is also possible to create apps in which the device is a CoreBluetooth.CBPeripheral.
The following example shows the typical initialization behavior of an app that consumes data from external Bluetooth LE devices. Applications that have a CoreBluetooth.CBCentral must have an associated CoreBluetooth.CBCentralManagerDelegate delegate object and must override it's CoreBluetooth.CBCentralManagerDelegate.UpdatedState method. The override must check the state of the CoreBluetooth.CBCentralManager and confirm that it is CoreBluetooth.CBCentralManagerState.PoweredOn.
Typically, applications will want to scan for Bluetooth LE peripherals. This is a high-energy function, so developers should call CoreBluetooth.CBManager.StopScan after finding the CoreBluetooth.CBPeripheral in which they are interested or after a certain amount of time.
C# Example
public class MySimpleCBCentralManagerDelegate : CBCentralManagerDelegate
{
override public void UpdatedState (CBCentralManager mgr)
{
if (mgr.State == CBCentralManagerState.PoweredOn) {
//Passing in null scans for all peripherals. Peripherals can be targeted by using CBUIIDs
CBUUID[] cbuuids = null;
mgr.ScanForPeripherals (cbuuids); //Initiates async calls of DiscoveredPeripheral
//Timeout after 30 seconds
var timer = new Timer (30 * 1000);
timer.Elapsed += (sender, e) => mgr.StopScan();
} else {
//Invalid state -- Bluetooth powered down, unavailable, etc.
System.Console.WriteLine ("Bluetooth is not available");
}
}
public override void DiscoveredPeripheral (CBCentralManager central, CBPeripheral peripheral, NSDictionary advertisementData, NSNumber RSSI)
{
Console.WriteLine ("Discovered {0}, data {1}, RSSI {2}", peripheral.Name, advertisementData, RSSI);
}
}
public partial class HelloBluetoothCSharpViewController : UIViewController
{
MySimpleCBCentralManagerDelegate myDel;
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
//Important to retain reference, else will be GC'ed
myDel = new MySimpleCBCentralManagerDelegate ();
var myMgr = new CBCentralManager (myDel, DispatchQueue.CurrentQueue);
}
//...etc...
}
The CoreBluetooth.CBCentralManagerDelegate.DiscoveredPeripheral method may be called multiple times for a single physical device. Once application developers have a reference to the CoreBluetooth.CBPeripheral in which they are interested, they should maintain that reference for further work and call CoreBluetooth.CBCentralManager.StopScan.
With a reference to a discovered CoreBluetooth.CBPeripheral, developers can then connect to it, as shown in the following example.
A CoreBluetooth.CBPeripheral has zero or more CoreBluetooth.CBServices, each of which has zero or more CoreBluetooth.CBCharacteristics. If the characteristic represents a measurement (such as a heartbeat, time, temperature, etc.), the value will be in the CoreBluetooth.CBCharacteristic.Value property.
C# Example
public class SimplePeripheralDelegate : CBPeripheralDelegate
{
public override void DiscoveredService (CBPeripheral peripheral, NSError error)
{
System.Console.WriteLine ("Discovered a service");
foreach (var service in peripheral.Services) {
Console.WriteLine (service.ToString ());
peripheral.DiscoverCharacteristics (service);
}
}
public override void DiscoveredCharacteristic (CBPeripheral peripheral, CBService service, NSError error)
{
System.Console.WriteLine ("Discovered characteristics of " + peripheral);
foreach (var c in service.Characteristics) {
Console.WriteLine (c.ToString ());
peripheral.ReadValue (c);
}
}
public override void UpdatedValue (CBPeripheral peripheral, CBDescriptor descriptor, NSError error)
{
Console.WriteLine ("Value of characteristic " + descriptor.Characteristic + " is " + descriptor.Value);
}
public override void UpdatedCharacterteristicValue (CBPeripheral peripheral, CBCharacteristic characteristic, NSError error)
{
Console.WriteLine ("Value of characteristic " + characteristic.ToString () + " is " + characteristic.Value);
}
}
//...
mgr = new CBCentralManager (myCentralDelegate, DispatchQueue.CurrentQueue);
mgr.ConnectedPeripheral += (s, e) => {
activePeripheral = e.Peripheral;
System.Console.WriteLine ("Connected to " + activePeripheral.Name);
if (activePeripheral.Delegate == null) {
activePeripheral.Delegate = new SimplePeripheralDelegate ();
//Begins asynchronous discovery of services
activePeripheral.DiscoverServices ();
}
};
//Connect to peripheral, triggering call to ConnectedPeripheral event handled above
mgr.ConnectPeripheral (myPeripheral);