美文网首页
CoreLocation框架详细解析(十六) —— 基于Core

CoreLocation框架详细解析(十六) —— 基于Core

作者: 刀客传奇 | 来源:发表于2020-12-11 13:26 被阅读0次

    版本记录

    版本号 时间
    V1.0 2020.12.11 星期五

    前言

    很多的app都有定位功能,比如说滴滴,美团等,他们都需要获取客户所在的位置,并且根据位置推送不同的模块数据以及服务,可以说,定位方便了我们的生活,接下来这几篇我们就说一下定位框架CoreLocation。感兴趣的可以看我写的上面几篇。
    1. CoreLocation框架详细解析 —— 基本概览(一)
    2. CoreLocation框架详细解析 —— 选择定位服务的授权级别(二)
    3. CoreLocation框架详细解析 —— 确定定位服务的可用性(三)
    4. CoreLocation框架详细解析 —— 获取用户位置(四)
    5. CoreLocation框架详细解析 —— 监控用户与地理区域的距离(五)
    6. CoreLocation框架详细解析 —— 确定接近iBeacon(六)
    7. CoreLocation框架详细解析 —— 将iOS设备转换为iBeacon(七)
    8. CoreLocation框架详细解析 —— 获取指向和路线信息(八)
    9. CoreLocation框架详细解析 —— 在坐标和用户友好的地名之间转换(九)
    10. CoreLocation框架详细解析(十) —— 跟踪访问位置简单示例(一)
    11. CoreLocation框架详细解析(十一) —— 跟踪访问位置简单示例(二)
    12. CoreLocation框架详细解析(十二) —— 仿Runkeeper的简单实现(一)
    13. CoreLocation框架详细解析(十三) —— 仿Runkeeper的简单实现(二)
    14. CoreLocation框架详细解析(十四) —— 仿Runkeeper的简单实现(三)
    15. CoreLocation框架详细解析(十五) —— 仿Runkeeper的简单实现(四)

    开始

    首先看下主要内容:

    在此地理围栏教程中,您将学习如何使用Core Location框架在Swift中的iOS中创建和使用地理围栏。内容来自翻译

    下面就是写作环境:

    Swift 5, iOS 14, Xcode 12

    接着就是正文啦

    当应用程序的设备进入或离开已配置的地理区域时,地理围栏将通知该应用程序。 例如,它使您可以制作出色的应用程序,这些应用程序可以在您出门在外时触发通知,或者在用户最喜欢的商店在附近时与他们打招呼。

    在此地理栅栏教程中,您将学习如何从Core Location使用Region Monitoring API。 更具体地说,您将介绍如何:

    • Set up Core Location and permissions
    • Register your geofences
    • React to geofence events
    • Notify users of geofence events

    为此,您将创建一个名为Geotify的基于位置的提醒应用程序,该应用程序使用户可以创建提醒并将其与实际位置相关联。

    打开入门项目。

    入门项目提供了一个简单的用户界面,用于在地图视图中添加和删除annotation items。 每个annotation item代表一个带有地理位置的提醒,称为geotification

    构建并运行该项目,您将看到一个空的地图视图。

    该应用程序的设置是为了让用户立即开始添加地理信息。

    1. Do You Know the Way to San Jose?

    点按导航栏中的+按钮以添加新的地理位置。 该应用程序将显示一个单独的视图,使您可以为地理化设置各种属性。

    在本教程中,您将在CupertinoApple Park中添加pin。 如果您不知道它在哪里,请打开此地图this map并使用它找到正确的位置。 请务必放大以使其准确!

    注意:要捏合以放大模拟器,请按住Option键,然后暂时按住Shift键以移动捏合中心,然后释放Shift并单击拖动以进行捏合。

    缩放并拖动到Cupertino中的正确位置后,地图就显示了这样。

    2. Say Hi to Tim

    半径Radius表示距iOS触发通知的指定位置的距离(以米为单位)。 Note可以是用户希望显示为通知一部分的任何消息。 该应用程序还允许用户(通过顶部的分段控件segmented control)指定在进入或退出定义的圆形地理围栏时是否应触发提醒。

    输入1000作为半径值,然后向Say Hi to Tim!作为note,并在第一次进入时将顶部开关留在Upon Entry位置。

    对所有值都满意后,请单击+。 您会在地图视图上看到地理化为新的annotation pin,并在其周围有一个圆圈,表示已定义的地理围栏:

    轻按图钉pin,您将显示之前设置的地理详细信息。 除非您要删除地理位置,否则不要点击垃圾桶按钮!

    随意添加或删除任意数量的地理标记。 由于该应用程序使用UserDefaults作为永久存储,因此地理分类列表将在两次启动之间保留。


    Setting Up Core Location

    至此,您添加到地图视图中的任何地理信息都是可见的;您实际上不会收到任何通知。 您可以通过进行每个地理定位并将其关联的地理围栏注册到Core Location中进行监控来解决此问题。

    但是在进行任何地理围栏监视之前,您需要设置一个CLLocationManager并请求适当的权限。

    打开GeotificationsViewController.swift并在geotifications声明后添加以下内容:

    lazy var locationManager = CLLocationManager()
    

    这将设置一个实例变量来存储location manager。 使用lazy表示第一次使用时才计算初始值。

    接下来,用以下代码替换`viewDidLoad()``:

    override func viewDidLoad() {
      super.viewDidLoad()
      // 1
      locationManager.delegate = self
      // 2
      locationManager.requestAlwaysAuthorization()
      // 3
      loadAllGeotifications()
    }
    

    以下是您在上面的代码中所做的操作的概述:

    • 1) 将视图控制器设置为locationManager的代理,以便视图控制器接收相关的代理方法调用。
    • 2) 调用requestAlwaysAuthorization(),该操作向用户显示提示,要求用户授权使用位置服务Always。具有地理围栏功能的应用需要Always authorization,因为即使应用未运行,它们也必须监视地理围栏。
    • 3) 调用loadAllGeotifications(),该方法反序列化保存到UserDefaults的地理列表,并将其加载到本地geotifications数组中。该方法还将geotifications作为annotations添加到地图视图上。

    1. Location Permissions

    用户可以向您的应用授予四级位置权限:

    • 1) Don’t Allow:用户已拒绝位置信息访问。
    • 2) Allow Once:用户将允许您的应用一次确定位置。
    • 3) Allow While Using App:只要应用程序位于前台,您的应用程序就可以确定位置。
    • 4) Always Allow:您的应用程序在后台时会收到位置更新,并能够确定在前台的位置。

    为了保护用户的隐私,即使您请求Always权限,该应用程序也只会在首次使用时提示Allow While Using App 。这将使您可以临时访问后台位置,并且在以后的某个时刻,当发生后台位置事件时,将要求用户确认他们要继续允许后台位置访问。

    该确认将在您无法控制的时间进行,并且可能在您的应用程序不在前台时进行。因此,重要的是要清楚地解释为什么您始终需要访问位置信息。您可以在Info.plistNSLocationAlwaysAndWhenInInUseUsageDescriptionNSLocationWhenInUseUsageDescription键下进行此操作。没有这些值,您的应用将不会请求位置访问权限。没有很好的解释,用户可能会拒绝位置权限。入门项目已经包含两个键的值。

    构建并运行。您会看到一个用户提示,其中包含来自Info.plist的描述:

    如上所述,点击Allow While Using App。 确保Precise仍处于On

    2. Showing the User’s Location

    在实施地理围栏之前,您需要解决一个小问题:用户的当前位置未显示在地图视图中! 默认情况下,地图视图会禁用此功能,因此,导航栏左上角的缩放按钮不起作用。

    幸运的是,修复并不困难-您在用户授权应用后即可启用当前位置。

    GeotificationsViewController.swift中,找到CLLocationManagerDelegate扩展并添加以下代码:

    
    func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
      // 1
      let status = manager.authorizationStatus
    
      // 2
      mapView.showsUserLocation = (status == .authorizedAlways)
    
      // 3
      if status != .authorizedAlways {
        let message = """
        Your geotification is saved but will only be activated once you grant
        Geotify permission to access the device location.
        """
        showAlert(withTitle: "Warning", message: message)
      }
    }
    

    每当位置授权状态更改以及首次创建location manager时,都会调用此方法。 此实现执行以下操作:

    • 1) 从管理器检索授权状态。
    • 2) 授权authorizedAlways时显示用户位置,这是对此应用程序唯一有用的模式。
    • 3) 如果用户未授权该应用,则会显示一条message alertshowAlert(withTitle:message :)Utilities.swift中的一个辅助方法,该方法带有标题和消息并显示alert视图。

    构建并运行。 如果您正在设备上运行该应用,则会在主地图视图中看到位置标记。 如果您在模拟器上运行,请在菜单中单击Features ▸ Location ▸ Apple以查看位置标记:

    导航栏上的缩放按钮现在也可以使用。


    Registering the Geofences

    配置location manager后,您现在必须允许您的应用注册用户地理围栏以进行监视。

    1. How Geofencing Works

    地理围栏或Apple所称的区域监视(region monitoring)需要设置一个圆圈来进行监视。 这被定义为CLCircularRegion,具有中心坐标和半径(以米为单位)。

    该设备可以监听用户进入和/或退出圆形围栏区域的情况。 当用户从圆圈外移动到圆圈内时,将触发进入事件。

    用户离开圈子时会触发退出事件。

    如果满足以下条件,则调用location manager回调:

    • 该设备能够监视位置。
    • 监视条件足以解决一个区域-GPSWi-Fi,充足的电池和其他硬件考虑因素的完美结合。
    • 用户已启用位置服务。
    • 用户已授予Always位置权限并具有精确的监视。
    • 该应用程序无法监视超过20个区域。

    该应用程序将用户地理围栏信息存储在您的自定义Geotification模型中。 但是要监视地理围栏,Core Location要求您将每个围栏表示为一个CLCircularRegion实例。 为了解决这个问题,您将创建一个帮助程序方法,该方法从给定的Geotification对象返回CLCircularRegion

    2. Creating Regions

    打开Geotification.swift并将以下方法添加到文件底部的空扩展名中:

    var region: CLCircularRegion {
      // 1
      let region = CLCircularRegion(
        center: coordinate,
        radius: radius,
        identifier: identifier)
    
      // 2
      region.notifyOnEntry = (eventType == .onEntry)
      region.notifyOnExit = !region.notifyOnEntry
      return region
    }
    

    上面的代码是这样的:

    • 1) 它使用地理围栏的位置,地理围栏的半径和一个标识符(该标识符可以使iOS区分给定应用的已注册地理围栏)来初始化CLCircularRegion。 初始化非常简单,因为模型已经包含了必需的属性。
    • 2) CLCircularRegion还具有两个布尔属性:notifyOnEntrynotifyOnExit。 这些标志分别指定在设备进入或离开定义的地理围栏时触发地理围栏事件。 由于您将应用程序设计为每个地理围栏只允许一种通知类型,因此请根据存储在geotification对象中的eventType值将其中一个标志设置为true,将另一个标志设置为false

    接下来,您需要一种方法,只要用户添加地理信息,就可以开始监视该地理信息geotification

    3. Monitoring Regions

    打开GeotificationsViewController.swift并将以下方法添加到GeotificationsViewController的主体中:

    func startMonitoring(geotification: Geotification) {
      // 1
      if !CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self) {
        showAlert(
          withTitle: "Error",
          message: "Geofencing is not supported on this device!")
        return
      }
    
      // 2
      let fenceRegion = geotification.region
      // 3
      locationManager.startMonitoring(for: fenceRegion)
    }
    

    以下是此方法的概述:

    • 1) isMonitoringAvailableForClass(_ :)确定设备是否具有支持监视地理围栏所需的硬件。 如果无法进行监视,请纾困并alert用户。
    • 2) 使用先前定义的帮助程序方法,根据给定的地理位置创建一个CLCircularRegion实例。
    • 3) 向Core Location注册CLCircularRegion实例,以通过CLLocationManager进行监视。

    注意:如果iOS检测到边界交叉,则会触发地理围栏事件。 如果用户在注册时已经在地理围栏内,则iOS不会生成事件。 如果您需要查询设备位置在给定地理围栏之内还是之外,CLLocationManager有一个名为requestStateForRegion(_ :)的方法。

    完成start方法后,您还需要一种在用户将其从应用程序中删除时停止监视给定地理记录的方法。

    GeotificationsViewController.swift中,在startMonitoring(geotificiation :)下面添加以下方法:

    func stopMonitoring(geotification: Geotification) {
      for region in locationManager.monitoredRegions {
        guard 
          let circularRegion = region as? CLCircularRegion, 
          circularRegion.identifier == geotification.identifier 
        else { continue }
    
        locationManager.stopMonitoring(for: circularRegion)
      }
    }
    

    该方法指示locationManager停止监视与给定地理位置关联的CLCircularRegion

    4. Adding Geotifications

    现在,开始和停止方法均已完成,因此无论何时添加或删除地理位置,都将使用它们。 您将从添加部分开始。

    首先,查看GeotificationsViewController.swift中的addGeotificationViewController(_:didAddGeotification :)

    这是AddGeotificationViewController在创建地理化时调用的委托方法。 它负责创建新的Geotification对象,并相应地更新地图视图和Geotifications列表。 它调用saveAllGeotifications(),它获取更新的地理geotifications列表并通过UserDefaults持久保存。

    现在,将addGeotificationViewController(_:didAddGeotification :)替换为以下内容:

    func addGeotificationViewController(
      _ controller: AddGeotificationViewController,
      didAddGeotification geotification: Geotification
    ) {
      controller.dismiss(animated: true, completion: nil)
    
      // 1
      geotification.clampRadius(maxRadius:
        locationManager.maximumRegionMonitoringDistance)
      add(geotification)
    
      // 2
      startMonitoring(geotification: geotification)
      saveAllGeotifications()
    }
    

    您已对代码进行了两个关键更改:

    • 1)您确保半径值不超过locationManagermaximumRegionMonitoringDistance属性,该属性定义地理围栏的最大半径(以米为单位)。 这很重要,因为任何超过此最大值的值都将导致监视失败。
    • 2)您可以调用startMonitoring(geotification :)Core Location中注册新添加的geotification对象以进行监视。

    此时,该应用程序可以注册新的地理围栏以进行监视。 但有一个限制:由于地理围栏是共享的系统资源,因此Core Location将已注册地理围栏的数量限制为每个应用最多20个。

    尽管有解决方法,但在本教程中,您将采用限制用户可以添加的地理位置数量的方法。

    将以下内容添加到updateGeotificationsCount()的末尾:

    navigationItem.rightBarButtonItem?.isEnabled = (geotifications.count < 20)
    

    每当应用程序达到限制时,此行就会禁用导航栏中的Add按钮。

    5. Removing Geotifications

    现在,您需要处理地理化的移除。 您将在mapView(_:annotationView:calloutAccessoryControlTapped :)中处理此功能,只要用户在annotation上点击delete附件控件,就会调用该函数。

    mapView(_:annotationView:calloutAccessoryControlTapped :)中,在remove(geotification)之前,添加以下内容:

    stopMonitoring(geotification: geotification)
    

    这将停止监视与地理化关联的地理围栏,然后再将其删除并将更改保存到UserDefaults

    在这一点上,您的应用程序可以监视和取消监视用户地理围栏。 欢呼!

    构建并运行。 您将看不到任何更改,但是应用程序现在可以注册地理围栏区域以进行监视。 但是,它还无法对任何地理围栏事件做出反应。 不用担心-这是下一个业务!


    Reacting to Geofence Events

    当用户进入或离开地理围栏区域时,您的应用程序可能正在前台运行,在后台运行或根本不运行! 您必须应对所有这些可能性。

    1. Handling Location Errors

    您将首先实现一些委托方法以简化错误处理。 如果发生任何问题,添加这些信息很重要。

    GeotificationsViewController.swift中,将以下方法添加到CLLocationManagerDelegate

    func locationManager(
      _ manager: CLLocationManager,
      monitoringDidFailFor region: CLRegion?,
      withError error: Error
    ) {
      guard let region = region else {
        print("Monitoring failed for unknown region")
        return
      }
      print("Monitoring failed for region with identifier: \(region.identifier)")
    }
    
    func locationManager(
      _ manager: CLLocationManager, 
      didFailWithError error: Error
    ) {
      print("Location Manager failed with the following error: \(error)")
    }
    

    这些委托方法记录location manager遇到的任何错误,以方便您进行调试。

    注意:您肯定会在生产应用程序中更强大地处理这些错误。 例如,您可以通知用户出了什么问题,而不是无声地失败。

    2. Handling Location Events

    接下来,您将添加代码以监听和响应地理围栏的进入和退出事件。

    打开SceneDelegate.swift并在文件顶部添加以下行以导入CoreLocation框架:

    import CoreLocation
    

    var window: UIWindow?下面添加新属性:

    let locationManager = CLLocationManager()
    

    然后添加以下方法。 当场景被激活时被调用:

    func scene(
      _ scene: UIScene,
      willConnectTo session: UISceneSession,
      options connectionOptions: UIScene.ConnectionOptions
    ) {
      locationManager.delegate = self
      locationManager.requestAlwaysAuthorization()
    }
    

    您已经设置了SceneDelegate来接收与地理围栏相关的事件。忽略错误Xcode将在此处显示;您很快就会解决。但是您可能会想:“为什么我指定SceneDelegate代替view controller来执行此操作?”

    iOS始终监控应用程序注册的地理围栏,包括应用程序未运行时。如果设备在应用程序未运行时触发地理围栏事件,则iOS会在后台重新启动应用程序。这使得SceneDelegate成为处理事件的理想入口点,因为可能未加载或未准备好视图控制器。

    现在您可能还想知道,“新创建的CLLocationManager实例如何知道受监视的地理围栏?”

    事实证明,应用程序中注册的所有地理围栏都可以由应用程序中的所有location managers方便地访问,因此初始化location managers的位置无关紧要。很对吧?

    3. Comings and Goings

    现在剩下的就是实现相关的委托方法来对地理围栏事件做出反应。要接收这些事件,请在SceneDelegate.swift中添加以下扩展名:

    // MARK: - Location Manager Delegate
    extension SceneDelegate: CLLocationManagerDelegate {
      func locationManager(
        _ manager: CLLocationManager,
        didEnterRegion region: CLRegion
      ) {
        if region is CLCircularRegion {
          handleEvent(for: region)
        }
      }
    
      func locationManager(
        _ manager: CLLocationManager,
        didExitRegion region: CLRegion
      ) {
        if region is CLCircularRegion {
          handleEvent(for: region)
        }
      }
    
      func handleEvent(for region: CLRegion) {
        print("Geofence triggered!")
      }
    }
    

    正如方法名称所示那样,当设备进入CLRegion时,您将收到locationManager(_:didEnterRegion :);当设备退出CLRegion时,您将收到locationManager(_:didExitRegion :)

    两种方法都接收到有问题的CLRegion。您必须确保它是一个CLCircularRegion,因为如果您的应用程序也恰巧在监视iBeacon,则它可能是CLBeaconRegion。如果该区域确实是CLCircularRegion,则调用handleEvent(for :)

    此时,handleEvent(_ :)接受一个CLRegion并记录一条语句。不用担心-您稍后将实现事件处理。

    4. Simulating Location Events

    既然您的应用程序已经能够接收地理围栏事件,您就可以对其进行(也许是字面意义上的)测试运行了。如果那没有让您兴奋,那应该会,因为在本教程中第一次,您将看到一些结果。

    测试应用程序最准确的方法是将其部署在设备上,添加一些地理标记,然后将应用程序带着走步或开车。但是,现在这样做是不明智的,因为在拔下设备后您将无法验证地理围栏事件发出的打印日志。此外,在您承诺试用该应用程序之前,最好能确保该应用程序能够正常工作。

    幸运的是,有一种简单的方法可以在不离开家中的情况下完成此操作。 Xcode允许您在项目中包含硬编码的航点GPX文件,可用于模拟测试位置。入门项目为您提供此项方便。

    打开SimulatedLocations.gpx(可在Supporting Files组中找到),并检查其内容。

    您会看到以下内容:

    <?xml version="1.0"?>
    <gpx version="1.1" creator="Xcode">
      <wpt lat="37.3349285" lon="-122.011033">
        <name>Apple</name>
        <time>2014-09-24T14:00:00Z</time>
      </wpt>
      <wpt lat="37.422" lon="-122.084058">
        <name>Google</name>
        <time>2014-09-24T14:00:05Z</time>
      </wpt>
    </gpx>
    

    GPX文件本质上是一个XML文件,其中包含两个航点:位于Mountain ViewGoogleGoogleplex和位于CupertinoApple Park。 您会注意到每个航路点上都有时间节点。 它们之间的间隔为五秒钟,因此,当您使用此文件模拟位置时,AppleGoogle之间将需要五秒钟的时间。 还有另外两个GPX文件:Google.gpxApple.gpx。 这些是固定的位置,在创建地理围栏时可以方便使用。

    5. Going on an Imaginary Drive

    要开始模拟GPX文件中的位置,请构建并运行项目。 当应用启动主视图控制器时,返回Xcode,在Debug bar中选择Location图标,然后选择SimulatedLocations

    返回应用程序,使用导航栏左上角的缩放按钮缩放到当前位置。 靠近该区域后,您会看到位置标记从Googleplex移到Apple Park,然后又移回。

    通过沿着两个航路点定义的路径添加一些地理栅栏来测试应用程序。 如果在启用地理栅栏注册之前在本教程的前面添加了任何地理标记,则这些地理栅栏将不起作用,因此您可能需要清除它们并重新开始。

    对于测试位置,最好在每个航路点大致放置一个地理位置。 这是一个可能的测试方案:

    • GoogleRadius: 1000m, Message: "Say Bye to Google!", Notify on Exit
    • AppleRadius: 1000m, Message: "Say Hi to Apple!", Notify on Entry

    注意:使用提供的其他测试位置可以轻松添加位置。

    添加地理标记后,每次位置标记进入或离开地理围栏时,您都会在控制台中看到一条日志。 如果您激活主屏幕按钮或锁定屏幕以将应用程序发送到后台,那么即使设备无法通过地理围栏,您也将看到日志,尽管您无法验证该行为。


    Notifying the User of Geofence Events

    您在使用该应用程序方面取得了很大进步。 现在,您需要在设备越过地理化的地理围栏时通知用户。

    若要获取与委托调用返回的触发CLCircularRegion关联的注释,您需要检索UserDefaults中保留的相应地理位置。 事实证明这很简单,因为您可以在注册过程中使用分配给CLCircularRegion的唯一标识符来查找正确的地理位置。

    SceneDelegate.swift中,在SceneDelegate的底部添加以下帮助程序方法:

    func note(from identifier: String) -> String? {
      let geotifications = Geotification.allGeotifications()
      let matched = geotifications.first { $0.identifier == identifier }
      return matched?.note
    }
    

    此辅助方法根据其标识符从持久性存储中检索地理化,并返回该地理化的注释。

    现在,您可以检索与地理围栏相关的注释(note),您将编写代码以在地理围栏事件触发时触发通知,并将该注释用作消息。

    首先,您需要获得发送用户通知的权限,您可以在应用启动时执行此操作。 打开AppDelegate.swift并将以下方法添加到AppDelegate

    func application(
      _ application: UIApplication,
      didFinishLaunchingWithOptions 
        launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
    ) -> Bool {
      let options: UNAuthorizationOptions = [.badge, .sound, .alert]
      UNUserNotificationCenter.current()
        .requestAuthorization(options: options) { _, error in
          if let error = error {
            print("Error: \(error)")
          }
        }
      return true
    }
    

    此方法请求授权以使用用户通知,并在触发位置事件时显示badgesoundalert。 现在,它记录是否有错误。

    接下来,添加以下方法:

    func applicationDidBecomeActive(_ application: UIApplication) {
      application.applicationIconBadgeNumber = 0
      UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
      UNUserNotificationCenter.current().removeAllDeliveredNotifications()
    }
    

    每当应用程序激活时,它就会清除所有现有通知,从而进行一些内部整理。

    1. Building the Notification

    接下来,返回SceneDelegate.swift并将handleEvent(for :)替换为以下内容:

    func handleEvent(for region: CLRegion) {
      // Show an alert if application is active
      // 1
      if UIApplication.shared.applicationState == .active {
        guard let message = note(from: region.identifier) else { return }
        window?.rootViewController?.showAlert(withTitle: nil, message: message)
      } else {
        // Otherwise present a local notification
        // 2
        guard let body = note(from: region.identifier) else { return }
        let notificationContent = UNMutableNotificationContent()
        notificationContent.body = body
        notificationContent.sound = .default
        notificationContent.badge = UIApplication.shared
          .applicationIconBadgeNumber + 1 as NSNumber
        // 3
        let trigger = UNTimeIntervalNotificationTrigger(
          timeInterval: 1, 
          repeats: false)
        let request = UNNotificationRequest(
          identifier: "location_change",
          content: notificationContent,
          trigger: trigger)
        UNUserNotificationCenter.current().add(request) { error in
          if let error = error {
            print("Error: \(error)")
          }
        }
      }
    }
    

    这是上面的代码中发生的事情:

    • 1) 如果该应用程序处于活动状态,请显示alert视图以通知用户。
    • 2) 如果该应用程序未处于活动状态,请从地理位置获取文本,然后构建本地通知。
    • 3) 发送请求以显示本地通知。

    构建并运行,接受通知权限,然后运行上一部分中介绍的测试过程。 每当您的测试触发地理围栏事件时,您都会看到一个alert controller显示提醒note

    在测试运行期间,通过激活主页按钮或锁定设备将应用程序发送到后台。 您将继续定期接收有关地理围栏事件的通知:

    这样一来,您手中就会有一个功能齐全的基于位置的提醒应用程序。 是的,走出去,并试用该应用程序吧!

    注意:在测试应用程序时,您可能会遇到通知无法在边界点准确触发的情况。

    这是因为在iOS考虑跨越边界之前,必须穿越一个额外的缓冲距离,并且该设备必须在新位置停留的最短时间段。 iOS内部定义了这些阈值,以减轻用户在靠近地理围栏边界的情况下虚假触发通知的情况。

    此外,这些阈值似乎受可用的定位硬件功能的影响。 当设备上启用Wi-Fi时,地理围栏行为似乎更加准确。

    地理围栏是一项功能强大的技术,在市场营销,资源管理,安全性,父母控制甚至游戏等领域具有许多实用且影响深远的应用程序。 您可以实现的取决于您的想象力。 您可以阅读 Apple's Region Monitoring以了解更多信息。

    通过我们的 MapKit pro courseMapKit and Core Location video course了解更多信息!

    后记

    本篇主要讲述了基于Core Location地理围栏的实现,感兴趣的给个赞或者关注~~~

    相关文章

      网友评论

          本文标题:CoreLocation框架详细解析(十六) —— 基于Core

          本文链接:https://www.haomeiwen.com/subject/kgfdgktx.html