ios延迟位置更新无法推迟 [英] ios deferred location updates fail to defer

查看:186
本文介绍了ios延迟位置更新无法推迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究为iOS活动跟踪器使用延迟位置更新,它允许在后台使用位置服务。我已经实现了建议的代码片段(见下文)。在Xcode调试中,延迟位置尝试启动几次,直到位置数据以大约每秒1进入。之后,它声称成功启动延迟,并且在指定的时间段到期后,完成触发器的回调也会成功。但是在此期间,位置处理程序仍然每秒运行一次。我读过这是因为手机还没有准备好进入后台,而Xcode的测试就是这样做的。注意,AppDelegate的didEnterBackground事件处理程序在关闭屏幕时立即被调用,并在重新打开应用程序时恢复。

I am looking into using deferred location updates for an iOS activity tracker, which allows location services in background. I've implemented the suggested code snippets (see below). In Xcode debugging, deferred locations attempt to start a few times until location data comes in at about 1 per second. After that, it claims to succeed in starting deferrals, and the callback for the finish trigger also succeeds after the specified time period expires. However during the time, the location handler still runs once per second. I've read that this is because the phone hasn't deemed itself ready to enter the background, and that testing in Xcode does this. Note, AppDelegate's "didEnterBackground" eventhandler got called immediately when turning off the screen, and resumed when reopening app.

我运行相同的代码,手机断开连接作为另一个测试,靠近窗户的GPS,屏幕关闭或切换到完全不同的应用程序,它仍然从来没有实际推迟更新。我可以告诉,因为网络更新仍然每30秒进入一次,而不是下面代码示例中所需的120秒间隔。

I ran the same code with the phone disconnected as another test, near the window with GPS, screen off, or switching to entirely different apps, and it still never actually defers the updates. I can tell because the networked update still comes in once every 30 seconds, instead of the interval of 120 seconds which is desired in the code sample below.

还需要什么实际上让延期工作,因为启动它们没有错误,他们确实得到他们的完成回调?为什么即使应用程序转到后台,位置更新仍以每秒1次的速度继续?

What else is needed to actually get deferrals to work, since there is no error occurring in starting them and they do get their finish callback? Why do location updates continue at 1 per second even when the app goes to background?

Iphone 5s,IOS 7.1.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]);
    }
}


推荐答案

如果设备连接到调试器或充电器,设备将保持供电(不睡眠),因此不会进入延迟模式。 mode是一种功率优化,允许设备进入休眠状态。如果设备未被安排因其他原因而休眠,则启用延迟模式生病不要强迫它睡觉。通过确保没有其他应用程序正在使用位置服务,并在关闭屏幕时将其与充电器断开连接来尝试测试。运行一段时间后,重新插入并检查日志,你应该看到设备睡眠和延期更新。

If the device is connected to a debugger or on a charger, the device will remain powered (not sleep) and therefore will not enter deferred mode. Deferred mode is a power optimization allowing the device to sleep. If the device is not scheduled to sleep for other reasons, enabling deferred mode will not force it to sleep otherwise. Try your test by ensuring no other apps are using location services, and disconnecting it from a charger with the screen off. After running for some time, plug back in and check your logs, you should see that the device slept and deferred updates.

来自Apple的
allowDeferredLocationUpdatesUntilTraveled:timeout: documentation:

From Apple's allowDeferredLocationUpdatesUntilTraveled:timeout: documentation:


只有在系统输入低功率时才会提供延迟更新
州。调试期间不会发生延迟更新,因为Xcode
会阻止您的应用程序休眠,从而阻止系统从
进入低功耗状态。

Deferred updates are delivered only when the system enters a low power state. Deferred updates do not occur during debugging because Xcode prevents your app from sleeping and thus prevents the system from entering that low power state.

值得注意的是,延迟更新仅在locationManager.desiredAccuracy设置为kCLLocationAccuracyBest或kCLLocationAccuracyBest时可用; locationManager.distanceFilter也必须设置为kCLDistanceFilterNone。

It is also worth noting that deferred updates are only available when locationManager.desiredAccuracy is set to kCLLocationAccuracyBest OR kCLLocationAccuracyBest; locationManager.distanceFilter must also be set to kCLDistanceFilterNone.

来自Apple的文档:

From Apple's documentation:


...只有当设备上有GPS硬件并且所需精度设置为kCLLocationAccuracyBest或kCLLocationAccuracyBestForNavigation时,位置管理器才允许延迟更新。

...the location manager allows deferred updates only when GPS hardware is available on the device and when the desired accuracy is set to kCLLocationAccuracyBest or kCLLocationAccuracyBestForNavigation.


...位置管理器的distanceFilter属性必须设置为kCLDistanceFilterNone。

...the distanceFilter property of the location manager must be set to kCLDistanceFilterNone.

这篇关于ios延迟位置更新无法推迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆