【问题标题】:Location based iphone app not working in background after updating to iOS 9.3.1 and above更新到 iOS 9.3.1 及更高版本后,基于位置的 iphone 应用程序无法在后台运行
【发布时间】:2016-06-01 10:44:21
【问题描述】:

我创建了一个应用程序,即使应用程序在后台或屏幕被锁定,它也会跟踪用户的位置。我已经在装有 iOS 9.2 的 iPhone 5s 设备上对其进行了测试,一切正常。更新到 iOS 9.3.1 后,我注意到应用程序会在后台运行大约 10 分钟,然后应用程序会自动停止。我昨天将手机更新到 iOS 9.3.2,希望能解决这个问题。但是问题仍然存在。

我在 AppDelegate 类中有以下代码

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

  var window: UIWindow?
  private static var backgroundService : BackgroundService? = nil
  var startServices : Bool = false
  public static var bgTask = UIBackgroundTaskIdentifier()

  func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    print("didFinishLaunchingWithOptions")

    AppDelegate.bgTask = beginBackgroundUpdateTask()
    startBackgroundService()
    return true
  }

  internal func startBackgroundService(){
    if AppDelegate.backgroundService == nil{
      AppDelegate.backgroundService = BackgroundService.getBackgroundService()
    }
    AppDelegate.backgroundService!.startService(self)
  }

  internal func stopBackgroundService(){
    AppDelegate.backgroundService!.stopService()
  }

  func beginBackgroundUpdateTask() -> UIBackgroundTaskIdentifier {
    return UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({})
  }

  func applicationDidEnterBackground(application: UIApplication) {
    self.startBackgroundService()
    print("applicationDidEnterBackground")
  }
}

已为 iphone 上的应用启用后台应用刷新和定位服务。 Info.plist 中已启用后台模式并添加了其他所需权限。

问题不是由于任何代码更改,因为我在另一部装有 iOS 9.2 的手机上测试了代码,它运行良好。将第二部手机更新到 iOS 9.3.2 后,发生了同样的问题。 9.3 中是否有任何更改导致此问题?我浏览了变更日志和文档,但找不到任何有用的东西。有没有其他人遇到过类似的问题?是否需要进行任何更改以确保该应用与 iOS 9.3 兼容?

【问题讨论】:

  • 我怀疑苹果已经收紧了后台处理。使用backgroundTaskWithExpirationHandler不是在后台获取位置更新的正确方法。
  • @Paulw11 - 您能否建议在后台获取更新的正确方法是什么?我是 iOS 开发新手,backgroundTaskWithExpirationHandler 是我设法让它在后台工作的唯一方法。
  • 您是否使用后台模式进行位置更新?
  • @Ahmed - 是的,位置更新的后台模式已启用。
  • 您是否在后台模式下对其进行了多次测试?

标签: ios iphone swift


【解决方案1】:

终于解决了这个问题。按照建议添加locationManager.allowsBackgroundLocationUpdates = true 后,问题仍然存在。虽然它在后台运行了更长的时间,但在某个时间点之后,应用程序停止获取位置数据。

在网上搜索了更多之后,我发现了这个设置

locationManager.pausesLocationUpdatesAutomatically = false

添加此行解决了该问题,并且位置获取在后台工作而不会突然停止。它的默认值为 true。

正如@Ahmed 和@Chajmz 所述,iOS 9 及更高版本需要allowBackgroundLocationUpdates

在 iOS 9 及更高版本中,无论部署目标如何,您还必须将位置管理器对象的 allowedBackgroundLocationUpdates 属性设置为 YES 才能接收后台位置更新。默认情况下,此属性为 NO,并且在您的应用主动需要后台位置更新之前,它应该保持这种状态。

根据有关 CLLocationManager - pausesLocationUpdatesAutomatically的文档

允许位置管理器暂停更新可以在不牺牲位置数据的情况下延长目标设备的电池寿命。当此属性设置为 true 时,位置管理器会在位置数据不太可能更改时暂停更新(并关闭适当的硬件)。例如,如果用户在使用导航应用时停下来吃东西,位置管理器可能会暂停更新一段时间。

该属性的默认值为true。

【讨论】:

  • @Nilesh - 您需要在初始化 locationManager 的任何位置添加这两行。
【解决方案2】:

从 iOS 9 开始,您可以避免使用 backgroundTaskWithExpirationHandler,如果您想从您的 LocationManager 持续访问您的数据,您可以使用 allowsBackgroundLocationUpdates 但是,如果您在后台停止您的 LocationManager,您将不会无法从后台重新启动它。

if #available(iOS 9.0, *) {
     manager.allowsBackgroundLocationUpdates = true
 } else {
      // Fallback on earlier versions
 }

【讨论】:

  • 只要在前台启动了重要的位置更新就可以重新启动
猜你喜欢
  • 1970-01-01
  • 2019-04-18
  • 2012-04-20
  • 1970-01-01
  • 1970-01-01
  • 2020-02-19
  • 1970-01-01
  • 1970-01-01
  • 2021-08-05
相关资源
最近更新 更多