我正在寻找一种在iOS应用程序中每n分钟更新一次后台位置的方法.我正在使用iOS 4.3,该解决方案适用于非越狱的iPhone.
我尝试/考虑了以下选项:
CLLocationManager startUpdatingLocation/startMonitoringSignificantLocationChanges:这根据预期在后台工作,基于配置的属性,但似乎不可能强制它每n分钟更新一次位置NSTimer:当应用程序在前台运行但似乎不是为后台任务设计时,是否有效UIApplication:beginBackgroundTaskWithExpirationHandler:据我所知,当应用程序移动到后台而不是实现"长时间运行"的后台进程时,这应该用于在后台完成一些工作(也限制时间).如何实施这些常规后台位置更新?
这是CLLocationManager文档中描述使用startMonitoringSignificantLocationChanges的应用程序行为的部分:
如果您启动此服务并且您的应用程序随后终止,则系统会在新事件到达时自动将应用程序重新启动到后台.在这种情况下,传递给应用程序的选项字典:didFinishLaunchingWithOptions:应用程序委托的方法包含密钥UIApplicationLaunchOptionsLocationKey,以指示您的应用程序是由于位置事件而启动的.重新启动后,您仍必须配置位置管理器对象并调用此方法以继续接收位置事件.重新启动位置服务时,会立即将当前事件传递给您的代理.此外,即使在启动位置服务之前,也会使用最新的位置对象填充位置管理器对象的位置属性.
所以我的理解是,如果你的应用程序终止(并假设你没有从applicationWillTerminate调用stopMonitoringSignificantLocationChanges),你将会被应用程序唤醒UIApplicationLaunchOptionsLocationKey参数:didFinishLaunchingWithOptions.此时,您将创建CLLocationManager,调用startMonitoringSignificantLocationChanges并在有限时间内执行后台位置处理.这一点我很好.
前一段只谈到应用程序终止时会发生什么,它不会建议您在应用程序暂停时执行的操作.didFinishLaunchingWithOptions的文档说:
该应用程序在后台跟踪位置更新,已被清除,现在已重新启动.在这种情况下,字典包含一个键,表示由于新的位置事件导致应用程序重新启动.
建议您在终止后启动应用程序(因为位置更改)时才会收到此呼叫.
但是," 位置感知规划指南"中关于重大变更服务的段落如下:
如果您使此服务保持运行并且您的应用程序随后被暂停或终止,则服务会在新位置数据到达时自动唤醒您的应用程序.在唤醒时,您的应用程序将被置于后台并给予少量时间来处理位置数据.由于您的应用程序位于后台,因此应该执行最少的工作并避免任何可能阻止其在分配的时间到期之前返回的任务(例如查询网络).如果没有,您的申请可能会被终止.
这表明如果您的应用已被暂停,您会被位置数据唤醒,但未提及您是如何被唤醒的:
在写这篇文章的过程中,我想我可能刚刚回答了我自己的问题,但是如果有更多知识渊博的人对我的理解得到证实,那就太棒了.
使用最新iOS设备中的M7芯片,当用户使用CMMotionActivityManager从静止到跑步,步行等时,可以通过编程方式获得通知.当Stava和Runkeeper 检测到用户没有通过M7移动时,它们都使用它来自动暂停GPS轮询(关闭GPS天线),然后在再次移动时重新启用GPS更新.当应用程序处于后台状态时,它可以执行此操作,这是此处的关键.
我在复制此功能时遇到的问题是,如果我在我的应用程序处于后台时关闭GPS更新,我将停止接收活动更新,并且无法再检测用户何时通过M7再次移动以重新打开GPS.
如果我让GPS一直运行,我会在整个应用程序处于后台时继续从Core Motion获取移动更新.
我假设他们没有玩白噪声或其他一些廉价的技巧来保持活跃.他们是怎么做到的?
我正在尝试实施这篇文章中给出的建议.
不幸的是,我不清楚这些步骤.我尝试实现这些建议,但是即使在我启动和停止locationServices之后,backgroundTimeRemaining仍然继续减少.这就是我开发它的方式:
- (void)applicationDidEnterBackground:(UIApplication *)application {
UIApplication* app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task.
self.timer = nil;
[self initTimer];
});
}
Run Code Online (Sandbox Code Playgroud)
initTimer:
- (void)initTimer {
// Create the location manager if this object does not
// already have one.
if (nil == self.locationManager)
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
[self.locationManager …Run Code Online (Sandbox Code Playgroud) 似乎在iOS 7中,应用程序无法再从后台任务启动位置管理器(通过调用startUpdatingLocation).
在iOS 6中,我使用了这里描述的方法:https://stackoverflow.com/a/6465280每n分钟运行一次后台位置更新.我们的想法是使用计时器运行后台任务,并在计时器触发时启动位置管理器.之后关闭位置管理器并启动另一个后台任务.
更新到iOS 7后,此方法不再起作用.启动位置管理器后,应用程序不会收到任何locationManager:didUpdateLocations.有任何想法吗?
我正在创建一个应用程序,其中我从服务器下载一些数据.在后台进行时,我希望连接应该继续运行,以便可以下载数据.我知道appDelegate中有方法
- (void)applicationDidEnterBackground:(UIApplication *)application
Run Code Online (Sandbox Code Playgroud)
当应用程序进入后台时调用.但是,随着连接的viewController中创建的,怎么能在管理的appDelegate?
还有/其他方式可以这样做吗?我已经通过这个链接,但是有一些简单的实现吗?
基于此示例应用程序 和此Stackoverflow帖子:定期iOS后台位置更新,我已设法创建用于定期后台位置跟踪的工作实现.
一切都在设备上运行良好,我从Xcode安装应用程序,但对于我通过crashlytics发送应用程序的每个测试人员,应用程序仍然在后台超时.
是否必须对调试/发布模式或配置文件进行任何操作?
CLLocationManager.requestLocation()大约需要10秒才能开火didUpdateLocations.
以下是为其设置的属性 CLLocationManager
let locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = 10
locationManager.requestWhenInUseAuthorization()
locationManager.requestLocation()
Run Code Online (Sandbox Code Playgroud)
根据文档,这可能需要几秒钟.
此方法立即返回.调用它会导致位置管理器获取位置修复(可能需要几秒钟)并使用结果调用委托的locationManager(_:didUpdateLocations :)方法.
但这需要10秒钟吗?或者我错过了什么?
我编写了下面的代码,它有一个每分钟调用一次回调函数的计时器.当应用程序进入后台时,我启动了另一个调用相同回调方法的计时器,但后台计时器仅工作三分钟.
我知道Apple只允许后台任务三分钟.我的应用程序更像是一个跟踪应用程序,即使应用程序处于后台,每分钟也会跟踪用户的位置,因此我需要实现此功能.
我知道beginBackgroundTaskWithExpirationHandler要使用但我不知道我的实现是否正确.
注意:我在plist toApp寄存器中有必要的后台模式来进行位置更新.
非常感谢任何工作代码或链接.
override func viewDidLoad() {
super.viewDidLoad()
timeInMinutes = 1 * 60
self.locationManager.requestAlwaysAuthorization()
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
var timer = NSTimer.scheduledTimerWithTimeInterval( timeInMinutes, target: self, selector: "updateLocation", userInfo: nil, repeats: true)
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
let locValue:CLLocationCoordinate2D = manager.location!.coordinate
self.latitude = locValue.latitude
self.longitude = locValue.longitude
if UIApplication.sharedApplication().applicationState == .Active {
} else {
backgroundTaskIdentifier = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({ () -> Void in
self.backgroundTimer.invalidate()
self.backgroundTimer = NSTimer.scheduledTimerWithTimeInterval( …Run Code Online (Sandbox Code Playgroud) 我只想按需跟踪用户当前位置。我只需要初始位置,不需要持续更新。我认为最好的方法是向用户发送静默通知,以便一次获取用户的当前位置。接收静默通知效果很好,但 LocationManager 无法对位置进行初始修复。我的位置管理器委托类正常实例化,但在调用位置管理器方法 startUpdatingLocation() 后的任何时候都不会触发 didUpdateLocations 函数。当应用程序从 AppDelegate:didFinishLaunchingWithOptions 正常启动时,LocationManager 会毫无问题地更新用户位置。
我正在 Xcode 6.3.2 到 iOS 8.3 上进行开发
我的 AppDelegate:DidReceiveRemoteNotification 看起来像这样:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler handler: (UIBackgroundFetchResult) -> Void) {
var bgTask = bgManager()
bgTask.registerBackgroundTask()
LocManager.locationMngr.startUpdatingLocation() // LocManager is global variable
let delayInSeconds = 8.0
let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delayInSeconds * Double(NSEC_PER_SEC)))
dispatch_after(popTime, dispatch_get_main_queue()) {
println(LocManager.updated)
bgTask.endBackgroundTask()
handler(UIBackgroundFetchResult.NewData)
}
}
Run Code Online (Sandbox Code Playgroud)
我首先尝试仅使用以下行:
LocManager.locationMngr.startUpdatingLocation()
Run Code Online (Sandbox Code Playgroud)
但当它不起作用时,我添加了后台任务和dispatch_after,以确保我的位置管理器有足够的时间在终止之前检索第一个位置更新。
这是 LocationManager 类:
class LocationManager: NSObject, CLLocationManagerDelegate {
let locationMngr:CLLocationManager
var coord:CLLocationCoordinate2D
var …Run Code Online (Sandbox Code Playgroud) core-location apple-push-notifications appdelegate swift ios8.3
ios ×9
background ×3
objective-c ×3
swift ×3
iphone ×2
appdelegate ×1
apple-m7 ×1
core-motion ×1
gps ×1
ios7 ×1
ios8.3 ×1
location ×1