在Swift中每30分钟发送一次位置更新

我有位置服务的背景模式,并且每30分钟发送一次位置(经度和纬度)到服务器。 现在我在控制台上打印相同的内容。 它似乎工作了一段时间,但我想知道如何在这种情况下与NSTimer工作。 我应该从哪里调用它?

import UIKit import CoreLocation @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate { var window: UIWindow? var locationManager = CLLocationManager() func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after application launch. return true } func applicationWillResignActive(application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } func applicationDidEnterBackground(application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. self.locationManager.delegate = self self.locationManager.startUpdatingLocation() // I know i should be using signification location option here. this is just for testing now. } func locationManager(manager: CLLocationManager!, didUpdateToLocation newLocation: CLLocation!, fromLocation oldLocation: CLLocation!) { self.sendBackgroundLocationToServer(newLocation); } func sendBackgroundLocationToServer(location: CLLocation) { var bgTask = UIBackgroundTaskIdentifier() bgTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler { () -> Void in UIApplication.sharedApplication().endBackgroundTask(bgTask) } println(location.coordinate.latitude) if (bgTask != UIBackgroundTaskInvalid) { UIApplication.sharedApplication().endBackgroundTask(bgTask); bgTask = UIBackgroundTaskInvalid; } } func applicationWillEnterForeground(application: UIApplication) { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. application.beginBackgroundTaskWithExpirationHandler{} } func applicationDidBecomeActive(application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. application.beginBackgroundTaskWithExpirationHandler{} } func applicationWillTerminate(application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. application.beginBackgroundTaskWithExpirationHandler{} } } 

也许调用application.beginBackgroundTaskWithExpirationHandler{}是一个坏主意? 我可以在这里跟什么select?

beginBackgroundTask...的想法是启动一个有限长度的任务,以便如果用户离开应用程序,它将继续在后台任务中运行一段有限的时间(3分钟,我相信)。 在时间用完之前,你必须调用endBackgroundTask ,否则应用程序将被立即终止。

所以,不幸的是,后台任务机制并不适合你所期望的意图。 但是,有一组窄的特殊背景模式,devise用于在一组狭窄的function(VOIP,audio等)之外的后续操作。 有关更多信息,请参阅iOS应用程序编程指南的实现长时间运行任务部分:后台执行 。

现在,其中一种背景模式是“位置”服务。 所以,如果这是你的应用程序的核心function,对于正确的function是必不可less的,那么你可以注册location背景模式,你的应用程序将继续在后台运行。 从那里,你可以监视位置更新,如果足够的时间已经过去,触发一些过程。 但是,如果这种背景位置模式不是您的应用程序的基本function,苹果可能会拒绝您的应用程序请求一个不需要的背景模式。


顺便说一下,你应该知道,开始标准的位置服务可能会耗尽设备电池。 您可能会考虑使用电池效率“重大变化”的位置服务 。 每当用户移动一些显着的距离时(例如以公里为单位测量,我相信它是由移动到不同的手机塔触发的),这也具有自动唤醒您的应用程序的优点。

几个笔记,因为我们一直在处理位置问题,并与后台应用程序挣扎,似乎没有唤醒我们。

  1. 只要你的应用程序没有被暂停,NSTimer就是好的。 当然,它是在后台,但只有它可以从iOS(APN,位置…)接收通知。 最后,当你在BG中跑步时,你的计时器将停止发射。 所以,你依靠BG模式之一踢你。

  2. 如果你正在使用CLLocationManager.startUpdatingLocation,你会注意到你放弃了这些之后。 特别是当电话放松,并尝试睡觉。 这是因为一个称为CLLocationManager.pausesLocationUpdatesAutomatically的logging不完善的特性,当它设置为“true”(默认设置)时,决定停止发送这些特性。 您可以将其设置为“false”,并且您将继续获取您的位置更新。 这几乎可以确保你的应用程序做你想要的。

  3. 如上所述,您必须确保何时获取您的locationManager.didUpdateLocationscallback函数,以便在处理该信息并发送networking数据时开始执行backgroundTask以保持应用程序正常工作。 但你似乎明白这一点。

  4. 刚刚醒来足以“logging”位置更新并不是那么糟糕。 只要确保你没有产生你的networking代码,除非你已经明确地打了你30分钟的期望。

尝试这个:

  • 为位置服务制作一个单身人士。 注册一个NSNotification
  • AppDelegatewillEnterBackGround ,你通过NSNotificationCenter发送一个通知

那么,你的单身人士将开始updatingLocation位置,并在收到位置数据时将其发送到服务器。