swift scan for all bluetooth devices

I do that but issue is that I can saw only iOS MacBook on list.
I didn’t add any filter to search this but I can’t find the android phone and Bluetooth speaker in list.
So any one know about this please help me out.?
MacBook is not iOS. Do you see, other iOS devices ?
AFAIK, only BLE devices can be discovered using public API (non public API are forbidden on the Appstore). Is your other device BLE ?

Did you use
Code Block
optional func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber)

Could you show your code ?
import UIKit
import CoreBluetooth

class ViewController: UIViewController {

  @IBOutlet weak var tblOfList: UITableView!
  @IBOutlet weak var btnOfScan: UIButton!
   
  var peripherals:[CBPeripheral] = []
  var centralManager: CBCentralManager!

   
  override func viewDidLoad() {
    super.viewDidLoad()
     
    self.tblOfList.tableFooterView = UIView()
    centralManager = CBCentralManager(delegate: self, queue: .main)
     
  }
   
  @IBAction func btnScanClick( sender: Any) {
    print("scan Start")
    //let options: [String: Any] = [CBCentralManagerScanOptionAllowDuplicatesKey:NSNumber(value: false)]
    centralManager?.scanForPeripherals(withServices: nil, options: nil)
    DispatchQueue.main.asyncAfter(deadline: .now() + 60.0) {
      self.centralManager.stopScan()
      print("Scanning stop")
    }
  }
}
extension ViewController : UITableViewDelegate,UITableViewDataSource {
  func tableView(
tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return peripherals.count
  }
   
  func tableView( tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = self.tblOfList.dequeueReusableCell(withIdentifier: "listCell", for: indexPath) as! listCell
    let peripheral = peripherals[indexPath.row]
    cell.lblOfDeviceName?.text = peripheral.name
    return cell
  }
  func tableView(
tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let peripheral = peripherals[indexPath.row]
    print("Details : ", peripheral)
  }
}
extension ViewController : CBPeripheralDelegate, CBCentralManagerDelegate{
  func centralManager( central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
    self.peripherals.append(peripheral)
    print("Discovered \(peripheral.name ?? "")")
    self.tblOfList.reloadData()
  }
  func centralManagerDidUpdateState(
central: CBCentralManager) {
    switch central.state {
     case .unknown:
      print("central.state is .unknown")
     case .resetting:
      print("central.state is .resetting")
     case .unsupported:
      print("central.state is .unsupported")
     case .unauthorized:
      print("central.state is .unauthorized")
     case .poweredOff:
      print("central.state is .poweredOff")
     case .poweredOn:
      print("central.state is .poweredOn")
    @unknown default:
      fatalError()
    }
  }
  func centralManager( central: CBCentralManager, didConnect peripheral: CBPeripheral) {
    print("Connected to "+peripheral.name!)
  }

  func centralManager(
central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
    print(error!)
  }
}
@Claude31  Please check the code in comment.
Have you checked if your Android devices support BLE ?

Could you test with a second iOS or MacOS device to discover, to see if you see 2 of them ?

Or turn off Apple device BlueTooth to see if Android appears.
I did not find issue after quick check of your code.

Did you try to set
Code Block
withServices = [CBUUIDCharacteristicExtendedPropertiesString]

as recommended in doc (scanForPeripherals(withServices:options:))

The recommended practice is to populate the serviceUUIDs parameter rather than leaving it nil.

Have also a look at this thread, which may give you additional information.
Thanks for your Ans I'm able to find the bluetooth device now, but problem is now getting only one device in the list.
there are 4 device around but I can saw only one.

currently i'm using this to find the bluetooth devices


let options: [String: Any] = [CBCentralManagerScanOptionAllowDuplicatesKey:NSNumber(value: false)]
centralManager?.scanForPeripherals(withServices: nil, options: options)
  • -

Can you confirm:
  • you have 4 devices,

  • you can see each if it is the only up or visible

  • but if several are on you see only one in the list.

Is that this ?

Did you try to set the service as well ?

Just for testing, could you comment out the following:
Code Block
DispatchQueue.main.asyncAfter(deadline: .now() + 60.0) {
self.centralManager.stopScan()
print("Scanning stop")
}

and add
Code Block
peripherals = []

at the beginning of btnScanClick scan function.
You could also try to create a button to stop scan manually and call tableView reload there.

@Claude31,
Hey thanks for your response, Actually I have the same question related to this.
  1. Can we search the BLE devices when my app in background mode.

  2. Can we search the BLE devices when our app is Inactive mode,

I searched lot regarding this but not get a proper solutions on this.

Do you see now all the devices in the list ?
You'll find the answer here: https://stackoverflow.com/questions/57904096/how-to-scan-ble-devices-in-background


Apps that have specified the bluetooth-central background mode are allowed to scan while in the background. That said, they must explicitly scan for one or more services by specifying them in the serviceUUIDs parameter. The CBCentralManager scan option is ignored while scanning in the background.

For background scanning to work you need to specify serviceUUIDs.
Thanks for your the Answer,

I tried this link but not working.

https://stackoverflow.com/questions/57904096/how-to-scan-ble-devices-in-background

Do you know some steps to achieve this, so I can follow and make it working.

Please correct me If I'm wrong,

Its possible to just search the new devices when app inactive mode..
That's what I understand.
  • when inactive, you can search only for devices already found, using the UUID

  • when inactive, you cannot discover new devices

Thanks for your Ans.
  1. when inactive, you can search only for devices already found, using the UUID

>> Actually I'm not connecting any device just searching the device and find the distance.
So, can we do that without connecting the device can we just search the device.

2. when inactive, you cannot discover new devices
>> Completely Agree with you, Do you have any document from apple, where they mention this.

I check this link :link
They mention here we can do this by using the some Restore delegate method, but I'm not able to do that.
And not able to find where they mention we can only do this if we already connected to that devices in past.

And finally, I just want to know that, Can we search the BLE / Bluetooth devices when app is inactive mode.








This document is interesting, provides some context.

https :// medium.com/ @cbartel/ios-scan-and-connect-to-a-ble-peripheral-in-the-background-731f960d520d
@Claude31

Thanks for your help now I'm able to search the app in background state but now problem is that.
  • I want search the bluetooth devices when app is Inactive state.

  • We can do this by using the 'willRestoreState' function but don't know how to implement that.

  • And didn't get any proper document on this.

So please can you help me on this.
swift scan for all bluetooth devices
 
 
Q