即使手机在swift中重新启动后,如何在后台获取位置?

我正在开发一个应用程序跟踪用户select的时间间隔的电话位置。 我用定时器启动了startUpdatingLocation ,当它得到位置停止更新时,将位置发送到服务器并再次启动定时器。 一切都在后台完成。 即使手机重新启动并将数据发送到服务器,我也需要在后台模式(iOS 8中)中获取位置数据。 我尝试了数百种方法,没有人为我工作。 所以…我现在得到了什么:在info.plist:

  • 所需的背景模式 – 位置和获取
  • NSLocationAlwaysUsageDescription – 位置是需要此应用程序正常工作

在AppDelegate中:

  var locationController: LocationController = LocationController() as LocationController; func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool { UIApplication.sharedApplication().setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum); var bgTask = UIBackgroundTaskIdentifier() bgTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler { () -> Void in UIApplication.sharedApplication().endBackgroundTask(bgTask) } if(self.locationController.profileForTracking != nil && self.locationController.profileForTracking != "Disabled" && self.locationController.intervalForTracking != nil && self.locationController.trackingAllowed == true){ self.locationController.initLocationManager(); if(self.locationController.timer != nil){ self.locationController.timer = self.locationController.timer; } else { self.locationController.startTimerForLocationUpdate(); } println("Location can now start ...."); } return true } func application(application: UIApplication!, performFetchWithCompletionHandler completionHandler: ((UIBackgroundFetchResult) -> Void)!) { var bgTask = UIBackgroundTaskIdentifier() bgTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler { () -> Void in UIApplication.sharedApplication().endBackgroundTask(bgTask) } if(self.locationController.profileForTracking != nil && self.locationController.profileForTracking != "Disabled" && self.locationController.intervalForTracking != nil && self.locationController.trackingAllowed == true){ self.locationController.initLocationManager(); if(self.locationController.timer != nil){ self.locationController.timer = self.locationController.timer; } else { self.locationController.startTimerForLocationUpdate(); } println("Location can now start ...."); } } 

一切似乎工作(当应用程序在前台或后台/不活动),除非手机重新启动或用户终止应用程序。 我认为我做错了事,iOS不会唤醒应用程序。 我怎么做,如果我能做到这一点,有办法让用户select的时间段(30分钟,1小时…)。 提前致谢!

在移动到后台或应用程序终止时调用此方法

 startMonitoringSignificantLocationChanges(); 

所以,如果你重新启动你的设备或应用程序被杀死,只要你的位置有重大的位置变化,操作系统将在后台启动你的应用程序。

根据苹果文件

如果您启动此服务,并且您的应用程序随后终止,则系统会在新事件到达时自动将应用程序重新启动到后台。 在这种情况下,传递给应用程序的选项字典:willFinishLaunchingWithOptions:和application:didFinishLaunchingWithOptions:您的应用程序委托的方法包含键UIApplicationLaunchOptionsLocationKey,表示您的应用程序是由于位置事件而启动的。 重新启动后,您仍然必须configuration一个位置pipe理器对象并调用此方法来继续接收位置事件。 当您重新启动位置服务时,当前事件会立即传送到您的委托。 另外,即使在启动位置服务之前,您的位置pipe理器对象的位置属性也会填入最近的位置对象。

你想要的不再是可能的。 从iOS7开始,应用程序只能在后台保持活动状态,以便在用户 (而不是系统)(例如,通过重大的位置更改事件)将其发送到前台时接收位置信息。 这个变化在WWDC13的一次会谈中被简要地提到,可能是题为“核心位置的新变化”的那个。

我有一个这个function的应用程序,它打破了iOS7。 我与苹果开发者支持交谈,他们证实了这一变化。 我正在研究的这个项目是一个针对学术研究的起源 – 目的地调查; 我们的解决scheme最终是保留一组本地通知,并在运行时定期更新未来的火灾时间; 如果我们停止运行,用户会收到通知重新启动应用程序。

同样要注意的是,如果您告诉核心位置停止更新您的位置,您将无法重新打开它,直到用户再次将其放到前台。 我们在这里使用的解决scheme是延迟位置更新的组合,并将“期望的精确度”向上调整,以便在没有必要时手机不打开GPS或wifi天线的电源。 这显然不是很理想,但是我的电池性能已经devise得更合理了。