Get List Of BLE Devices Using CoreBluetooth – (Archive)

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:

27 thoughts on “Get List Of BLE Devices Using CoreBluetooth – (Archive)”

    1. There is a delegate method for CBPeripheralDelegate that you can use on your discovered peripheral, alternatively you will see an RSSI parameter in the didDiscoverPeripheral delegate method.

  1. I get the error, Binary operator ‘==’ cannot be applied to operands of type ‘CBManagerState’ and ‘CBCentralManagerState’, at the line, if (central.state == CBCentralManagerState.PoweredOn). Any idea?

    1. Change “CBCentralManagerState.PoweredOn” to “CBManagerState.PoweredOn”. Apparently the former was deprecated in iOS 10.

  2. //CoreBluetooth methods
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
    switch (central.state) {
    case .poweredOff:
    break

    case .unauthorized:
    // Indicate to user that the iOS device does not support BLE.
    break

    case .unknown:
    // Wait for another event
    break

    case .poweredOn:
    self.centralManager?.scanForPeripherals(withServices: nil, options: nil)

    case .resetting:
    break

    case .unsupported:
    break
    }
    }

  3. I get problems with dequeueReusableCell returning nil and thus the optional unwrapping failing. It may be worth mentioning that you need to add a cell with identifier “cell” to the Table View in the storyboard

  4. Hello and thank you very much for your project,

    I tested it with my iPhone to find my Raspberry Pi Zero W having BLE, but it did not find it, I wanted to ask you why can’t do it ? , maybe you have an explanation to help me?

    1. As per the code, the phone should not be paired with the device??? Go to Bluetooth options in phone settings and click on “Forget this device” for the device you are trying to connect and try running again.

  5. Pingback: Jump In – xaboh17, andec17, madan17 | | Civilingeniør i Lærings- og Oplevelsesteknologi

  6. Pingback: Bluetooth | Bluetooth low energy | Swift - Rigorous | Fascinating | Spectacular

  7. Just wanted to take a moment and thank you for posting this and the code sample at GitHub. The code is github has a very nice interface too. Now hopefully, I’ll be able to extend that code to do what I am trying to do — just trying to get a basic BLE to Arduino working so that I can send bytes from iOS device to Arduino. I’m able to do this easily with my Android apps but have found it a bit more difficult to do on iOS / Swift (but that’s just because I’m not as experienced in iOS dev). Thanks again.

  8. Pingback: Bluetooth | Bluetooth low energy | Swift - The Expert Software Development And Training Company - +91-7838552946 +91-9711874933

Comments are closed.