简体   繁体   English

IOS-位置更新间隔

[英]IOS - Location Update Interval

I'm starting on IOS developing, and I'm very unfamiliar with the language. 我正在开始IOS开发,并且对语言非常不熟悉。

I'm trying to develop an app that will track the location of a device on the background. 我正在尝试开发一个可在后台跟踪设备位置的应用程序。 I've followed some tutorials and put up a code that Logs the location update. 我遵循了一些教程,并提供了记录位置更新的代码。

-(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];
}

It works. 有用。 Since I've configured the .plist file it is registered for running on background, it logs the location endlessly. 由于我已经配置了.plist文件,因此已将其注册为在后台运行,因此它会不断记录该位置。

But I need the update to be periodically, with a defined interval, otherwise it would be a battery killer. 但是我需要定期进行更新,并按定义的时间间隔进行更新,否则将导致电池电量下降。 I realize that there are tons of questions here on SO about Location Update on the background, but my attempts are not being successful and I'm stuck. 我意识到关于SO的背景信息在这里有无数的问题,但是我的尝试没有成功,我陷入了困境。

I've tried stoping the Update and scheduling a start with NSTimer within the location update listener: 我尝试停止更新并安排在位置更新侦听器中使用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];
}

Where CurrentLocationIdentifier is a method that requests the start update again. 其中CurrentLocationIdentifier是再次请求开始更新的方法。

But it runs the first time, and then don't fire the scheduled task! 但是它是第一次运行,然后不要触发预定任务! What am I doing wrong? 我究竟做错了什么? Should it be done some other way? 是否应该以其他方式完成?

If you don't need detailed location updates in the background then the significant location update service is probably the best approach. 如果您不需要在后台进行详细的位置更新,则重要的位置更新服务可能是最好的方法。

- (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];
}

By the way, the delegate method you are using, locationManager:didUpdateToLocation:fromLocation: is deprecated and you should use locationManager:didUpdateLocations: 顺便说一句,已弃用了您使用的委托方法locationManager:didUpdateToLocation:fromLocation: ,您应该使用locationManager:didUpdateLocations:

UPDATE Significant location change isn't available on all devices, so I added a check to my code. 更新并非所有设备都提供重要的位置更改,因此我在代码中添加了检查。 You need to decide what approach to take on a device where it isn't available - stick with standard updates, perhaps increasing distanceFilter 您需要决定在不可用的设备上采用哪种方法-坚持使用标准更新,也许会增加distanceFilter

I have a project on Github, https://github.com/dsdavids/TTLocationHandler , that you are welcome to download and fiddle with. 我在Github上有一个项目, https://github.com/dsdavids/TTLocationHandler ,欢迎您下载和使用。 TTLocationHandler is a drop in class that you can set as you wish to get the sort of results others have been pointing to. TTLocationHandler是您可以设置的类中的一个类,您可以根据需要获得其他对象一直指向的结果。 I made it when I was in exactly your situation, trying to figure out how to use location services in the background. 我碰巧在您遇到的情况下做到了,试图弄清楚如何在后台使用位置服务。

I would strongly advise that you forget any ideas of trying to fire regularly by any scheduled timer. 我强烈建议您不要忘记尝试通过任何预定的计时器定期触发的想法。 The idea is to set the handler to fire for events as makes sense then analyze the return and further filter down your response to only as much activity as needed. 这样做的想法是将处理程序设置为针对有意义的事件触发,然后分析返回值,并进一步过滤响应,以仅根据需要进行尽可能多的活动。 I find significant location changes to be the best trade off. 我发现重大的位置更改是最好的权衡。

You are able to set this for tracking non stop, then respond only as often as you require. 您可以将其设置为跟踪不间断,然后仅根据需要进行响应。 You better have a good reason for that battery hit or your app will be rejected. 您最好有充分理由说明电池电量耗尽,否则您的应用将被拒绝。 My own app was rejected at first, even though I was setting it to only go full bore if it was plugged in to power. 我自己的应用程序一开始被拒绝,即使我将其设置为仅在接通电源后才能完全使用。 I suppose they were right though. 我想他们是对的。 I was able to get everything I need with significant location changes and region monitoring. 通过重大的位置更改和区域监视,我能够获得所需的一切。 My app never lets the locationManager go wild and has little impact on battery. 我的应用程序永远不会让locationManager崩溃,并且对电池的影响很小。

There is no way to wake up the application after a given time interval to execute your code. 在给定的时间间隔后无法唤醒应用程序以执行代码。 You really have two options, background fetches, and either region monitoring or significant location changes. 您确实有两个选择,后台获取,以及区域监视或重大位置更改。

In terms of getting location updates periodically (based on time rather than distance moved), the best you can do is utilize iOS multitasking API performFetchWithCompletionHandler , which in a nutshell allows the OS to wake you up when it determines you can have time to process. 就定期获取位置更新(基于时间而不是移动的距离)而言,您可以做的最好的事情就是利用iOS多任务API performFetchWithCompletionHandler ,简而言之,它允许OS在确定您有时间处理时您唤醒。 You'll have about 30 seconds of wall time to handle what you want to and go back to sleep. 您将有大约30秒钟的空闲时间来处理所需的内容,然后返回睡眠状态。

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

There are a number of steps involved to get this set up, but it's pretty easy and should point you in the right direction. 进行此设置涉及很多步骤,但这很容易,应该为您指明正确的方向。 Note that this will not allow you to schedule these events whenever you want, you are really limited by the OS and the algorithm it uses to determine how often you should be allowed to perform background fetches. 请注意,这将不允许您在需要时安排这些事件,这实际上受操作系统及其用于确定应该多久执行一次后台提取操作的算法的限制。 If you take a long time and use lots of battery, you will get less frequent fetches, and if you take too much time and never complete you'll be terminated. 如果您花费很长时间并且使用大量电池,则获取的频率会降低,如果花费太多时间而又从未完成,则将被终止。 Being "responsible" in the background ends up with the OS giving you more time. 在后台“负责任”最终会给操作系统带来更多时间。

In my experience, being as "responsible" as possible while doing location updates and sending server requests, background fetches occur approx. 以我的经验,在执行位置更新和发送服务器请求时尽可能地“负责任”,后台获取大约发生。 15-30 minutes apart. 相隔15-30分钟。

If you want to be woken up when users move some specified distance, region monitoring is a pretty good (although imperfect) way to handle that, and can allow your app to wake up, start a long running background task (30 seconds) and do what you need to do before ending the task and going back to sleep. 如果您想在用户移动指定距离时被唤醒,则区域监视是一种很好的方式(尽管不完美),可以处理您的应用,并可以唤醒您的应用,启动长时间运行的后台任务(30秒)并执行在结束任务并重新入睡之前需要执行的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM