扫描信标并在swift中找到最接近的信标

时间:2016-01-15 09:53:57

标签: swift ibeacon

我想开发一个快速的项目来检测iPhone周围的信标并确定哪一个是最接近的信标。我做了很多搜索,但我没有得到一些对我有用的东西(我是快速开发的新手,所以我能解决这个问题)任何人都可以帮助我,所以我可以开始了。

2 个答案:

答案 0 :(得分:2)

您可以使用:

func locationManager(manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], inRegion region: CLBeaconRegion) {
let knownBeacons = beacons.filter{ $0.proximity != CLProximity.Unknown }
if (knownBeacons.count > 0) {
    let closestBeacon = knownBeacons[0] as CLBeacon
}

}

从我的测试中,信标到达已经从最近到最远排序的信标阵列,首先是未知数,然后是最近的已知信标。也就是说,我在文档中的任何地方都找不到这个,所以我不建议在生产应用程序中始终发生这种情况。为了简单起见,我们将把信标数组中的第一个元素作为最近的信标。我们过滤数组以移除具有未知范围的信标

答案 1 :(得分:0)

找到最近的信标可能会非常复杂。如果没有RSSI(信号强度),有时信标的准确度值为-1,如果在最后一秒未检测到信标,有时信标会从扫描列表中丢失。这是我用于基础知识的一些Swift代码:

let expirationTimeSecs = 5.0
public var closestBeacon: CLBeacon? = nil
var trackedBeacons: Dictionary<String, CLBeacon>
var trackedBeaconTimes: Dictionary<String, NSDate>

override init() {
  trackedBeacons = Dictionary<String, CLBeacon>()
  trackedBeaconTimes = Dictionary<String, NSDate>()
}

public func locationManager(manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], inRegion region: CLBeaconRegion) {
  let now = NSDate()
  for beacon in beacons {
    let key = keyForBeacon(beacon)
    if beacon.accuracy < 0 {
      NSLog("Ignoring beacon with negative distance")
    }
    else {
      trackedBeacons[key] = beacon
      if (trackedBeaconTimes[key] != nil) {
        trackedBeaconTimes[key] = now
      }
      else {
        trackedBeaconTimes[key] = now
      }
    }
  }
  purgeExpiredBeacons()
  calculateClosestBeacon()
}

func calculateClosestBeacon() {
  var changed = false
    // Initialize cloestBeaconCandidate to the latest tracked instance of current closest beacon
    var closestBeaconCandidate: CLBeacon?
    if closestBeacon != nil {
      let closestBeaconKey = keyForBeacon(closestBeacon!)
      for key in trackedBeacons.keys {
        if key == closestBeaconKey {
          closestBeaconCandidate = trackedBeacons[key]
        }
      }
    }

    for key in trackedBeacons.keys {
      var closer = false
      let beacon = trackedBeacons[key]
      if (beacon != closestBeaconCandidate) {
        if beacon!.accuracy > 0 {
          if closestBeaconCandidate == nil {
            closer = true
          }
          else if beacon!.accuracy < closestBeaconCandidate!.accuracy {
            closer = true
          }
        }
        if closer {
          closestBeaconCandidate = beacon
          changed = true
        }
      }
    }
    if (changed) {
      closestBeacon = closestBeaconCandidate
    }
}

func keyForBeacon(beacon: CLBeacon) -> String {
  return "\(beacon.proximityUUID.UUIDString) \(beacon.major) \(beacon.minor)"
}

func purgeExpiredBeacons() {
  let now = NSDate()
  var changed = false
  var newTrackedBeacons = Dictionary<String, CLBeacon>()
  var newTrackedBeaconTimes = Dictionary<String, NSDate>()
  for key in trackedBeacons.keys {
    let beacon = trackedBeacons[key]
    let lastSeenTime = trackedBeaconTimes[key]!
    if now.timeIntervalSinceDate(lastSeenTime) > expirationTimeSecs {
      NSLog("******* Expired seeing beacon: \(key) time interval is \(now.timeIntervalSinceDate(lastSeenTime))")
      changed = true
    }
    else {
      newTrackedBeacons[key] = beacon!
      newTrackedBeaconTimes[key] = lastSeenTime
    }
  }
  if changed {
    trackedBeacons = newTrackedBeacons
    trackedBeaconTimes = newTrackedBeaconTimes
  }
}