【官文翻译】区域监测和iBeacon

Region Monitoring and iBeacon

区域监测和iBeacon

The Core Location framework provides two ways to detect a user’s entry and exit into specific regions: geographical region monitoring (iOS 4.0 and later and OS X v10.8 and later) and beacon region monitoring (iOS 7.0 and later).

核心位置框架提供了两种检测用户进入和退出特定区域的方法:地理区域监控(iOS 4.0及更高版本和OS X v10.8及更高)和信标区域监控(IOS7.0及更高版)。

A geographical region is an area defined by a circle of a specified radius around a known point on the Earth’s surface. In contrast, a beacon region is an area defined by the device’s proximity to Bluetooth low-energy beacons.

地理区域是由围绕地球表面已知点的指定半径的圆定义的区域。相比之下,信标区域是由设备接近蓝牙低能量信标定义的区域。

Beacons themselves are simply devices that advertise a particular Bluetooth low-energy payload—you can even turn your iOS device into a beacon with some assistance from the Core Bluetooth framework.

信标本身只是广告特定蓝牙低能量负载的设备,您甚至可以在核心蓝牙框架的帮助下将iOS设备变成信标。

Apps can use region monitoring to be notified when a user crosses geographic boundaries or when a user enters or exits the vicinity of a beacon. While a beacon is in range of an iOS device, apps can also monitor for the relative distance to the beacon.

当用户跨越地理边界或用户进入或离开信标附近时,应用程序可以使用区域监控来获得通知。当信标在iOS设备的范围内时,应用程序还可以监控到信标的相对距离。

You can use these capabilities to develop many types of innovative location-based apps. Because geographical regions and beacon regions differ, the type of region monitoring you decide to use will likely depend on the use case of your app.

您可以使用这些功能开发多种创新的基于位置的应用程序。由于地理区域和信标区域不同,您决定使用的区域监控类型可能取决于应用程序的使用情况。

In iOS, regions associated with your app are tracked at all times, including when the app isn’t running. If a region boundary is crossed while an app isn’t running, that app is relaunched into the background to handle the event.

在iOS中,与您的应用程序关联的区域会随时被跟踪,包括应用程序未运行时。如果应用程序未运行时跨越了区域边界,则该应用程序将重新启动到后台以处理事件。

Similarly, if the app is suspended when the event occurs, it’s woken up and given a short amount of time (around 10 seconds) to handle the event. When necessary, an app can request more background execution time using the beginBackgroundTaskWithExpirationHandler: method of the UIApplication class.

类似地,如果应用程序在事件发生时被挂起,它会被唤醒,并在短时间内(大约10秒)处理事件。必要时,应用程序可以使用UIApplication类的beginBackgroundTaskWithExpirationHandler:方法请求更多的后台执行时间。

In OS X, region monitoring works only while the app is running (either in the foreground or background) and the user’s system is awake. As a result, the system doesn’t launch apps to deliver region-related notifications.

在OS X中,区域监控仅在应用程序正在运行(无论是在前台还是后台)且用户系统处于唤醒状态时起作用。因此,系统不会启动应用程序来发送与地区相关的通知。

1 Determining the Availability of Region Monitoring

1 确定区域监控的可用性

Before attempting to monitor any regions, your app should check whether region monitoring is supported on the current device. Here are some reasons why region monitoring might not be available:

在尝试监视任何区域之前,应用程序应检查当前设备上是否支持区域监视。以下是区域监控可能不可用的一些原因:

  • The device doesn’t have the necessary hardware to support region monitoring.
  • 该设备没有支持区域监控的必要硬件。
  • The user denied the app the authorization to use region monitoring.
  • 用户拒绝了应用程序使用区域监控的授权。
  • The user disabled location services in the Settings app.
  • 用户在“设置”应用程序中禁用了位置服务。
  • The user disabled Background App Refresh in the Settings app, either for the device or for your app.
  • 用户在设置应用程序中禁用了设备或应用程序的后台应用程序刷新。
  • The device is in Airplane mode and can’t power up the necessary hardware.
  • 设备处于飞行模式,无法启动必要的硬件。

In iOS 7.0 and later, always call the isMonitoringAvailableForClass: and authorizationStatus class methods of CLLocationManager before attempting to monitor regions. (In OS X v10.8 and later and in previous versions of iOS, use the regionMonitoringAvailable class instead.)

在iOS 7.0及更高版本中,在尝试监视区域之前,请始终调用CLLocationManager的isMonitoringAvailableForClass:和authorizationStatus类方法。(在OS X v10.8及更高版本以及iOS的早期版本中,请改用regionMonitoringAvailable类。)

The isMonitoringAvailableForClass: method tells you whether the underlying hardware supports region monitoring for the specified class at all. If that method returns NO, your app can’t use region monitoring on the device.

isMonitoringAvailableForClass:方法告诉底层硬件是否支持对指定类进行区域监视。如果该方法返回NO,则应用程序无法在设备上使用区域监控。

If it returns YES, call the authorizationStatus method to determine whether the app is currently authorized to use location services. If the authorization status is kCLAuthorizationStatusAuthorized, your app can receive boundary crossing notifications for any regions it registered. If the authorization status is set to any other value, the app doesn’t receive those notifications.

如果返回YES,则调用authorizationStatus方法以确定应用程序当前是否被授权使用位置服务。如果授权状态为kCLAuthorizationStatusAuthorized,则您的应用程序可以接收其注册的任何地区的跨境通知。如果授权状态设置为任何其他值,则应用程序不会接收这些通知。

Note: Even when an app isn’t authorized to use region monitoring, it can still register regions for use later. If the user subsequently grants authorization to the app, monitoring for those regions will begin and will generate subsequent boundary crossing notifications. If you don’t want regions to remain installed while your app is not authorized, you can use the locationManager:didChangeAuthorizationStatus: delegate method to detect changes in your app’s status and remove regions as appropriate.
注意:即使应用程序未被授权使用区域监控,它仍可以注册区域以供以后使用。如果用户随后向应用程序授予授权,则将开始对这些区域进行监控,并生成后续的跨境通知。如果您不希望在应用程序未授权时保留安装区域,则可以使用locationManager:didChangeAuthorizationStatus:delegate方法检测应用程序状态的更改,并根据需要删除区域。

Finally, if your app needs to process location updates in the background, be sure to check the backgroundRefreshStatus property of the UIApplication class. You can use the value of this property to determine if doing so is possible and to warn the user if it is not. Note that the system doesn’t wake your app for region notifications when the Background App Refresh setting is disabled globally or specifically for your app.

最后,如果应用程序需要在后台处理位置更新,请确保检查UIApplication类的backgroundRefreshStatus属性。您可以使用此属性的值来确定是否可以这样做,如果不可以,则警告用户。请注意,当“后台应用程序刷新”设置全局禁用或专门针对应用程序禁用时,系统不会为区域通知唤醒应用程序。

2 Monitoring Geographical Regions

2 监测地理区域

Geographical region monitoring uses location services to detect entry and exit into known geographical locations (learn more about location services in Getting the User’s Location). You can use this capability to generate alerts when the user gets close to a specific location or to provide other relevant information. For example, upon approaching a specific dry cleaners, an app could notify the user to pick up any clothes that are now ready.

地理区域监控使用位置服务来检测进入和退出已知地理位置(在获取用户位置中了解有关位置服务的更多信息)。您可以使用此功能在用户接近特定位置时生成警报或提供其他相关信息。例如,当接近特定的干洗店时,应用程序可以通知用户取任何现在准备好的衣服。

2.1 Defining a Geographical Region to Be Monitored

2.1 定义要监控的地理区域

To begin monitoring a geographical region, you must define the region and register it with the system. In iOS 7.0 and later, you define geographical regions using the CLCircularRegion class. (In OS X v10.8 and later and in previous versions of iOS, you use the CLRegion class instead.)

要开始监视地理区域,必须定义该区域并将其注册到系统中。在iOS 7.0及更高版本中,您可以使用CLCircularRegion类定义地理区域。(在OS X v10.8及更高版本以及iOS的早期版本中,您使用CLRegion类。)

Each region you create must include both the data that defines the desired geographic area and a unique identifier string. The identifier string is the only guaranteed way for your app to identify a region later. To register a region, call the startMonitoringForRegion: method of your CLLocationManager object.

您创建的每个区域都必须包含定义所需地理区域的数据和唯一标识符字符串。标识符字符串是应用程序以后识别区域的唯一保证方式。要注册区域,请调用CLLocationManager对象的startMonitoringForRegion:方法。

Listing 2-1 shows a sample method that creates a new geographic region based on a circular overlay region. The overlay’s center point and radius form the boundary for the region, although if the radius is too large to be monitored, it is reduced automatically. You don’t need to save strong references to the regions you create but might want to store the region’s identifier if you plan to access the region information later.

清单2-1显示了一个基于圆形覆盖区域创建新地理区域的示例方法。覆盖的中心点和半径形成区域的边界,但如果半径太大而无法监控,则会自动减小。您不需要保存对所创建区域的强引用,但如果您计划稍后访问区域信息,则可能需要存储区域的标识符。

Listing 2-1 Creating and registering a geographical region based on a Map Kit overlay

清单2-1基于MapKit覆盖创建和注册地理区域

- (void)registerRegionWithCircularOverlay:(MKCircle*)overlay andIdentifier:(NSString*)identifier {
 
   // If the overlay's radius is too large, registration fails automatically,
   // so clamp the radius to the max value.
   CLLocationDistance radius = overlay.radius;
   if (radius > self.locManager.maximumRegionMonitoringDistance) {
      radius = self.locManager.maximumRegionMonitoringDistance;
   }
 
   // Create the geographic region to be monitored.
   CLCircularRegion *geoRegion = [[CLCircularRegion alloc]
      initWithCenter:overlay.coordinate
              radius:radius
          identifier:identifier];
   [self.locManager startMonitoringForRegion:geoRegion];
}

Monitoring of a geographical region begins immediately after registration for authorized apps. However, don’t expect to receive an event right away, because only boundary crossings generate an event. In particular, if the user’s location is already inside the region at registration time, the location manager doesn’t automatically generate an event.

注册授权应用程序后,立即开始监控地理区域。但是,不要期望立即接收事件,因为只有边界交叉才会生成事件。特别是,如果用户的位置在注册时已经在区域内,则位置管理器不会自动生成事件。

Instead, your app must wait for the user to cross the region boundary before an event is generated and sent to the delegate. To check whether the user is already inside the boundary of a region, use the requestStateForRegion: method of the CLLocationManager class.

相反,在生成事件并将其发送给代理之前,您的应用程序必须等待用户越过区域边界。要检查用户是否已经在区域边界内,请使用CLLocationManager类的requestStateForRegion:方法。

Be judicious when specifying the set of regions to monitor. Regions are a shared system resource, and the total number of regions available systemwide is limited. For this reason, Core Location limits to 20 the number of regions that may be simultaneously monitored by a single app.

指定要监视的区域集时要谨慎。区域是共享的系统资源,全系统可用的区域总数有限。因此,核心位置将单个应用程序可同时监控的区域数量限制为20个。

To work around this limit, consider registering only those regions in the user’s immediate vicinity. As the user’s location changes, you can remove regions that are now farther way and add regions coming up on the user’s path.

要解决此限制,请考虑仅注册用户附近的区域。随着用户位置的改变,您可以删除现在更远的区域,并添加用户路径上的区域。

If you attempt to register a region and space is unavailable, the location manager calls the locationManager:monitoringDidFailForRegion:withError: method of its delegate with the kCLErrorRegionMonitoringFailure error code.

如果您尝试注册区域,但空间不可用,则位置管理器将调用其委托的locationManager:monitoringDidFailForRegion:withError:方法,并返回kCLErrorRegionMonitoringFailure错误代码。

2.2 Handling Boundary-Crossing Events for a Geographical Region

2.2 处理地理区域的跨界事件

By default, every time a user’s current location crosses a boundary region, the system generates an appropriate region event for your app. Apps can implement the following methods to handle boundary crossings:

默认情况下,每次用户的当前位置跨越边界区域时,系统都会为您的应用程序生成一个适当的区域事件。应用程序可以实现以下方法来处理边界穿越:

  • locationManager:didEnterRegion:
  • locationManager:didExitRegion:

You can customize which boundary-crossing events notify your app by explicitly setting the notifyOnEntry and notifyOnExit properties of the CLRegion class when you define and register a region. (The default value of both properties is YES.) For example, if you want to be notified only when the user exits the boundary of a region, you can set the value of the region’s notifyOnEntry property to NO.

通过在定义和注册区域时显式设置CLRegion类的notifyOnEntry和notifyOnExit财产,可以自定义哪些边界交叉事件通知应用程序。(两个财产的默认值都是YES。)例如,如果您只想在用户退出区域边界时收到通知,可以将区域的notifyOnEntry属性的值设置为NO。

The system doesn’t report boundary crossings until the boundary plus a system-defined cushion distance is exceeded. This cushion value prevents the system from generating numerous entered and exited events in quick succession while the user is traveling close the edge of the boundary.

在超过边界加上系统定义的缓冲距离之前,系统不会报告边界交叉。当用户接近边界边缘时,该缓冲值防止系统快速连续生成大量输入和退出事件。

When a region boundary is crossed, the most likely response is to alert the user of the proximity to the target item. If your app is running in the background, you can use local notifications to alert the user; otherwise, you can simply post an alert.

当越过区域边界时,最可能的响应是提醒用户与目标项目的接近程度。如果你的应用程序在后台运行,你可以使用本地通知来提醒用户;否则,您可以简单地发布警报。

3 Monitoring Beacon Regions

3 监测信标区域

Beacon region monitoring uses an iOS device’s onboard radio to detect when the user is in the vicinity of Bluetooth low-energy devices that are advertising iBeacon information. As with geographical region monitoring, you can use this capability to generate alerts or to provide other relevant information when the user enters or exits a beacon region.

信标区域监控使用iOS设备的车载无线电来检测用户何时在广告iBeacon信息的蓝牙低能耗设备附近。与地理区域监控一样,您可以使用此功能在用户进入或退出信标区域时生成警报或提供其他相关信息。

Rather than being identified by fixed geographical coordinates, however, a beacon region is identified by the device’s proximity to Bluetooth low-energy beacons that advertise a combination of the following values:

然而,信标区域不是通过固定的地理坐标来标识的,而是通过设备与蓝牙低能量信标的接近程度来标识的:

  • A proximity UUID (universally unique identifier), which is a 128-bit value that uniquely identifies one or more beacons as a certain type or from a certain organization
  • 一个接近UUID(通用唯一标识符),它是一个128位的值,将一个或多个信标唯一地标识为特定类型或来自特定组织
  • A major value, which is a 16-bit unsigned integer that can be used to group related beacons that have the same proximity UUID
  • 一个主要值,它是一个16位无符号整数,可用于对具有相同接近UUID的相关信标进行分组
  • A minor value, which is a 16-bit unsigned integer that differentiates beacons with the same proximity UUID and major value
  • 次要值,是一个16位无符号整数,用于区分具有相同接近UUID和主要值的信标

Because a single beacon region can represent multiple beacons, beacon region monitoring supports several interesting use cases. For example, an app dedicated to enhancing the experience of customers at a particular department store can use the same proximity UUID to monitor all stores in the department store chain.

因为单个信标区域可以表示多个信标,所以信标区域监控支持几个有趣的用例。例如,一个致力于增强特定百货商店客户体验的应用程序可以使用相同的邻近UUID来监控百货商店链中的所有商店。

When the user approaches a store, the app detects the store’s beacons and uses the major and minor values of those beacons to determine additional information, such as which specific store was encountered or which section of the store the user is in. (Note that although every beacon must advertise a proximity UUID, major and minor values are optional.)

当用户接近商店时,应用程序检测商店的信标,并使用这些信标的主要和次要值来确定附加信息,例如遇到了哪个特定商店或用户所在的商店的哪个部分。(请注意,尽管每个信标都必须通告邻近UUID,但主要值和次要值是可选的。)

3.1 Defining a Beacon Region to Be Monitored

3.1 定义要监视的信标区域

To begin monitoring a beacon region, define the region and register it with the system. You define a beacon region with the appropriate initialization method of the CLBeaconRegion class.

要开始监视信标区域,请定义该区域并将其注册到系统中。您可以使用CLBeaconRegion类的适当初始化方法定义信标区域。

When you create a CLBeaconRegion object, you specify the proximityUUID, major, and minor properties of the beacons you want to monitor (the proximity UUID is required; the major and minor values are optional).

创建CLBeaconRegion对象时,指定要监视的信标的proximityUUID、major和minor财产(需要接近UUID;major值和minor值是可选的)。

You must also supply a string that uniquely identifies the region so that you can refer to it in your code. Note that a region’s identifier is unrelated to the identifying information that a beacon advertises.

还必须提供唯一标识区域的字符串,以便在代码中引用该区域。注意,区域的标识符与信标通告的标识信息无关。

To register a beacon region, call the startMonitoringForRegion: method of your CLLocationManager object. Listing 2-2 shows a sample method that creates and registers a beacon region.

要注册信标区域,请调用CLLocationManager对象的startMonitoringForRegion:方法。清单2-2显示了创建和注册信标区域的示例方法。

Listing 2-2 Creating and registering a beacon region

清单2-2创建和注册信标区域

- (void)registerBeaconRegionWithUUID:(NSUUID *)proximityUUID andIdentifier:(NSString*)identifier {
 
   // Create the beacon region to be monitored.
   CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc]
      initWithProximityUUID:proximityUUID
                 identifier:identifier];
 
   // Register the beacon region with the location manager.
   [self.locManager startMonitoringForRegion:beaconRegion];
}

As with geographical region monitoring, monitoring of a beacon region begins immediately after registration for authorized apps. When a user’s device detects a beacon that is advertising the identifying information defined by the registered beacon region (proximity UUID, major value, and minor value), the system generates an appropriate region event for your app.

与地理区域监控一样,信标区域的监控在注册授权应用程序后立即开始。当用户的设备检测到一个信标,该信标正在广告由注册的信标区域(接近UUID、主要值和次要值)定义的标识信息时,系统会为您的应用程序生成一个适当的区域事件。

Note: It’s not unusual to configure a beacon region using only a UUID value. Doing so yields a region that is activated when the device comes within range of any beacon with the specified UUID. Upon entering the beacon region, you would then begin ranging for beacons to obtain detailed information about the specific beacons that are nearby. For more information about beacon ranging, see Determining the Proximity of a Beacon Using Ranging.
注意:仅使用UUID值配置信标区域并不罕见。这样做会产生一个区域,当设备位于具有指定UUID的任何信标的范围内时,该区域将被激活。进入信标区域后,您将开始测距信标,以获取附近特定信标的详细信息。有关信标测距的更多信息,请参阅使用测距确定信标的接近度。

3.2 Handling Boundary-Crossing Events for a Beacon Region

3.2 处理信标区域的边界穿越事件

When a user enters the registered beacon region, the location manager calls the locationManager:didEnterRegion: of its delegate object. Similarly, when a user is no longer in range of any beacons in the registered beacon region, the location manager calls the locationManager:didExitRegion: of its delegate object.

当用户进入注册的信标区域时,位置管理器调用其委托对象的locationManager:didEnterRegion:。类似地,当用户不再在注册的信标区域中的任何信标的范围内时,位置管理器调用其代理对象的locationManager:didExitRegion:。

Note that a user must cross the region’s boundary to trigger one of these calls; in particular, the location manager doesn’t call locationManager:didEnterRegion: if the user is already within the region. You can implement these delegate methods to alert the user appropriately or to present location-specific UI.

注意,用户必须跨越区域边界才能触发其中一个呼叫;特别是,如果用户已经在区域内,则位置管理器不会调用locationManager:didEnterRegion。您可以实现这些委托方法来适当地提醒用户或显示特定位置的UI。

You can specify which boundary-crossing events should notify your app by setting the notifyOnEntry and notifyOnExit properties of the beacon region. (The default value of both properties is YES.) For example, if you want to be notified only when the user exits the boundary of a region, you can set the value of the region’s notifyOnEntry property to NO.

您可以通过设置信标区域的notifyOnEntry和notifyOnExit财产来指定哪些跨界事件应通知您的应用程序。(两个财产的默认值都是YES。)例如,如果您只想在用户退出区域边界时收到通知,可以将区域的notifyOnEntry属性的值设置为NO。

You can also postpone notifying a user upon entering a beacon region until the user turns on the device’s display. To do so, simply set the value of the beacon region’s notifyEntryStateOnDisplay property value to YES and set the region’s notifyOnEntry property to NO when you register the beacon region. To prevent redundant notifications from being delivered to the user, post a local notification only once per region entry.

您还可以推迟在用户进入信标区域时通知用户,直到用户打开设备的显示器。为此,只需在注册信标区域时将信标区域的notifyEntryStateOnDisplay属性值设置为YES,并将区域的notifyOnEntry属性设置为NO。为了防止冗余通知传递给用户,每个区域条目只能发布一次本地通知。

3.2.1 Determining the Proximity of a Beacon Using Ranging

3.2.1 使用测距确定信标的接近度

While a user’s device is inside a registered beacon region, apps can use the startRangingBeaconsInRegion: method of the CLLocationManager class to determine the relative proximity of one or more beacons in the region and to be notified when that distance changes. (Always call the isRangingAvailable class method of the CLLocationManager class before attempting to range beacons in a beacon region.)

当用户的设备位于注册的信标区域内时,应用程序可以使用CLLocationManager类的startRangingBeaconsInRegion:方法来确定该区域中一个或多个信标的相对接近度,并在距离发生变化时得到通知。(在尝试对信标区域中的信标进行测距之前,请始终调用CLLocationManager类的isRangingAvailable类方法。)

Knowing the relative distance to a beacon can be useful for many apps. For example, imagine a museum that places a beacon at each exhibit. A museum-specific app could use a particular exhibit’s proximity as a cue to provide information about that exhibit rather than another.

了解到信标的相对距离对许多应用程序都很有用。例如,想象一个博物馆在每个展览上放置一个灯塔。博物馆专用的应用程序可以使用特定展品的邻近度作为提示,提供有关该展品的信息,而不是另一个展品的信息。

The location manager calls the locationManager:didRangeBeacons:inRegion: of its delegate object whenever beacons in the specified beacon region come within range, go out of range, or their proximity changes. This delegate method provides an array of CLBeacon objects that represent the beacons currently in range.

每当指定信标区域中的信标进入范围、超出范围或其接近度发生变化时,位置管理器就会调用其代理对象的locationManager:didRangeBeacons:inRegion:。此委托方法提供CLBeacon对象数组,这些对象表示当前范围内的信标。

The array of beacons is ordered by approximate distance from the device, with the closest beacon at the beginning of the array. You can use the information in these objects to determine the proximity of the user to each beacon. The value in the proximity property of the CLBeacon object gives a general sense of the relative distance to a beacon.

信标阵列按距设备的近似距离排序,最接近的信标位于阵列的开头。您可以使用这些对象中的信息来确定用户与每个信标的接近程度。CLBeacon对象的邻近度属性中的值提供了到信标的相对距离的一般意义。

Note: Beacon ranging depends on detecting the strength of Bluetooth low-energy radio signals, and the accuracy of those signals is attenuated (or lessened) by walls, doors, and other physical objects. The signals are also affected by water, which means the human body itself will affect the signals. It is important to be aware of these factors when planning your iBeacon deployment because they will impact the proximity value reported by each beacon. If needed, use the accuracy and rssi values reported by each CLBeacon object to adjust the placement of your beacons during deployment.

注意:信标测距取决于检测蓝牙低能量无线电信号的强度,这些信号的准确性会被墙壁、门和其他物理物体衰减(或降低)。信号也会受到水的影响,这意味着人体本身会影响信号。在规划iBeacon部署时,务必注意这些因素,因为它们会影响每个信标报告的接近值。如果需要,使用每个CLBeacon对象报告的精度和rssi值来调整部署期间信标的位置。

Inspired by the sample museum app described earlier in this section, Listing 2-3 shows how to use a beacon’s proximity property to determine its relative distance from the user’s device. The code presents a UI that provides more information about a particular museum exhibit when the proximity of the closest beacon in the array is relatively close to the user (as defined by the CLProximityNear constant).

受本节前面描述的示例博物馆应用程序的启发,清单2-3显示了如何使用信标的邻近属性来确定其与用户设备的相对距离。当阵列中最近的信标的接近度相对接近用户时(如CLProximityNear常数所定义的),该代码提供了一个UI,该UI提供了有关特定博物馆展品的更多信息。

Listing 2-3 Determining the relative distance between a beacon and a device

清单2-3确定信标和设备之间的相对距离

// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manager
        didRangeBeacons:(NSArray *)beacons
               inRegion:(CLBeaconRegion *)region {
 
   if ([beacons count] > 0) {
      CLBeacon *nearestExhibit = [beacons firstObject];
 
      // Present the exhibit-specific UI only when
      // the user is relatively close to the exhibit.
      if (CLProximityNear == nearestExhibit.proximity) {
         [self presentExhibitInfoWithMajorValue:nearestExhibit.major.integerValue];
      } else {
         [self dismissExhibitInfo];
   }
}

To promote consistent results in your app, use beacon ranging only while your app is in the foreground. If your app is in the foreground, it is likely that the device is in the user’s hand and that the device’s view to the target beacon has fewer obstructions. Running in the foreground also promotes better battery life by processing incoming beacon signals only while the user is actively using the device.

要在应用程序中促进一致的结果,请仅在应用程序处于前台时使用信标测距。如果您的应用程序位于前台,则设备很可能在用户手中,并且设备对目标信标的视图障碍物较少。在前台运行还通过仅在用户积极使用设备时处理传入的信标信号来提高电池寿命。

Note: If multiple beacon devices are advertising the same combination of proximity UUID, major values, and minor values, they may be reported by the locationManager:didRangeBeacons:inRegion: method as having different proximities and accuracies. It’s recommended that each beacon device be uniquely identified.
注意:如果多个信标设备正在通告接近UUID、主要值和次要值的相同组合,则locationManager:didRangeBeacons:inRegion:方法可能会报告它们具有不同的接近度和精度。建议对每个信标设备进行唯一标识。

Additionally, if you are ranging an iOS device that has been configured as a beacon, there may be a brief period in which the locationManager:didRangeBeacons:inRegion: method reports two devices with the same proximity UUID, major, and minor values instead of just one. This behavior occurs because the Bluetooth identifier of an iOS device changes periodically out of privacy concerns. The proximity property based on the original Bluetooth identifier reports a value of CLProximityUnknown within 2 seconds of the identifier change. Within 10 seconds, the identifiers resolve and only one beacon region is reported.
此外,如果您正在对已配置为信标的iOS设备进行测距,则可能会有一段时间,其中locationManager:didRangeBeacons:inRegion:方法报告两个具有相同接近UUID、主要和次要值的设备,而不是仅报告一个。出现这种行为是因为出于隐私考虑,iOS设备的蓝牙标识符会定期更改。基于原始蓝牙标识符的邻近度属性在标识符更改后2秒内报告CLProximityUnknown值。在10秒内,标识符解析,仅报告一个信标区域。

4 Turning an iOS Device into an iBeacon

4 将iOS设备转变为iBeacon

Any iOS device that supports sharing data using Bluetooth low energy can be used as an iBeacon. Because the app you write must run in the foreground, iBeacon support on iOS devices is intended for testing purposes and for apps that always run in the foreground anyway, such as point-of sale apps. For other types of iBeacon implementations, you need to acquire dedicated beacon hardware from third-party manufacturers.

任何支持使用蓝牙低能耗共享数据的iOS设备都可以用作iBeacon。由于您编写的应用程序必须在前台运行,iOS设备上的iBeacon支持旨在用于测试目的,以及始终在前台运行的应用程序,例如销售点应用程序。对于其他类型的iBeacon实现,您需要从第三方制造商购买专用信标硬件。

Because turning your iOS device into a beacon requires the use of the Core Bluetooth framework, be sure to link your app to CoreBluetooth.framework in your Xcode project. To access the classes and headers of the framework, include an #import <CoreBluetooth/CoreBluetooth.h> statement at the top of any relevant source files.

因为将iOS设备变成信标需要使用核心蓝牙框架,请确保将应用程序链接到Xcode项目中的CoreBluetooth.framework。要访问框架的类和头,请在任何相关源文件的顶部包含#import<CoreBluetooth/CoreBluetooth.h>语句。

4.1 Creating and Advertising a Beacon Region

4.1 创建和宣传灯塔区域

To use your iOS device as a beacon, you first generate a 128-bit UUID that will be your beacon region’s proximity UUID. Open Terminal and type uuidgen on the command line. You receive a unique 128-bit value in an ASCII string that is punctuated by hyphens, as in this example.

要将iOS设备用作信标,首先要生成一个128位UUID,该UUID将是信标区域的邻近UUID。打开终端并在命令行中键入uuidgen。您将收到一个ASCII字符串中唯一的128位值,该字符串由连字符分隔,如本例所示。

$ uuidgen
39ED98FF-2900-441A-802F-9C398FC199D2

Next, create a beacon region with the UUID you generated for the beacon’s proximity UUID, defining the major and minor values as needed. Be sure to also use a unique string identifier for the new region. This code shows how to create a new beacon region using the example UUID above.

接下来,使用为信标的邻近UUID生成的UUID创建信标区域,根据需要定义主要值和次要值。确保还为新区域使用唯一的字符串标识符。这段代码显示了如何使用上面的示例UUID创建新的信标区域。

NSUUID *proximityUUID = [[NSUUID alloc]
      initWithUUIDString:@"39ED98FF-2900-441A-802F-9C398FC199D2"];
 
// Create the beacon region.
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc]
      initWithProximityUUID:proximityUUID
                 identifier:@"com.mycompany.myregion"

Now that you have created a beacon region, you need to advertise your beacon’s proximity UUID (and any major or minor value you specified) using the CBPeripheralManager class of the Core Bluetooth framework. In Core Bluetooth, a peripheral is a device that advertises and shares data using Bluetooth low energy. Advertising your beacon’s data is the only way other devices can detect and range your beacon.

现在您已经创建了信标区域,您需要使用Core Bluetooth框架的CBPeripheralManager类来通告信标的邻近UUID(以及您指定的任何主要或次要值)。在核心蓝牙中,外围设备是一种使用蓝牙低能量来宣传和共享数据的设备。广告您的信标数据是其他设备检测和定位信标的唯一方法。

To advertise peripheral data in Core Bluetooth, you call the startAdvertising: method of the CBPeripheralManager class on an instance of a CBPeripheralManager object. This method expects a dictionary (an instance of NSDictionary) of advertisement data. As the next example shows, use the peripheralDataWithMeasuredPower: method of the CLBeaconRegion class to receive a dictionary that encodes your beacon’s identifying information along with other information needed for Core Bluetooth to advertise the beacon as a peripheral.

要在Core Bluetooth中公布外围数据,请在CBPeripheralManager对象的实例上调用CBPeripheral Manager类的startAdvertising:方法。此方法需要广告数据的字典(NSDictionary的实例)。如下一个示例所示,使用CLBeaconRegion类的peripheralDataWithMeasuredPower:方法接收一个字典,该字典对信标的标识信息以及核心蓝牙所需的其他信息进行编码,以将信标作为外围设备进行宣传。

// Create a dictionary of advertisement data.
NSDictionary *beaconPeripheralData =
      [beaconRegion peripheralDataWithMeasuredPower:nil];
Note: The code above passes in a value of nil to the measuredValue parameter, which represents the received signal strength indicator (RSSI) value (measured in decibels) of the beacon from one meter away. This value is used during ranging. Specifying nil uses the default value for the device. Optionally, specify an RSSI value if you need to further calibrate the device for better ranging performance in certain environments.
注意:上面的代码向measuredValue参数传递了一个值nil,该值表示一米外信标的接收信号强度指示器(RSSI)值(以分贝为单位)。此值在测距期间使用。指定nil将使用设备的默认值。如果需要进一步校准设备以在某些环境中获得更好的测距性能,可以选择指定RSSI值。

Next, create an instance of the CBPeripheralManager class, and ask it to advertise your beacon for other devices to detect, as shown in the code below.

接下来,创建CBPeripheralManager类的一个实例,并要求它通告信标以供其他设备检测,如下面的代码所示。

// Create the peripheral manager.
CBPeripheralManager *peripheralManager = [[CBPeripheralManager alloc]
   initWithDelegate:selfqueue:nil options:nil];
 
// Start advertising your beacon's data.
[peripheralManager startAdvertising:beaconPeripheralData];
Important: When you create a peripheral manager object, the peripheral manager calls the peripheralManagerDidUpdateState: method of its delegate object. You must implement this delegate method to ensure that Bluetooth low energy is supported and available to use on the local peripheral device. For more information about this delegate method, see CBPeripheralManagerDelegate Protocol Reference.

重要提示:当您创建外围设备管理器对象时,外围设备管理程序将调用其委托对象的peripheralManagerDidUpdateState:方法。您必须实现此委派方法,以确保本地外围设备支持并可使用低能耗蓝牙。有关此委托方法的更多信息,请参阅CBPeripheralManagerDelegate协议参考。

After advertising your app as a beacon, your app must continue running in the foreground to broadcast the needed Bluetooth signals. If the user quits the app, the system stops advertising your device as a peripheral.

For more information about how to use a peripheral manager to advertise data using Bluetooth low energy, see CBPeripheralManager Class Reference and Core Bluetooth Programming Guide.

在将应用程序广告为信标后,应用程序必须继续在前台运行,以广播所需的蓝牙信号。如果用户退出应用程序,系统将停止将您的设备作为外围设备进行广告宣传。
有关如何使用外围设备管理器使用蓝牙低能耗播发数据的更多信息,请参阅CBPeripheralManager类参考和核心蓝牙编程指南。

5 Testing an iOS App’s Region Monitoring Support

5 测试iOS应用程序的区域监控支持

When testing your region monitoring code in iOS Simulator or on a device, realize that region events may not happen immediately after a region boundary is crossed. To prevent spurious notifications, iOS doesn’t deliver region notifications until certain threshold conditions are met. Specifically, the user’s location must cross the region boundary, move away from the boundary by a minimum distance, and remain at that minimum distance for at least 20 seconds before the notifications are reported.

在iOS模拟器或设备上测试区域监控代码时,请意识到区域事件可能不会在跨越区域边界后立即发生。为了防止虚假通知,在满足某些阈值条件之前,iOS不会发送区域通知。具体而言,用户的位置必须越过区域边界,离开边界一段最小距离,并在报告通知之前保持该最小距离至少20秒。

The specific threshold distances are determined by the hardware and the location technologies that are currently available. For example, if Wi-Fi is disabled, region monitoring is significantly less accurate. However, for testing purposes, you can assume that the minimum distance is approximately 200 meters.

具体阈值距离由硬件和当前可用的定位技术确定。例如,如果禁用了Wi-Fi,则区域监控的准确性会大大降低。但是,出于测试目的,您可以假设最小距离约为200米。

posted @ 2023-02-03 17:23  码出境界  阅读(198)  评论(0编辑  收藏  举报