在没有NSTimer的情况下每隔几秒调用获取当前坐标 [英] Invoke get current coordinates every few seconds without NSTimer

查看:85
本文介绍了在没有NSTimer的情况下每隔几秒调用获取当前坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道如何使用NSTimer进行此操作,但我不想每隔几秒就没有计时器来获取当前的iPhone坐标。我不能使用计时器,因为我在应用程序处于后台时得到坐标。

我已经尝试了一些东西,但是每隔10秒就会调用一次,因为我不想。

我在这里做错了什么?

I know how to make this with NSTimer but I wan't to get current iPhone coordinates without timer on every few seconds. I can't use timer because I am getting coordinates while application is in background.
I have tried something but this calls every second not every 10 seconds as I wan't.
What am I doing wrong here?

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    CLLocation *loc = [locations objectAtIndex:0];

    NSDate* eventDate = loc.timestamp;
    NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
    if (howRecent < 10)
    {
        CLLocation* location = [locations lastObject];

        double lat = location.coordinate.latitude;
        double lng = location.coordinate.longitude;
        NSLog(@"lat:%f lng:%f", lat, lng);

首先尝试每10秒执行一次后台任务,但如果我不知道在哪里设置时间在这里做任何事情:

First try to do background task every 10 seconds, but don't know where to set time if I do anything right here:

- (void)applicationDidEnterBackground:(UIApplication *)application
{

    backgroundTask = [application beginBackgroundTaskWithExpirationHandler: ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            if (backgroundTask != UIBackgroundTaskInvalid)
            {
                [application endBackgroundTask:backgroundTask];
                backgroundTask = UIBackgroundTaskInvalid;
            }
        });
    }];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        _pendingLocationsTimer = [NSTimer timerWithTimeInterval:_pendingLocationsTimerDuration
                                                         target:self
                                                       selector:@selector(_acceptBestAvailableLocation:)
                                                       userInfo:nil repeats:NO];


        NSRunLoop *loop = [NSRunLoop currentRunLoop];
        [loop addTimer:_pendingLocationsTimer forMode:NSRunLoopCommonModes];
        [loop run];

        dispatch_async(dispatch_get_main_queue(), ^{
            if (backgroundTask != UIBackgroundTaskInvalid)
            {
                // if you don't call endBackgroundTask, the OS will exit your app.
                [application endBackgroundTask:backgroundTask];
                backgroundTask = UIBackgroundTaskInvalid;
            }
        });
    });

}


推荐答案

我有在背景状态下有计时器的问题。无法保证您将拥有一个活动的运行循环,因此在您返回前台之前,计时器永远不会启动。我做的是:

I have had issues with timers in the background state. There is no guarantee that you will have an active run loop and so the timer will never fire until you come back to foreground. What I did is:

 NSRunLoop *loop = [NSRunLoop currentRunLoop];
 [loop addTimer:myTimer forMode:NSRunLoopCommonModes];
 [loop run];

我在BackgroundIdentifierTask开始和结束调用中的后台线程上执行此操作。我并不完全相信我的一切都是正确的,事实上我查看了你的问题,看看答案是否可以帮助我确认或纠正我对要求的理解。

I do this on a background thread inside BackgroundIdentifierTask begin and end calls. I am not fully confident that I have it all correct, in fact I looked at your question to see if an answer may help me confirm or correct my understanding of the requirements.

如果要继续监视位置,还必须在默认的info.pList中启用位置服务的后台模式。如果您只是使用significantLocationUpdates或geofence,则不需要它。

You also must have the background mode for location services enabled in your default info.pList if you want to continually monitor location. You do not need that if you are just using significantLocationUpdates or geofence.

我的计时器确实有效,并按照预期的方式设置。在此之前它没有可靠的工作。

My timer does work and does fire as intended set up this way. It did not work reliably prior to that.

除此之外,没有计时器你可能是最好的。使用上面的代码,只需更改位置管理器的属性即可。期望的准确度和距离过滤器是可以减少经理发出新位置通知的频率的属性。

Aside from that, you may be best off with no timer. Using your code above, just change the properties of your location manager. Desired accuracy and distance filter are properties that will reduce how often the manager sends out a new location notification.

查看我刚刚在github上发布的我自己的位置处理程序示例任何有兴趣的人:

See an example of my own location handler I just posted on github for anyone that is interested:

http://github.com / dsdavids / TTLocationHandler

我不认为计时器是关键。如果在项目中删除TTLocationHandler类,请查看LMViewController类如何响应处理程序。

I don't think the timer is the key. If you drop the TTLocationHandler class in your project, then take a look at how the LMViewController class responds to the handler.

NSNotificationCenter *defaultNotificatoinCenter = [NSNotificationCenter defaultCenter];
[defaultNotificatoinCenter addObserver:self selector:@selector(handleLocationUpdate) name:LocationHandlerDidUpdateLocation object:nil];

将控制器设置为观察者。每当处理程序确定收到一个新的或更准确的位置时,都会调用handleLocationUpdate。

sets up the controller as an observer. Whenever the handler determines a new or more accurate location has been received, handleLocationUpdate is called.

当调用startUpdating时,locationManager会发送新的位置,每秒很多首先,当移动直到设备静止并达到精度。 TTLocationHandler 正在过滤这些事件,并仅根据配置发送需要的通知。

The locationManager, when startUpdating is invoked will send out new locations, many per second at first and when moving until the device is stationary and accuracy achieved. The TTLocationHandler is filtering these events and only sending notification as needed based on configuration.

请注意,在 - (id)init中,设置了_recencyThreshold到60.所以我们每隔60秒保存或显示一个引脚。如果您想要更小的间隔,请更改此值。

Note that in -(id)init, _recencyThreshold is set to 60. So we are saving or displaying a pin every 60 seconds. If you want smaller interval, change this.

实际上,TTLocationHandler将在后台切换到重要的位置更改,除非设备已插入电源。如果使用电池供电,你将不会在更新之间获得那么小的间隔,但是你会得到更新。

As it is, TTLocationHandler will always switch to significant location changes when in background unless the device is plugged in to power. You will not get that small an interval between updates if it is on battery power, but you will get updates.

我添加了一个属性来配置连续后台更新而不收费。

I added a property to configure for continuous background updates without charging.

我在存储库中添加了另一个类来说明我将如何进行用我的经纪人实现你的目标。我添加了LMPinTracker类,您可以在其中添加用于存储和上传位置的代码。

I have added another class to the repository to show how I would go about achieving your goals with the my handler. I have added LMPinTracker class where you can add your code for storing and uploading the locations.

查看LMAppDelegate.m

Look at LMAppDelegate.m

    self.pinTracker.uploadInterval = 30.00;

将其更改为上传到服务器之间的任何间隔。

change that to whatever interval you want between uploads to the server.

    self.sharedLocationHandler.recencyThreshold = 5.0;

将5.0更改为存储位置之间所需的最短时间。它不会准确,会根据行程速度和信号强度而有所不同,但基本上,在x秒间隔后,它会考虑存储的位置陈旧并尝试获得另一个准确的位置。

Change that 5.0 to the minimum time you want between stored locations. It won't be exact, will vary on the rate of travel and the signal strength but basically, after x seconds interval it will consider the stored location stale and attempt to get another accurate location.

现在查看LMPinTracker.m文件

在这两行之后立即存储数据:

Now look at the LMPinTracker.m file
Put your data storing code right after these two lines:

    // Store the location into your sqlite database here
    NSLog(@"Received location info: %@ \n Ready for store to database",lastKnowLocationInfo);

在此评论之后将您的网络上传代码放在此处:

Put your web upload code right here after this comment:

    // Do your upload to web operations here



< h2>评论

这应该做你想做的事情,同时仍然尊重用户电池和后台操作。

Comments

This should do what you are looking to do, while still respecting user battery and background operation.

基本上,当用户旅行时,更新将在您设置的时间间隔内连续进行。

当用户静止时,将没有更新且没有重大活动。

当没有新活动时,您也不会上传到网络。

当用户再次开始移动时,记录和更新恢复。

Basically, when a user is traveling, updates will be continuous at about the interval you have set.
When a user is stationary, there will be no updates and no significant activity.
When there is no new activity, you won't upload to web either.
Logging and updating resumes when user starts moving again.

如果我是你,希望进一步完善它,我会考虑设置一个区域和时间来检查。如果用户保持静止一段时间,请仅切换到significantLocationUpdates。然后,您将关闭位置服务,但在用户再次开始使用时会重新启动。

If I were you, looking to refine it further, I would consider setting a region and time to check. If the user remains stationary for a length of time, switch to significantLocationUpdates only. Then you will power down the location services but be brought back up when the user gets underway once again.

这篇关于在没有NSTimer的情况下每隔几秒调用获取当前坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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