🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
> [Determining the Proximity to an iBeacon](https://developer.apple.com/documentation/corelocation/determining_the_proximity_to_an_ibeacon?language=occ) 学习如何探测信标,并确定它们的相对距离。 ### 第1节概述 iBeacon 是一种设备,它能发出蓝牙信号,可以被你的设备检测到。企业可以在距离检测对用户有利的环境中部署 iBeacon 设备,应用可以利用信标的近距离来确定合适的行动路线。根据附近的信标,你决定采取什么行动。例如,百货商店可能会部署识别商店每个部分的信标,相应的应用程序可能会在用户靠近每个区域时指出销售项目。 在你的应用中加入 iBeacon 支持,包括在两个不同的阶段探测信标: 1. 使用区域监测来检测 iBeacon 的存在。 2. 使用信标来确定接近被检测到的iBeacon的距离。 使用两个步骤来探测信标可以大大降低功耗。测距需要频繁地测量蓝牙信号的强度,并计算距离到相关的信标的距离。相比之下,区域监测只需要被动地倾听附近的信标,后者消耗的电力要少得多。 ### 第2节部署 iBeacon 硬件 在部署 iBeacon 硬件时,必须使用适当的邻近 UUID,major, minor 值来编程每个 iBeacon设备。这些值可唯一标识每个信标,并使应用程序能够在一后区分这些信标。 - 邻近UUID(通用唯一标识符)是一个128位值,唯一标识应用程序的信标。 - major 值是一个16位无符号整数,用于区分具有相同的邻近 UUID 的信标组。 - minor 值是一个16位无符号整数,用于区分具有相同 UUID 和 major 值的信标组。 只有邻近的 UUID 是必须的,但是建议将三个值编程到 iBeacon 硬件中。在应用程序中,可以通过指定值的一个子集来查找相关的信标组。 ### 第3节 利用区域监测检测信标的存在 当 iBeacon 在附近时,使用区域监测来提醒应用程序。要监视信标,请创建一个 [CLBeaconRegion](https://developer.apple.com/documentation/corelocation/clbeaconregion?language=objc) 对象,并使用 [CLLocationManager](https://developer.apple.com/documentation/corelocation/cllocationmanager?language=objc) 对象的 [startMonitoringForRegion:](https://developer.apple.com/documentation/corelocation/cllocationmanager/1423656-startmonitoringforregion?language=objc) 方法进行注册。BeaconRegion 包含要检测的信标的邻近 UUID ,major 值和 minor 值。只有具有匹配值的信标才会触发对委托对象的调用。 清单1显示了如何为公司的信标设置区域监控的例子。由于通常为公司定义一个 UUID,稍后不要更改,因此该示例包含该值的硬编码版本。在调用此方法之前,必须已经创建了一个 [CLLocationManager](https://developer.apple.com/documentation/corelocation/cllocationmanager?language=objc) 对象并为其指派了一个委托。 ###### 清单1 为信标设置区域检测 ``` func monitorBeacons() { if CLLocationManager.isMonitoringAvailable(for: CLBeaconRegion.self) { // Match all beacons with the specified UUID let proximityUUID = UUID(uuidString: "39ED98FF-2900-441A-802F-9C398FC199D2") let beaconID = "com.example.myBeaconRegion" // Create the region and begin monitoring it. let region = CLBeaconRegion(proximityUUID: proximityUUID!, identifier: beaconID) self.locationManager.startMonitoring(for: region) } } ``` 当检测到匹配的 iBeacon 时,CLLocationManager 对象通过调用 [locationManager:didEnterRegion:](https://developer.apple.com/documentation/corelocation/cllocationmanagerdelegate/1423560-locationmanager?language=objc) 方法来通知其委托。类似地,当检测到的信标移出范围时,位置管理器调用 [locationManager:didExitRegion:](https://developer.apple.com/documentation/corelocation/cllocationmanagerdelegate/1423630-locationmanager?language=objc) 方法。使用委托方法来启动和停止信标测距。 如果应用在检测到信标时未运行,系统会尝试启动您的应用。 > 重要提示 > 应用程序必须始终具有使用区域监视的权限,并且必须配置位置更新后台模式才能启动。 ### 第4节使用测距确定与信标的距离 在检测到 iBeacon 后,使用测距来确定信标和用户设备之间的相对距离。当两台设备相距甚远,彼此靠近或彼此紧邻时,会发出报告。它不提供一个精确的距离,也不应该依靠信号的强度来自己计算这些信息。使用相对值来确定适当的操作过程。例如,一个美术馆的应用程序可能会等待,直到用户在 iBeacon 的附近,然后才能提供相应的作品信息。 ###### 图1 确定相对接近 iBeacon 的距离 ![image](https://docs-assets.developer.apple.com/published/1b05f56180/6644bab4-c328-45b7-9020-2eb4ba8dadcc.png) 开始测距的最合理的地方是在首次检测到信标时 locationManager.delegat 的 [locationManager:didEnterRegion:](https://developer.apple.com/documentation/corelocation/cllocationmanagerdelegate/1423560-locationmanager?language=objc) 方法。(停止测距量的地方在代理的 [locationManager:didExitRegion:](https://developer.apple.com/documentation/corelocation/cllocationmanagerdelegate/1423630-locationmanager?language=objc) 方法中。) 要开始测距,请将用于区域监测的 [CLBeaconRegion](https://developer.apple.com/documentation/corelocation/clbeaconregion?language=objc) 对象传递给 locationManager 的 [startRangingBeaconsInRegion:](https://developer.apple.com/documentation/corelocation/cllocationmanager/1620554-startrangingbeaconsinregion?language=objc) 方法。 清单2展示了这个委托方法的一个实现,它检测到信标时打开了的测距。该方法还将信标添加到内部数组,以便应用程序可以随时停止和重新启动测距。例如,当应用程序在后台以节省电力时,可能会停止测距。 ###### 清单2 测距信标 ``` func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) { if region is CLBeaconRegion { // Start ranging only if the feature is available. if CLLocationManager.isRangingAvailable() { manager.startRangingBeacons(in: region as! CLBeaconRegion) // Store the beacon so that ranging can be stopped on demand. beaconsToRange.append(region as! CLBeaconRegion) } } } ``` 当测距处于活动状态时,只要有更改报告,locationManager 对象就会调用其委托的 locationManager:didRangeBeacons:inRegion: 方法。使用此方法根据附近的信标的距离采取行动。清单3显示博物馆应用程序如何使用邻近值来显示最近展览的信息。在这个例子中,博物馆使用 major 和 minor 来确定哪个展览。 ### ### 清单3 在最近的信标上的操作 ``` func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) { if beacons.count > 0 { let nearestBeacon = beacons.first! let major = CLBeaconMajorValue(nearestBeacon.major) let minor = CLBeaconMinorValue(nearestBeacon.minor) switch nearestBeacon.proximity { case .near, .immediate: // Display information about the relevant exhibit. displayInformationAboutExhibit(major: major, minor: minor) break default: // Dismiss exhibit information, if it is displayed. dismissExhibit(major: major, minor: minor) break } } } ``` > 提示 > 部署信标时,考虑给每一个UUID,major 和 minor 值的独特组合,以便可以更容易地区分它们。 如果多个信标使用相同的UUID,major 和 minor ,则传送到 [locationManager:didRangeBeacons:inRegion:](https://developer.apple.com/documentation/corelocation/cllocationmanagerdelegate/1621501-locationmanager?language=objc) 方法的信标数组可能只能通过它们的距离和精度值进行区分。