Core Bluetooth snippets with Swift

Tsutsumi Shuichi
5 min readFeb 24, 2016

--

This article shows simple examples (code snippets) of Core Bluetooth with Swift & Objective-C.

import

objc

@import CoreBluetooth;

swift

import CoreBluetooth

Central Manager

Initialize

Adopt protocol and define properties.

objc

@interface SomeClass () <CBCentralManagerDelegate>
@property (nonatomic, strong) CBCentralManager *centralManager;
@property (nonatomic, strong) CBPeripheral *peripheral;
@end

swift

class ComeClass: SomeSuperclass, CBCentralManagerDelegate {
var centralManager: CBCentralManager!
var peripheral: CBPeripheral

Initialize CBCentralManager.

objc

self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];

swift

centralManager = CBCentralManager(delegate: self, queue: nil)

Scan

Receive the update of central manager’s state. **Required**

objc

- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
NSLog(@”state:%ld”, (long)central.state);
}

swift

func centralManagerDidUpdateState(central: CBCentralManager) {
print(“state: \(central.state)”)
}

Start scanning.

objc

[self.centralManager scanForPeripheralsWithServices:nil options:nil];

swift

centralManager.scanForPeripheralsWithServices(nil, options: nil)

Receive the results of scan.

objc

- (void)   centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI
{
NSLog(@”peripheral:%@”, peripheral);
}

swift

func centralManager(central: CBCentralManager,
didDiscoverPeripheral peripheral: CBPeripheral,
advertisementData: [String : AnyObject],
RSSI: NSNumber!)
{
print(“peripheral: \(peripheral)”)
}

Stop scanning.

objc

[self.centralManager stopScan];

swift

centralManager.stopScan()

Connect

Start connecting.

objc

[self.centralManager connectPeripheral:peripheral options:nil];

swift

centralManager.connectPeripheral(peripheral, options: nil)

Receive the result of connecting.

objc

// Called when it succeeded
- (void) centralManager:(CBCentralManager *)central
didConnectPeripheral:(CBPeripheral *)peripheral
{
NSLog(@”connected!”);
}
// Called when it failed
- (void) centralManager:(CBCentralManager *)central
didFailToConnectPeripheral:(CBPeripheral *)peripheral
error:(NSError *)error
{
NSLog(@”failed…”);
}

swift

// Called when it succeeded
func centralManager(central: CBCentralManager,
didConnectPeripheral peripheral: CBPeripheral)
{
print(“connected!”)
}
// Called when it failed
func centralManager(central: CBCentralManager,
didFailToConnectPeripheral peripheral: CBPeripheral,
error: NSError?)
{
print(“failed…”)
}

Discover services & characteristics

Adopt CBPeripheralDelegate protocol.

objc

@interface SomeClass () <CBCentralManagerDelegate, CBPeripheralDelegate>

swift

class SomeClass: SomeSuperclass, CBCentralManagerDelegate, CBPeripheralDelegate {

Start discovering services.

objc

peripheral.delegate = self;
[peripheral discoverServices:nil];

swift

peripheral.delegate = self
peripheral.discoverServices(nil)

Receive the result of discovering services.

objc

- (void)     peripheral:(CBPeripheral *)peripheral
didDiscoverServices:(NSError *)error
{
if (error) {
NSLog(@”error: %@”, error);
return;
}

NSArray *services = peripheral.services;
NSLog(@”Found %lu services! :%@”, (unsigned long)services.count, services);
}

swift

func peripheral(peripheral: CBPeripheral, didDiscoverServices error: NSError?)
{
if let error = error {
print(“error: \(error)”)
return
}
let services = peripheral.services
print(“Found \(services.count) services! :\(services)”)
}

Start discovering characteristics.

objc

[peripheral discoverCharacteristics:nil forService:service];

swift

peripheral.discoverCharacteristics(nil, forService: service)

Receive the result of discovering characteristics.

objc

- (void)                      peripheral:(CBPeripheral *)peripheral
didDiscoverCharacteristicsForService:(CBService *)service
error:(NSError *)error
{
if (error) {
NSLog(@”error: %@”, error);
return;
}
NSArray *characteristics = service.characteristics;
NSLog(@”Found %lu characteristics!”, (unsigned long)characteristics.count);
}

swift

func peripheral(peripheral: CBPeripheral,
didDiscoverCharacteristicsForService service: CBService,
error: NSError?)
{
if let error = error {
print(“error: \(error)”)
return
}

let characteristics = service.characteristics
print(“Found \(characteristics.count) characteristics!)
}

Read

Start reading the value of a characteristic.

objc

[peripheral readValueForCharacteristic:characteristic];

swift

peripheral.readValueForCharacteristic(characteristic)

Receive the result of reading.

objc

- (void)                 peripheral:(CBPeripheral *)peripheral
didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic
error:(NSError *)error
{
if (error) {
NSLog(@”Failed… error: %@”, error);
return;
}

NSLog(@"characteristic uuid:%@, value%@”,
characteristic.UUID, characteristic.value);
}

swift

func peripheral(peripheral: CBPeripheral,
didUpdateValueForCharacteristic characteristic: CBCharacteristic,
error: NSError?)
{
if let error = error {
print(“Failed… error: \(error)”)
return
}

print(“characteristic uuid: \(characteristic.UUID), value: \(characteristic.value)”)
}

Write

Start writing the value of a characteristic.

objc

[peripheral writeValue:data
forCharacteristic:characteristic
type:CBCharacteristicWriteWithResponse];

swift

peripheral.writeValue(data, forCharacteristic: characteristic, type: CBCharacteristicWriteType.WithResponse)

Receive the result of writing.

objc

- (void)                peripheral:(CBPeripheral *)peripheral
didWriteValueForCharacteristic:(CBCharacteristic *)characteristic
error:(NSError *)error
{
if (error) {
NSLog(@"error:%@”, error);
return;
}

NSLog(@”Succeeded!”);
}

swift

func peripheral(peripheral: CBPeripheral,
didWriteValueForCharacteristic characteristic: CBCharacteristic,
error: NSError?)
{
if let error = error {
print(“error: \(error)”)
return
}

print(“Succeeded!”)
}

Notify

Start receiving notifications for changes of a characteristic’s value.

objc

[peripheral setNotifyValue:YES
forCharacteristic:characteristic];

swift

peripheral.setNotifyValue(true, forCharacteristic: characteristic)

Stop receiving notifications for changes of a characteristic’s value.

objc

[peripheral setNotifyValue:NO
forCharacteristic:characteristic];

swift

peripheral.setNotifyValue(false, forCharacteristic: characteristic)

Receive the result of starting/stopping to receive notification.

objc

- (void)                             peripheral:(CBPeripheral *)peripheral
didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic
error:(NSError *)error
{
if (error) {
NSLog(@"error:%@”, error);
}
else {
NSLog(@"isNotifying:%d”, characteristic.isNotifying);
}
}

swift

func peripheral(peripheral: CBPeripheral,
didUpdateNotificationStateForCharacteristic characteristic: CBCharacteristic,
error: NSError?)
{
if let error = error {
print(“error: \(error)”)
}
else {
print(“isNotifying: \(characteristic.isNotifying)”)
}
}

Receive notifications for changes of a characteristic’s value.

objc

- (void) peripheral:(CBPeripheral *)peripheral
didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic
error:(NSError *)error
{
if (error) {
NSLog(@"error:%@”, error);
return;
}

NSLog(@"characteristic UUID:%@, value:%@",
characteristic.UUID, characteristic.value);
}

swift

func peripheral(peripheral: CBPeripheral,
didUpdateValueForCharacteristic characteristic: CBCharacteristic,
error: NSError?)
{
if let error = error {
print(“error: \(error)”)
return
}

print(“characteristic UUID: \(characteristic.UUID), value: \(characteristic.value)”)
}

Peripheral Manager

Initialize

Adopt protocol and define properties.

objc

@interface SomeClass () <CBPeripheralManagerDelegate>
@property (nonatomic, strong) CBPeripheralManager *peripheralManager;
@end

swift

class SomeClass: SomeSuperclass, CBPeripheralManagerDelegate {
var peripheralManager: CBPeripheralManager!

Initialize CBPeripheralManager.

objc

self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];

swift

peripheralManager = CBPeripheralManager(delegate: self, queue: nil)

Advertise

Receive the update of peripheral manager’s state. **Required**

objc

- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral
{
NSLog(@”state:%ld”, (long)peripheral.state);
}

swift

func peripheralManagerDidUpdateState(peripheral: CBPeripheralManager)
{
print(“state: \(peripheral.state)”)
}

Start advertising.

objc

NSDictionary *advertisementData = @{CBAdvertisementDataLocalNameKey: @”Test Device”};
[self.peripheralManager startAdvertising:advertisementData];

swift

let advertisementData = [CBAdvertisementDataLocalNameKey: “Test Device”]
peripheralManager.startAdvertising(advertisementData)

Receive the result of starting to advertise.

objc

- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral
error:(NSError *)error
{
if (error) {
NSLog(@”Failed… error:%@”, error);
return;
}

NSLog(@”Succeeded!”);
}

swift

func peripheralManagerDidStartAdvertising(peripheral: CBPeripheralManager, error: NSError?)
{
if let error = error {
print(“Failed… error: \(error)”)
return
}
print(“Succeeded!”)
}

Stop advertising.

objc

[self.peripheralManager stopAdvertising];

swift

peripheralManager.stopAdvertising()

Add services

Create a service.

objc

CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID];
CBMutableService *service;
service = [[CBMutableService alloc] initWithType:serviceUUID
primary:YES];

swift

let serviceUUID = CBUUID(string: kServiceUUID)
let service = CBMutableService(type: serviceUUID, primary: true)

Create characteristics.

objc

CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID];CBCharacteristicProperties properties = (
CBCharacteristicPropertyNotify |
CBCharacteristicPropertyRead |
CBCharacteristicPropertyWrite
);
CBAttributePermissions permissions = (CBAttributePermissionsReadable | CBAttributePermissionsWriteable);CBMutableCharacteristic *c;
c = [[CBMutableCharacteristic alloc] initWithType:characteristicUUID
properties:properties
value:nil
permissions:permissions];

swift

let characteristicUUID = CBUUID(string: kCharacteristicUUID)
let properties: CBCharacteristicProperties = [.Notify, .Read, .Write]
let permissions: CBAttributePermissions = [.Readable, .Writeable]
let characteristic = CBMutableCharacteristic(
type: characteristicUUID,
properties: properties,
value: nil,
permissions: permissions)

Add characteristics to a service.

objc

service.characteristics = @[characteristic1, characteristic2];

swift

service.characteristics = [characteristic1, characteristic2]

Add a service to the peripheral manager.

objc

[self.peripheralManager addService:service];

swift

peripheralManager.addService(service)

Receive the result of adding a service.

objc

- (void)peripheralManager:(CBPeripheralManager *)peripheral
didAddService:(CBService *)service
error:(NSError *)error
{
if (error) {
NSLog(@"error:%@”, error);
return;
}

NSLog(@"service:%@”, service);
}

swift

func peripheralManager(peripheral: CBPeripheralManager, didAddService service: CBService, error: NSError?)
{
if let error = error {
print(“error: \(error)”)
return
}

print(“service: \(service)”)
}

Respond to Read requests

objc

- (void)peripheralManager:(CBPeripheralManager *)peripheral
didReceiveReadRequest:(CBATTRequest *)request
{
if ([request.characteristic.UUID isEqual:self.characteristic.UUID])
{
// Set the characteristic's value to the request
request.value = self.characteristic.value;

// Respond to the request
[self.peripheralManager respondToRequest:request
withResult:CBATTErrorSuccess];
}
}

swift

func peripheralManager(peripheral: CBPeripheralManager, didReceiveReadRequest request: CBATTRequest)
{
if request.characteristic.UUID.isEqual(characteristic.UUID)
{
// Set the correspondent characteristic's value
// to the request
request.value = characteristic.value

// Respond to the request
peripheralManager.respondToRequest(
request,
withResult: .Success)
}
}

Respond to Write requests

objc

- (void)  peripheralManager:(CBPeripheralManager *)peripheral
didReceiveWriteRequests:(NSArray *)requests
{
for (CBATTRequest *aRequest in requests)
{
if ([aRequest.characteristic.UUID isEqual:self.characteristic.UUID])
{
// Set the request's value
// to the correspondent characteristic
self.characteristic.value = aRequest.value;
}
}

[self.peripheralManager respondToRequest:requests[0]
withResult:CBATTErrorSuccess];
}

swift

func peripheralManager(peripheral: CBPeripheralManager, didReceiveWriteRequests requests: [CBATTRequest])
{
for request in requests
{
if request.characteristic.UUID.isEqual(characteristic.UUID)
{
// Set the request's value
// to the correspondent characteristic
characteristic.value = request.value
}
}
peripheralManager.respondToRequest(requests[0], withResult: .Success)
}

Respond to Notifications/Indications

Receive subscribe requests.

objc

- (void)       peripheralManager:(CBPeripheralManager *)peripheral
central:(CBCentral *)central
didSubscribeToCharacteristic:(CBCharacteristic *)characteristic
{
NSLog(@"subscribed centrals: %@”, self.characteristic.subscribedCentrals);
}

swift

func peripheralManager(
peripheral: CBPeripheralManager,
central: CBCentral,
didSubscribeToCharacteristic characteristic: CBCharacteristic)
{
print(“subscribed centrals: \( characteristic.subscribedCentrals)”)
}

Receive unsubscribe requests.

objc

- (void)         peripheralManager:(CBPeripheralManager *)peripheral
central:(CBCentral *)central
didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic
{
NSLog(@"subscribed centrals: %@”,
self.characteristic.subscribedCentrals);
}

swift

func peripheralManager(
peripheral: CBPeripheralManager,
central: CBCentral,
didUnsubscribeFromCharacteristic characteristic: CBCharacteristic)
{
print(“subscribed centrals: \(characteristic.subscribedCentrals)”)
}

Notify/Indicate updating a value

objc

self.characteristic.value = data;[self.peripheralManager updateValue:data
forCharacteristic:self.characteristic
onSubscribedCentrals:nil];

swift

characteristic.value = dataperipheralManager.updateValue(
data,
forCharacteristic: characteristic,
onSubscribedCentrals: nil)

About me

iOS Freelancer in Tokyo, Japan / Berlin, Germany. Works from abroad are welcome.

My Profile Summary (Including contact information)

--

--

Tsutsumi Shuichi

Freelance iOS Engineer. Author of “iOSxBLE Core Bluetooth Programming”, “Metal入門”, etc. Creator of iOS Sampler series. http://github.com/shu223