Итак, мы столкнулись с проблемой, развивающейся в Swift для iOS 13. Когда мы используем более новый метод для ранжирования маяков «startRangingBeacons (удовлетворяющий: CLBeaconIdentityConstraint)», он будет ранжировать только последний добавленный маяк, поэтому, если есть Есть более одного маяка, у нас есть проблемы. Когда мы используем более старый метод startRangingBeacons (in: region), он устарел, но все еще функционирует в iOS 13, приложение работает должным образом.
Подробности (используя более новый метод с «ограничениями»):
- Приложение запускает мониторинг двух областей маяка
- Запускает дальние маяки, если пользователь вводит BeaconRegion
- Включите Beacon1, приложение начинает диапазон Beacon1
- Включите 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")]
Определение BeaconData
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)
}
Как получить диапазон всех маяков с помощью более нового метода "тонадежные ограничения "?