I want to detect and capture how far a beacon is from my device. I find my Beacon using CBCentralManager, but when I use CLLocation to capture the metrics, in my LocationManager function I can't find my beacon. The beacon parameter is empty.
CoreBluetoothTest
import SwiftUI
import CoreBluetooth
class CoreBluetoothTest: NSObject, ObservableObject {
private var centralManager: CBCentralManager?
private var peripherals: [CBPeripheral] = []
@Published var peripheralsNames: [String] = []
private var devideCount: Int = 0
private var beaconDetector = BeaconDetector()
override init() {
super.init()
self.centralManager = CBCentralManager(delegate: self, queue: .main)
}
}
extension CoreBluetoothTest: CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == .poweredOn {
self.centralManager?.scanForPeripherals(withServices: nil)
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData data: [String : Any], rssi RSSI: NSNumber) {
if !peripherals.contains(peripheral) {
devideCount += 1
self.peripherals.append(peripheral)
print("Device número \(devideCount): \(peripheral.identifier), RSSI: \(RSSI)")
//let nearbyInteraction = NearbyInteractionTest()
//nearbyInteraction.startupMPC(identifier: peripheral.identifier.uuidString)
central.connect(peripheral)
print("Efetuando conexão \(peripheral.state)")
// 3 = Desconectando, 2 = Conectado, 1 = conectando, 0 = Desconectado
if peripheral.name == nil {
self.peripheralsNames.append("\(peripheral.identifier.description) RSSI: \(RSSI)")
} else {
self.peripheralsNames.append(peripheral.name ?? "Dispositivo sem nome")
}
}
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
print("Omg! conexão falhada com: \(peripheral.identifier), Status: \(peripheral.state)")
// 3 = Desconectando
print("Error: \(error)")
central.connect(peripheral)
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
print("Conexão realizada com sucesso com: \(peripheral.identifier)")
beaconDetector.startScanning(myID: peripheral.identifier)
}
}
BeaconDetector
import Combine
import Foundation
import CoreLocation
extension BeaconDetector: CLLocationManagerDelegate{
}
class BeaconDetector: CLLocationManager, ObservableObject {
var didChange = PassthroughSubject<Void, Never>()
var locationManager: CLLocationManager?
var lastDistance = CLProximity.unknown
override init() {
super.init()
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.requestWhenInUseAuthorization()
}
func locationManager(manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus)
{
if status == .authorizedWhenInUse {
if CLLocationManager.isMonitoringAvailable(for:
CLBeaconRegion.self) {
if CLLocationManager.isRangingAvailable() {
// we are ready to go
}
}
}
}
func startScanning(myID: UUID) {
let constraint = CLBeaconIdentityConstraint(uuid: myID, major: 1, minor: 50000)
let beaconRegion = CLBeaconRegion(beaconIdentityConstraint: constraint, identifier: "MyBeacon")
locationManager?.startMonitoring(for: beaconRegion)
locationManager?.startRangingBeacons(satisfying: constraint)
print("Regioes \(locationManager?.monitoredRegions)")
print("RangedBeaconConstraints \(locationManager?.rangedBeaconConstraints)")
}
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion)
{
}
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion)
{
}
func locationManager(_ manager: CLLocationManager, monitoringDidFailFor region: CLRegion?,
withError error: Error)
{
}
func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon],
in region: CLBeaconRegion
) {
if let beacon = beacons.first {
print("Encontrou Beacon")
update(distance: beacon.proximity)
} else {
print("Não localizou o beacon")
}
}
}
Logs: