When you connect to the Bluetooth Central Manager (CM) and start scanning for a device that has particular services, the CM will let you know when it finds a device.
func centralManager(
central: CBCentralManager,
didDiscoverPeripheral peripheral: CBPeripheral,
advertisementData: [String : AnyObject],
RSSI: NSNumber)
However, there’s no corresponding “didUndiscoverPeripheral” type of function. In the case of my app, I needed to show an instruction screen, detect when the device was turned on (discovered), show a list of discovered devices and let the user select it. If the device timed out or was turned off(stops broadcasting advertisement Date), I needed to remove the device from the discovered device list.
It will be better if you can explain it with a working example.
Set the CBCentralManagerScanOptionAllowDuplicatesKey to true before the scan starts so that the didDiscover peripheral callBack method will execute every time when an advertisement packet is received.
create a dictionary and a timer to keep track of the discovered device list. The key of the dictionary is peripheral identifier and value is counter initially set to 5 when the peripheral is discovered first time after that when an advertisement packet from the peripheral is received we keep on updating the counter value to 5 in didDiscover peripheral callback method.
var discoveredPeripherals : [String: Int] = [String: Int]()
var discoveryTimer : Timer = Timer()
ScheduledTimer when scan is starts :
discoveryTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateDiscoveredDevices), userInfo: nil, repeats: true)
stop the timer when scan stops.
discoveryTimer.invalidate()
if the device stops advertisement and it is not connected then remove the device after 5 sec from the discovered device list.
@objc func updateDiscoveredDevices() {
peripherals.forEach{
if discoveredPeripherals.index(forKey: $0.identifier.uuidString) != nil
{
if discoveredPeripherals[$0.identifier.uuidString]! != 0
{
discoveredPeripherals[$0.bleDeviceGetId()]! -= 1
}
else{
if $0.state != CBPeripheralState.connected
{
removeDevice($0)
}
}
}
}
}
Thanks to @Paulw11 for suggesting this approach.