从 Firebase 检测带有 UUID 的 iBeacons

Posted

技术标签:

【中文标题】从 Firebase 检测带有 UUID 的 iBeacons【英文标题】:Detecting iBeacons with UUID from Firebase 【发布时间】:2020-05-11 19:52:03 【问题描述】:

我正在尝试从我的 Firebase 数据库中接收所有 UUID。使用这些 UUID,我想搜索这些 UUID 是否在设备附近。下面是我为实现这一目标而编写的代码。每当我运行我的程序时,它只会检测某些 UUID,而不是所有 UUID。有人可以帮我弄清楚为什么会这样吗?

提前致谢!!

编辑:我想一个接一个地不断检查信标

我的 JSON 数据库文件


  "UUID" : 
    "Cool Cool" : "E99B856D-2F8A-49F0-A583-E675A86F33BE",
    "Sabad's Ipad" : "44837477-B489-4BC7-83A6-D001D7FE0BD0",
    "Sweta" : "7D0D9B66-0554-4CCF-A6E4-ADE12325C4F0",
    "User 2" : "6D340D8D-005B-4610-A4FA-AA8D9437B8A8"
  ,
  "User Detected" : 
    "Sabad's Ipad" : 
      "Co-ordinates" : "Latitude: 25.089279174804688   Longitude:55.17439565327509",
      "DateTime" : "2020-05-11 17:52:13 +0000",
      "UUID" : "A0719C85-E00B-4961-B9D0-7FCADD4ABA21"
    
  

我的 ViewController.swift

import Firebase

import UIKit
import CoreLocation
import CoreBluetooth

//Initialise View Controller

class ViewController: UIViewController, CLLocationManagerDelegate, CBPeripheralManagerDelegate


@IBOutlet weak var distanceReading: UILabel!
var locationManager:CLLocationManager?

var currentDateTime : Date = Date()
var currentDateTime2 : Date = Date()
var uuid = UUID()

let ref = Database.database().reference()

var dataArray = [String]()

var latitude = CLLocationDegrees(0)
var longitude = CLLocationDegrees(0)


override func viewDidLoad() 
    super.viewDidLoad()

    locationManager = CLLocationManager()
    locationManager?.delegate = self
    locationManager?.requestAlwaysAuthorization()

    view.backgroundColor = .gray

    uuid = UUID()

    let name = UIDevice.current.name
    ref.child("UUID/\(name)").setValue("\(String(describing: uuid))")

    if CLLocationManager.locationServicesEnabled() 
        locationManager?.delegate = self
        locationManager?.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
        locationManager?.startUpdatingLocation()
    


//MARK: Detect iBeacon

func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) 
    guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else  return 
    latitude = (locValue.latitude)
    longitude = (locValue.longitude)

    if status == .authorizedAlways 
        if CLLocationManager.isMonitoringAvailable(for: CLBeaconRegion.self)
            if CLLocationManager.isRangingAvailable() 
                 startScanning()
            
        
    


func startScanning()
    ref.child("UUID").observe(.childAdded)  (snapshot) in
//        ref.child("UUID").observeSingleEvent(of: .childAdded)  (snapshot)
            let data = snapshot.value as? String
            if let actualPost = data
            self.dataArray.append(actualPost)
//          print(self.dataArray)
            _ = self.dataArray.count
//          print(dataCount)
//          for i in 0..<(dataCount)
            for i2 in self.dataArray
//              print(i2)
//                print("Next")
                let beaconRegion = CLBeaconRegion(uuid : UUID(uuidString: i2)! , major: 123, minor: 789, identifier: "MyBeaconDetector")
//                print(beaconRegion)
                self.locationManager?.startMonitoring(for: beaconRegion)
                self.locationManager?.startRangingBeacons(satisfying: beaconRegion.beaconIdentityConstraint)
            
        
    
 

  func update(distance:CLProximity)
  UIView.animate(withDuration: 0.01 ) 
      switch distance
          case .immediate:
              self.view.backgroundColor = .blue
              self.distanceReading.text = "Right Here"
              self.currentDateTime = Date()
              print(self.currentDateTime)

          case .near:
              self.view.backgroundColor = .orange
              self.distanceReading.text = "Near"
              self.currentDateTime2 = Date()
              print(self.currentDateTime2)

          case .far:
              self.view.backgroundColor = .red
              self.distanceReading.text = "Far"

          default:
              self.view.backgroundColor = .gray
              self.distanceReading.text = "UNKNOWN"
      
  

  

    func locationManager(_ manager: CLLocationManager, didRange beacons : [CLBeacon], satisfying beaconConstraint: CLBeaconIdentityConstraint) 
    let dataCount = UInt32(beacons.count)
//    print(dataCount)
    print(beaconConstraint)
//    print(dataCount)
        for i in 0...10000
            if let beacon = beacons.randomElement() 
            print(beacon)
            update(distance: beacon.proximity)
            let name = UIDevice.current.name
            self.ref.child("User Detected/\(name)/DateTime").setValue("\(self.currentDateTime)")
            self.ref.child("User Detected/\(name)/UUID").setValue("\(String(describing: self.uuid))")
            self.ref.child("User Detected/\(name)/DateTime").setValue("\(self.currentDateTime)")
            self.ref.child("User Detected/\(name)/Co-ordinates").setValue("Latitude: \(self.latitude)   Longitude:\(self.longitude)")
            continue

           else
//            print("Check")
            update(distance: .unknown)
          
       
    

【问题讨论】:

请注意,您可以同时扫描的信标区域数量相对较少。您最好为每台设备使用相同的 uuid,并简单地为每台设备分配一个独特的主要和次要组合。 是的,但我不想同时搜索它们,而是尝试检查它们是否一个接一个。 【参考方案1】:

问题出在这几行代码中:

            for i2 in self.dataArray
                let beaconRegion = CLBeaconRegion(uuid : UUID(uuidString: i2)!,
                                                  major: 123, minor: 789, 
                                                  identifier: "MyBeaconDetector")
                self.locationManager?.startMonitoring(for: beaconRegion)
                self.locationManager?.startRangingBeacons(satisfying: beaconRegion.beaconIdentityConstraint)

问题是您正在为循环中构造的每个区域重复使用identifier 字段。该字符串应该是唯一的。所以你最终要做的是覆盖你之前注册的测距/监控区域。

要解决此问题,请像这样使每个区域的 identifier 唯一:

            for i2 in self.dataArray
                let uniqueIdentifier = i2 // adjust as needed to make this unique
                let beaconRegion = CLBeaconRegion(uuid : UUID(uuidString: i2)!,
                                                  major: 123, minor: 789, 
                                                  identifier: uniqueIdentifier)
                self.locationManager?.startMonitoring(for: beaconRegion)
                self.locationManager?.startRangingBeacons(satisfying: beaconRegion.beaconIdentityConstraint)

【讨论】:

我这样做并使用了一个函数来创建一个函数,该函数创建随机字符串并将其分配给我在 CLBeaconRegion 中的标识符属性,但它仍然只检测到来自 Firebase 的 1 或 2 个 UUID

以上是关于从 Firebase 检测带有 UUID 的 iBeacons的主要内容,如果未能解决你的问题,请参考以下文章

Firebase Crashlytics 为 UUID 上传丢失的 dSYMs 文件

使用firebase时如何检测设备连接状态? [复制]

使用 useEffect 与 onAuthStateChanged 检测 Firebase 用户更改 - 有啥区别?

从 firebase 检测值并从 superView 中删除(如果为真)

检测到并上传了Firebase / Crashlytics事件,但不可见

由于带有 sequelize.js 的 UUID 外键,尝试将行插入表时出错