IOS - 位置更新间隔

时间:2014-09-26 21:12:33

标签: ios nstimer cllocationmanager

我从IOS开始开始,我对语言非常不熟悉。

我正在尝试开发一款能够跟踪背景设备位置的应用。我已经按照一些教程编写了一个记录位置更新的代码。

-(void)CurrentLocationIdentifier
{
    locationManager = [CLLocationManager new];
    locationManager.delegate = self;
    locationManager.distanceFilter = kCLDistanceFilterNone;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    [locationManager startUpdatingLocation];
}

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
    fromLocation:(CLLocation *)oldLocation {

        NSLog(@"%@", newLocation);
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [self CurrentLocationIdentifier];
}

有效。由于我已经配置了.plist文件,因此它已注册为在后台运行,它会无限地记录该位置。

但是我需要定期更新,定义的间隔,否则它将成为电池杀手。我意识到关于位置更新的背景有很多问题,但是我的尝试没有成功,而且我被卡住了。

我已尝试在位置更新侦听器中停止更新并使用NSTimer安排启动:

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
    fromLocation:(CLLocation *)oldLocation {

        NSLog(@"%@", newLocation);

        [locationManager stopUpdatingLocation];
        NSTimer *timer;
        timer = [NSTimer scheduledTimerWithTimeInterval:10
                    target:self
                    selector:@selector(CurrentLocationIdentifier)
                    userInfo:nil
                    repeats:NO];
}

CurrentLocationIdentifier是一种再次请求开始更新的方法。

但它是第一次运行,然后不会触发预定的任务!我究竟做错了什么?它应该以其他方式完成吗?

3 个答案:

答案 0 :(得分:2)

如果您不需要在后台进行详细的位置更新,则significant location update service可能是最佳方法。

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
        ... // Any other initialisation you already have
    locationManager = [CLLocationManager new];
    locationManager.delegate = self;
    locationManager.distanceFilter = kCLDistanceFilterNone;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    [locationManager startUpdatingLocation];
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    if ([CLLocationManager significantLocationChangeMonitoringAvailable] {
        [locationManager stopUpdatingLocation];
        [locationManager startMonitoringSignificantLocationChanges];
    }
    else {
        //Decide what you want do to if it isn't available
    }
}

- (void)applicationDidEnterForeground:(UIApplication *)application
{
    [locationManager startUpdatingLocation];
    [locationManager stopMonitoringSignificantLocationChanges];
}

顺便说一下,您使用的委托方法locationManager:didUpdateToLocation:fromLocation:已弃用,您应该使用locationManager:didUpdateLocations:

<强>更新 并非所有设备都提供重要的位置更改,因此我在代码中添加了检查。您需要决定在无法使用的设备上采取何种方法 - 坚持使用标准更新,可能会增加distanceFilter

答案 1 :(得分:2)

我在Github上有一个项目,https://github.com/dsdavids/TTLocationHandler,欢迎您下载并摆弄。 TTLocationHandler是一个类中的一个drop,你可以设置为你希望获得其他人指向的结果。我在完全符合你的情况下做到了,试图弄清楚如何在后台使用位置服务。

我强烈建议您忘记任何计划定时器试图定期开火的想法。我们的想法是将处理程序设置为触发事件,然后分析返回并进一步将响应过滤掉所需的活动。我发现重要的位置变化是最好的权衡。

您可以将此设置为跟踪不停止,然后根据需要进行响应。你最好有充分的理由来击中电池或你的应用程序将被拒绝。我自己的应用程序最初被拒绝,即使我把它设置为只有插入电源才能完全耗尽。我想他们是对的。通过重要的位置变更和区域监控,我能够获得所需的一切。我的应用程序永远不会让locationManager变得疯狂,对电池的影响也很小。

答案 2 :(得分:1)

在给定的时间间隔后无法唤醒应用程序以执行代码。您确实有两个选项,后台提取,区域监控或重要的位置更改。

在定期获取位置更新(基于时间而非移动距离)方面,您可以做的最好的事情就是利用iOS多任务API performFetchWithCompletionHandler,简而言之,它允许操作系统在它确定您有时间处理。你将有大约30秒的时间来处理你想要的东西并重新入睡。

https://developer.apple.com/library/ios/documentation/uikit/reference/uiapplicationdelegate_protocol/index.html#//apple_ref/occ/intfm/UIApplicationDelegate/application:performFetchWithCompletionHandler

要完成此设置需要执行许多步骤,但这很容易,并且应该指向正确的方向。请注意,这不允许您随时安排这些事件,您实际上受操作系统及其用于确定应允许执行后台提取的频率的算法的限制。如果你需要很长时间并且使用大量电池,那么你将获得更少的频率,如果你花费太多时间而从未完成,你将被终止。承担责任&#34;在后台以操作系统为您提供更多时间。

根据我的经验,作为&#34;负责任&#34;在进行位置更新和发送服务器请求时,尽可能进行后台提取。相隔15-30分钟。

如果你想在用户移动指定距离时被唤醒,区域监控是一种非常好的(虽然不完美)处理方式,可以让你的应用程序唤醒,启动一个长时间运行的后台任务(30秒)并且在结束任务并重新入睡之前做你需要做的事。