Download project from Github

To best visualize how things work, I recommend that you should follow along with the app provided in this guide. The Basic Chat app sends and receives data using the Feather Bluefruit's UART connection. You can learn more about UARTs here.

Go to the download page for the project. Once on the page, click on the "Clone or download" button.

Once the file is downloaded, click on the Basic Chat MVC.xcodeproj app and it will open up the project in Xcode.

Once we have the project open, select your iOS device's scheme in Xcode.

Now just press the Run button to test the app on your iOS device.

If all goes well, the Basic Chat MVC app will run on your iOS device and you'll be able to use the app as a reference while you explore the guide.

Make sure your Bluetooth is enabled while using Basic Chat

Understanding Core Bluetooth

The Core Bluetooth framework provides the classes needed for your apps to communicate with Bluetooth-equipped low energy (LE) and Basic Rate / Enhanced Data Rate (BR/EDR) wireless technology.

We need the CBCentralManager object that scans for, discovers, connects to, and manages peripherals. We'll also need the CBPeripheral object that represents remote peripheral devices that your app discovers with a central manager.

A CBPeripheral is used to discover, explore, and interact with the services available on a remote peripheral that supports Bluetooth low energy.

A service encapsulates the way part of the device behaves. For example, one service of a heart rate monitor may be to expose heart rate data from a sensor.

Services themselves contain of characteristics or included services (references to other services).

Characteristics provide further details about a peripheral’s service. For example, the heart rate service may contain multiple characteristics.

The following diagram shows the hierarchy of the CBPeripheral:

Getting Started

Before starting to code, you need to create a prompt that asks for permission to use the device's Bluetooth. 

In your file hierarchy on the left, locate Info.plist.

Add these to your info.plist:

• Privacy - Bluetooth Peripheral Usage Description

• Privacy - Bluetooth Always Usage Description

Add a description you see fit.

In this case, a message tells the user why the app is requesting the ability to connect to Bluetooth peripherals. 

Now, to look at some code.

In your project's file hierarchy, locate "ViewController.swift". This file handles the majority of the tasks which need to be performed to connect to a Bluetooth device.

At the top of the file, import CoreBluetooth:

import CoreBluetooth

This line adds Core Bluetooth framework to the project and gives the ability to communicate with Bluetooth devices.

Now create variable to store your central manager. The central manager manages discovered or connected remote peripheral devices (represented by CBPeripheral objects), including scanning for, discovering, and connecting to advertising peripherals.

var centralManager: CBCentralManager!

Then in your viewDidLoad, initialize the central manager by setting the delegate to self, otherwise the central state never changes on startup.

override func viewDidLoad() {
   super.viewDidLoad()
   centralManager = CBCentralManager(delegate: self, queue: nil)
 }

Now add a CBCentralManagerDelegate protocol to the ViewController in order to scan, discover and connect a peripheral.

The CBCentralManagerDelegate protocol defines the methods that a delegate of a CBCentralManager object must adopt.

extension ViewController: CBCentralManagerDelegate {

  func centralManagerDidUpdateState(_ central: CBCentralManager) {
    
     switch central.state {
          case .poweredOff:
              print("Is Powered Off.")
          case .poweredOn:
              print("Is Powered On.")
              startScanning()
          case .unsupported:
              print("Is Unsupported.")
          case .unauthorized:
          print("Is Unauthorized.")
          case .unknown:
              print("Unknown")
          case .resetting:
              print("Resetting")
          @unknown default:
            print("Error")
          }
  }

}

The only method required for CBCentralManagerDelegate would be centralManagerDidUpdateState(_:); the central manager calls this when its state updates, thereby indicating the availability of the central manager.

This required method is added to ensure that the central device (your iPhone or iPad) supports Bluetooth low energy and that it’s available to use. 

Also add a CBPeripheralDelegate protocol. The CBPeripheralDelegate provides updates on the use of a peripheral’s services. This will be needed later.

extension ViewController: CBPeripheralDelegate {
}

Before going any farther, you need to store a list of unique identifiers to help look for specific Bluetooth devices. Create a new file called CBUUIDs that stores the unique identifiers.

import Foundation
import CoreBluetooth

struct CBUUIDs{

    static let kBLEService_UUID = "6e400001-b5a3-f393-e0a9-e50e24dcca9e"
    static let kBLE_Characteristic_uuid_Tx = "6e400002-b5a3-f393-e0a9-e50e24dcca9e"
    static let kBLE_Characteristic_uuid_Rx = "6e400003-b5a3-f393-e0a9-e50e24dcca9e"

    static let BLEService_UUID = CBUUID(string: kBLEService_UUID)
    static let BLE_Characteristic_uuid_Tx = CBUUID(string: kBLE_Characteristic_uuid_Tx)//(Property = Write without response)
    static let BLE_Characteristic_uuid_Rx = CBUUID(string: kBLE_Characteristic_uuid_Rx)// (Property = Read/Notify)

}

CBUUID class represents universally unique identifiers (UUIDs) of attributes used in Bluetooth low energy communication, such as a peripheral’s services, characteristics, and descriptors.

By specifying what service to looking for, you tell the CBCentralManager to ignore all peripherals which don't advertise that specific service, and return a list of only the peripherals that offer this service.

Now to head back into the ViewController to start scanning for peripherals.

This guide was first published on Jul 27, 2017. It was last updated on 2021-02-23 12:51:57 -0500.

This page (Code) was last updated on Oct 15, 2021.

Text editor powered by tinymce.