gpt4 book ai didi

IOS:当应用程序在后台运行一段时间时停止位置更新

转载 作者:行者123 更新时间:2023-11-28 21:52:13 25 4
gpt4 key购买 nike

我编写了一个应用程序来监控用户的位置。当我的 View 这样加载时,位置服务会打开:

// 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;

// Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}

[self.locationManager startMonitoringSignificantLocationChanges];
NSLog(@"Started monitoring significant location changes");

如果我在应用程序处于事件状态时终止该应用程序,定位服务将停止。这是我为停止 AppDelegate.m 中的定位服务而编写的代码:

- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also
applicationDidEnterBackground:.
// Saves changes in the application's managed object context before the application terminates.
NSLog(@"entered terminate in delegate");
[myController.locationManager stopUpdatingLocation];
[myController.locationManager stopMonitoringSignificantLocationChanges];
myController.locationManager = nil;
[self saveContext];
}

我遇到了一个问题,如果我的应用程序已经在后台,则不会调用上述方法,因此我无法关闭定位服务。为了解决这个问题,我找到了我尝试过的解决方案:

- (void)applicationDidEnterBackground:(UIApplication *)application {
// 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.

UIApplication *app = [UIApplication sharedApplication];
if ([app respondsToSelector:@selector(beginBackgroundTaskWithExpirationHandler:)]) {
self.bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
// Synchronize the cleanup call on the main thread in case
// the task actually finishes at around the same time.
dispatch_async(dispatch_get_main_queue(), ^{
if (self.bgTask != UIBackgroundTaskInvalid)
{
NSLog(@"Marking bgTask as Invalid when we entered background");
[app endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
}
});
}];
}
}

所以如果我的应用程序在后台运行,上述解决方案就有效。但是,我注意到如果让我的应用程序在后台运行很长时间(超过五分钟),过期处理程序就会启动。因此,如果我终止应用程序而不将其带到前台。位置服务图标仍然出现在手机上。我必须重新启动应用程序或先将其置于前台,然后终止它,以便禁用定位服务的代码启动。

如果我删除这两行:

         [app endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;

然后在附加调试器的情况下,五分钟后停止定位服务。如果我让它在后台运行更长时间,那么终止代码永远不会启动。是因为我没有改变位置还是应用程序最终死掉了?

所以我的问题是,如果应用程序在后台运行了一段时间,是否还有另一种方法可以确保该应用程序正确停止位置服务监控?

谢谢...阿姆罗


编辑,我做了更多实验,这是我的发现:

如果我在调试器进入后台模式后等待 11 分钟,则会调用 willTerminate 方法:

2015-01-13 08:52:45.935 [441:37074] @@@AMRO--->applicationWillResignActive entered

2015-01-13 08:52:46.642 [441:37074] @@@AMRO--->Entered background mode

2015-01-13 08:55:42.697 [441:37074] @@@AMRO--->beginBackgroundTaskWithExpirationHandler called

2015-01-13 09:03:26.265 [441:37074] entered terminate in delegate

如果我在没有调试器的情况下尝试此操作,并且只等待四分钟,则不会调用终止函数,我不必等待整整 11 分钟。

最佳答案

来自 Apple 的文档:

应用终止

Apps must be prepared for termination to happen at any time and should not wait to save user data or perform other critical tasks. System-initiated termination is a normal part of an app’s life cycle. The system usually terminates apps so that it can reclaim memory and make room for other apps being launched by the user, but the system may also terminate apps that are misbehaving or not responding to events in a timely manner.

Suspended apps receive no notification when they are terminated; the system kills the process and reclaims the corresponding memory. If an app is currently running in the background and not suspended, the system calls the applicationWillTerminate: of its app delegate prior to termination. The system does not call this method when the device reboots.

In addition to the system terminating your app, the user can terminate your app explicitly using the multitasking UI. User-initiated termination has the same effect as terminating a suspended app. The app’s process is killed and no notification is sent to the app.

https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html#//apple_ref/doc/uid/TP40007072-CH2-SW1

关于 significantChangesLocation:

If you leave the significant-change location service running and your iOS app is subsequently suspended or terminated, the service automatically wakes up your app when new location data arrives.

https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html

如果您不希望您的应用被 significantChangeLocation 唤醒,您可以在 backgroundTimeRemaining 即将到期时调用 stopMonitoringSignificantLocationChanges。

注意。

关于IOS:当应用程序在后台运行一段时间时停止位置更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27915318/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com