【问题标题】:Starting locations updates after enter beacon region monitored Swift进入信标区域后开始位置更新监控 Swift
【发布时间】:2019-11-15 09:52:07
【问题描述】:

当用户进入该区域时,我正在制作一个带有位置更新的 ibeacon 区域监控应用程序(应用程序不在前台)。此位置更新必须配置为 kCLLocationAccuracyBestForNavigation 精度(因为我必须在使用保持在该区域时进行跟踪, 订阅我的重大变化是不够的)。一切正常,但 20 秒后(有时 1 分钟以上)我停止接收位置更新。我将所有键都放在 info.plist 中以始终使用位置,我在功能部分中包含后台模式,并在后台更新位置。

我使用不同的配置配置 locationManager,并且 SO 总是停止我的位置更新。我正在使用 IOS 12 和 Iphone 7 进行测试。

我配置CLLocationManager的方式:

self.locationManager.desiredAccuracy
=kCLLocationAccuracyBestForNavigation
self.locationManager.activityType = .automotiveNavigation
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.delegate = self
self.locationManager.allowsBackgroundLocationUpdates = true
self.locationManager.pausesLocationUpdatesAutomatically = false

开始位置更新(当用户进入 Ibeacon 区域时):

func beaconManager(_ manager: KTKBeaconManager, didEnter region: 
KTKBeaconRegion) {



    self.locationManager.startUpdatingLocation()


}

最后,在 didUpdate 位置我调用了一个网络服务:

func locationManager(_ manager: CLLocationManager, 
didUpdateLocations locations: [CLLocation]) {

    //Call web service using alamofire

}

我寻求您的帮助,以了解我是否为我想要执行的目的正确执行了设置,以及任何可以让我知道操作系统为什么会终止我获取位置更新的进程的线索

【问题讨论】:

    标签: ios swift core-location beacon region-monitoring


    【解决方案1】:

    在 iOS 的后台定期获取位置更新很棘手。操作系统旨在防止应用在后台持续运行以优化电池使用,并在一段时间后暂停应用,除非您有几件事完全正确。

    你需要做三件事:

    1. 您必须获得用户的“始终获取位置”权限(正如您所说的那样)。

    2. 您必须将以下条目添加到您的 Info.plist。这将允许您的应用程序在后台无限期运行,但是如果您希望将您的应用程序提交到 App Store,此条目还将向审阅者声明它是一个后台位置应用程序,您需要说服他们它提供对用户的基于位置的好处,并且用户知道这种好处。

     <key>UIBackgroundModes</key>
     <array>
         <string>location</string>
     </array>
    
    1. 您必须维护一个后台线程才能使您的应用程序保持活动状态。你是否真的在这个后台线程中做任何事情都没有关系。只要让它处于活动状态,iOS 就不会暂停您的应用。
      var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskIdentifier.invalid
    
      func extendBackgroundRunningTime() {
        if (backgroundTask != UIBackgroundTaskIdentifier.invalid) {
          // already started
          return
        }
        NSLog("Attempting to extend background running time")
    
        self.backgroundTask = UIApplication.shared.beginBackgroundTask(withName: "DummyTask", expirationHandler: {
          NSLog("Background task expired by iOS.  Cannot run again until a new beacon region event")
          UIApplication.shared.endBackgroundTask(self.backgroundTask)
          self.backgroundTask = UIBackgroundTaskIdentifier.invalid
        })
    
        DispatchQueue.global().async {
          while (true) {
            let backgroundTimeRemaining = UIApplication.shared.backgroundTimeRemaining
            // This will be a very large number if you have proper permissions
            // If not, it will generally count down from 10 seconds once you are in the
            // background until iOS suspends your app.
            NSLog("Thread background time remaining: \(backgroundTimeRemaining)")
            Thread.sleep(forTimeInterval: 1.0)
          }
        }
      }
    

    【讨论】:

    • 非常感谢大卫!我已经指出答案是正确的,因为使用您的代码,您可以在操作系统终止进程之前获得最长的执行时间。万一有人需要这个功能,我终于通过使用 David 的代码以及订阅圆形区域内外的事件实现了良好的性能
    猜你喜欢
    • 1970-01-01
    • 2015-02-07
    • 1970-01-01
    • 2012-03-07
    • 1970-01-01
    • 1970-01-01
    • 2019-02-11
    • 2017-08-09
    • 2014-08-09
    相关资源
    最近更新 更多