【发布时间】:2014-06-14 14:10:59
【问题描述】:
我正在研究为 iOS 活动跟踪器使用延迟位置更新,它允许在后台提供位置服务。我已经实现了建议的代码 sn-ps(见下文)。在 Xcode 调试中,延迟位置会尝试启动几次,直到位置数据以每秒 1 次左右的速度进入。之后,它声称启动deferrals成功,并且finish触发器的回调在指定的时间段到期后也成功。但是,在此期间,位置处理程序仍每秒运行一次。我读到这是因为手机还没有认为自己准备好进入后台,而 Xcode 中的测试就是这样做的。注意,AppDelegate 的“didEnterBackground”事件处理程序在关闭屏幕时立即被调用,并在重新打开应用程序时恢复。
我在手机断开连接的情况下运行了相同的代码,在 GPS 窗口附近、屏幕关闭或切换到完全不同的应用程序时,它仍然从未真正推迟更新。我可以判断,因为网络更新仍然每 30 秒进行一次,而不是下面代码示例中所需的 120 秒间隔。
实际上还需要什么才能使延迟起作用,因为在启动它们时没有发生错误并且它们确实得到了完成回调?为什么即使应用进入后台,位置更新也会以每秒 1 次的速度继续?
iPhone 5s,IOS 7.1.1
// .h file (partial)
@interface MotionTracker : NSObject<CLLocationManagerDelegate, UIAccelerometerDelegate>
@property (strong, nonatomic) CLLocationManager *locationManager;
@end
// .m file (parial)
- (id) init {
if(self = [super init]){
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
_locationManager.distanceFilter = kCLDistanceFilterNone;
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// if set to YES (default), app stops logging location at some point and doesn't resume in any timely fashion, all data points lost in between
_locationManager.pausesLocationUpdatesAutomatically = NO;
_locationManager.activityType = CLActivityTypeFitness;
}
return self;
}
// called early in program after login confirmed
- (void) startCollectingLocation {
[_locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
// logs to file when device is not in debug
// always returns 1
NSLog(@"Location update count: %d",[locations count]);
// some code here to handle location updates
// - collect key location day in NSDictionary
// - every N seconds send Network call to server to save (have tried 30 seconds, 15 minutes, 30 minute network intervals). Have also tried turning off network calls completely.
// deferred updates starter
if (!self.deferringUpdates) {
if([CLLocationManager deferredLocationUpdatesAvailable]){
[_locationManager allowDeferredLocationUpdatesUntilTraveled:500 timeout:(NSTimeInterval)120]; // (have also tried large numbers, and "Infinite"
self.deferringUpdates = YES;
NSLog(@"Deferred updates start");
} else {
NSLog(@"Deferred updates not available");
}
}
}
- (void)locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error {
if(!error){
_deferringUpdates = NO;
NSLog(@"Deferred updates: finished");
} else {
_deferringUpdates = NO;
NSLog(@"Deferred updates: %@", [error localizedDescription]);
}
}
【问题讨论】:
-
您是否完成了this answer 中列出的所有操作?在该列表之后的大部分时间里,我都能让它工作。
-
是的,我已经完成了该列表中的所有内容并检查了几次。那里的大部分内容似乎都很基本。
-
其中一个关键是等待位置更新定期进入,然后再启用延迟更新。即使这样,系统也不会一直启用它,这取决于设备上的其他内容。如果它对你有用,即使只是一次,那么你就做对了,这只是由系统决定何时让 CPU 休眠。
-
它从来没有工作过。我最初立即调用它,它会给出错误代码,直到 GPS 完全启动,然后运行没有错误但仍然没有延迟。然后我在尝试第一次调用之前等待了 15 秒,不再收到错误代码,但仍然没有运气。我已经让它在调试器上运行了几个小时,屏幕关闭。我已经在设备上独立运行它,并完成了离线日志记录,让它在一夜之间运行,基本上直到电池从所有位置更新中耗尽 12 小时以上。我不确定还需要什么来让 CPU 休眠。
-
连接到调试器时设备从不休眠。
标签: ios location core-location deferred