Get List Of BLE Devices Using CoreBluetooth

This post will show you just the minimum effort needed to get a list of BLE (Bluetooth 4.0) devices that are advertising on your iOS device. Make sure you have an iOS device with BLE and another device that is capable of advertising its BLE services ( I am using an RFDuino, with it's device name set to Display).

Let's get started.

  • Create a new single view Swift project.

  • Add a UITableView to the ViewController in the pre-made Storyboard.

  • Add a UITableviewCell to the tableview with identifier "cell".

  • Attach the datasource and delegate from the UITableView to the ViewController in the Storyboard.

  • Add an IBOutlet for the UITableView in your ViewController class.

  • Make sure the class for the ViewController is set to the class ViewController.

Add the CoreBluetooth framework to your project.

Now make your ViewController Swift file look like this:

import CoreBluetooth
import UIKit

class ViewController: UIViewController {
    var centralManager: CBCentralManager?
    var peripherals = Array<CBPeripheral>()
    
    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Initialise CoreBluetooth Central Manager
        centralManager = CBCentralManager(delegate: self, queue: DispatchQueue.main)
    }
}

extension ViewController: CBCentralManagerDelegate {
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if (central.state == .poweredOn){
            self.centralManager?.scanForPeripherals(withServices: nil, options: nil)
        }
        else {
            // do something like alert the user that ble is not on
        }
    }
    
    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
        peripherals.append(peripheral)
        tableView.reloadData()
    }
}

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell:UITableViewCell = self.tableView.dequeueReusableCell(withIdentifier: \"cell\")! as UITableViewCell
                                                                      
                                                                      let peripheral = peripherals[indexPath.row]
                                                                      cell.textLabel?.text = peripheral.name
                                                                      
                                                                      return cell
                                                                      }
                                                                      
                                                                      func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return peripherals.count
        }
                                                                      }

centralManagerDidUpdateState will be called whenever the CoreBluetooth BLE service state changes. For this example I am only checking if the state == .poweredOn but there are other states you can check for such as off, unknown and resetting. When the state is on we initiate a device scan using scanForPeripheralsWithServices.

If the service finds a device the delegate method didDiscoverPeripheral is called. In this method we just get the newly discovered peripheral and add it to our array of peripherals. We then call reloadData on the tableView so that the new object in the array is used in our tableView. I have only used the name property from the peripheral but there is loads more stuff to play with.

When you turn on your BLE device you should see something like the following: