SWIFT:CoreLocation - 使用 CLBeaconIdentityConstraint 测距信标不会测距多个信标

2023-11-29

因此,我们在 Swift for iOS 13 中开发时遇到了一个问题。当我们使用较新的方法来测距信标“startRangingBeacons(satisfying: CLBeaconIdentityConstraint )”时,它只会测距最近添加的信标,因此如果有多个信标, 我们出现了问题。当我们使用旧方法“startRangingBeacons(in:region)”(现已弃用但在 iOS 13 中仍然有效)时,应用程序按预期工作。

详细信息(使用带有“约束”的新方法):

  1. 应用程序开始监控2个Beacon区域
  2. 如果用户进入 BeaconRegion,则启动测距信标
  3. 打开Beacon 1,应用程序开始测距Beacon 1
  4. 打开Beacon2,应用程序开始测距Beacon2,但不测距beacon1。 (注意 - 两个信标区域重叠,旧方法可以处理此问题)

当使用startRangingBeacons(in:region)对信标进行测距时,应用程序能够对两个信标进行测距。

当最新的远程信标关闭时,didRangeBeacons 事件会被触发,并且 CLBeacon 列表为空,该列表中应该仍然有另一个信标,但事实并非如此。

这是不起作用的代码:

    func locationManager(_ manager: CLLocationManager, didRange beacons: [CLBeacon], satisfying beaconConstraint: CLBeaconIdentityConstraint) {

     for beacon in beacons {
         if [.near, .immediate].contains(beacon.proximity){
             if let index = beaconsInProximity.firstIndex(of: beacon) {
                 beaconsInProximity.remove(at: index)
             }
             beaconsInProximity.append(beacon)
             if beaconsInProximity.count > 1 { beaconsInProximity = beaconsInProximity.sorted(by: {$0.accuracy < $1.accuracy})}
             if nearestBeacon == nil || !nearestBeacon!.isEqual(beaconsInProximity[0]) {
                 if(nearestBeacon != nil) {
                     notifyUser(isExiting: true, isBeacon = true)
                 }
                 nearestBeacon = beaconsInProximity[0]
                 displayOrSendNotification()
             }

         } else if let index = beaconsInProximity.firstIndex(of: beacon){
             if(beaconsInProximity.count > 1) {
                 beaconsInProximity.remove(at: index)
                 if nearestBeacon != nil && nearestBeacon!.isEqual(beacon) {
                     notifyUser(isExiting: true, isBeacon = true)
                     nearestBeacon = beaconsInProximity.count > 0 ? beaconsInProximity[0] : nil
                     displayOrSendNotification()
                 }
             }
         }
    }
}

这是有效的代码:

    func locationManager(_ manager: CLLocationManager,
                     didRangeBeacons beacons: [CLBeacon],
                     in region: CLBeaconRegion) {
    print("Did range beacons")

    for beacon in beacons {
        if [.near, .immediate].contains(beacon.proximity){
            if let index = beaconsInProximity.firstIndex(of: beacon) {
                beaconsInProximity.remove(at: index)
            }
            beaconsInProximity.append(beacon)
            if beaconsInProximity.count > 1 { beaconsInProximity = beaconsInProximity.sorted(by: {$0.accuracy < $1.accuracy})}
            if nearestBeacon == nil || !nearestBeacon!.isEqual(beaconsInProximity[0]) {
                if(nearestBeacon != nil) {
                    displayOrSendNotification(isExiting: true, isBeacon: true)
                }
                nearestBeacon = beaconsInProximity[0]
                displayOrSendNotification(isExiting: false, isBeacon: true)
            }

        } else if let index = beaconsInProximity.firstIndex(of: beacon){
            if(beaconsInProximity.count > 1) {
                beaconsInProximity.remove(at: index)
                if nearestBeacon != nil && nearestBeacon!.isEqual(beacon) {
                    nearestBeacon = beaconsInProximity.count > 0 ? beaconsInProximity[0] : nil
                    displayOrSendNotification(isExiting: false, isBeacon: true)
                }
            }
        }
    }
}

创建信标进行监控:

var regionsToMonitor = [
        BeaconData(uuid: UUID(uuidString: "82eee62a-b285-44dc-88e9-531188ee72e7")!, major: 0, minor: 1, name: "Dime Team", description: "Awesome Innovations", image: "beacon-icon"),
        BeaconData(uuid: UUID(uuidString: "c2db97d9-6e80-44a2-82f5-3987065ba4ea")!, major: 7, minor: 11, name: "Data Team", description: "Busy Team", image: "beacon-icon")]

信标数据定义

struct BeaconData: RegionData{

    let uuid: UUID
    let major: NSNumber
    let minor: NSNumber
    let beaconRegion: CLBeaconRegion
    let name: String
    let detail: String
    let image: String

    init(uuid:  UUID, major: NSNumber, minor: NSNumber, name: String, description: String, image: String) {
        self.uuid = uuid
        self.major = major
        self.minor = minor
        self.beaconRegion = CLBeaconRegion(beaconIdentityConstraint: CLBeaconIdentityConstraint(uuid: uuid), identifier: name)
        self.name = name
        self.detail = description
        self.image = image
    }
    init(uuid:  UUID, major: NSNumber, minor: NSNumber, beaconRegion: CLBeaconRegion, name: String, description: String, image: String) {
        self.uuid = uuid
        self.major = major
        self.minor = minor
        self.beaconRegion = beaconRegion
        self.name = name
        self.detail = description
        self.image = image
    }

    func contains(region: CLRegion) -> Bool {
        return self.beaconRegion == region
    }
}

这是开始测距的代码。底部的注释调用可以按需要工作。上面未注释的调用是不稳定的调用。 W 在调用中创建内联约束,只是 UUID。它适用于一个信标,但一旦我们添加第二个信标(如上所述具有不同的 UUID),它就只范围是最新的。

        for region in beaconRegionsToRange {
            print("Start Ranging \(region.uuid)")
            locationManager.startRangingBeacons(satisfying: CLBeaconIdentityConstraint(uuid: region.uuid))
            //locationManager.startRangingBeacons(in: region)
        }

我们如何让它使用较新的“满足约束”方法来确定所有信标的范围?


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SWIFT:CoreLocation - 使用 CLBeaconIdentityConstraint 测距信标不会测距多个信标 的相关文章

随机推荐