确保 locationManager 已完成然后执行请求

Posted

技术标签:

【中文标题】确保 locationManager 已完成然后执行请求【英文标题】:Ensure locationManager has finished then perform request 【发布时间】:2014-01-05 04:16:31 【问题描述】:

我正在使用 CoreLocation 来获取用户位置。我需要获取用户位置,然后将其发送到服务器。我有这一切工作,但是!我正在执行locationManager:(CCLLocationManager *)manager...

在找到该位置之前,我的 url 请求已命中。最好的方法是:

请求位置 存储在字符串中 向请求发送字符串

我想确保在发送之前找到该位置。我是否使用条件检查类的实例并且在块内命中服务器。我不用一直更新,抓一次就stopUpdatingLocation

之前浏览过这篇文章:Getting Longitude/Latitude of the User When the viewDidLoad

到目前为止我所拥有的:

- (void)viewDidLoad 

    [super viewDidLoad];

    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;

    [locationManager startUpdatingLocation];

    ...more below... server request below here

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

    NSLog(@"didUpdateToLocation: %@", newLocation);
    CLLocation *currentLocation = newLocation;

    if (currentLocation != nil) 
        NSLog(@"found!");
        [locationManager stopUpdatingLocation];
    

关于如何做到这一点的想法?我认为条件可能有效,但不确定是否有适当的方法使用 CoreLocation 提供的方法来处理它。

【问题讨论】:

【参考方案1】:

创建一个执行与位置相关的代码的新方法。然后一旦你有了位置(即在 NSLog(@"found!"); 行之后),调用这个方法。

请注意,随着位置准确性的提高,该方法可能会被多次调用 - 您可能需要处理这个问题。

例如:

- (void)viewDidLoad 

    [super viewDidLoad];

    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;

    [locationManager startUpdatingLocation];


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

    NSLog(@"didUpdateToLocation: %@", newLocation);
    CLLocation *currentLocation = newLocation;

    if (currentLocation != nil) 
    
        NSLog(@"found!");
        [self handleLocation:newLocation];
        [locationManager stopUpdatingLocation];
    


- (void)handleLocation:(CLLocation*)location

    // handling code here

【讨论】:

【参考方案2】:

位置管理器是异步的。您必须要求更新位置,然后等待它给您回电。

更糟糕的是,前几次更新通常是需要丢弃的垃圾。

第一次位置更新通常具有几小时、几天甚至几周的时间戳。您首先必须检查以确保时间戳在最后几秒内。

完成后,您需要检查水平精度,并确保读数足够准确。通常,当您第一次启动位置管理器时,前几个读数的准确度值超过一公里,这很糟糕。 (准确度实际上是一个半径值。您只能确保您获得的位置位于具有指定半径的圆内。)您需要提出一个“足够好”的特定于应用程序的准确度读数,然后抛出直到你得到一个足够好的读数。您还需要检查负精度读数,这意味着 GPS 返回的值无效。

接下来,您必须考虑 GPS 未在合理时间内稳定下来的情况。 (有时可能需要几分钟,或者根本无法获得良好的读数。)在这种情况下,您需要将其视为失败。

因此,要处理您需要编写 locationManager:didUpdateLocation: 方法来检查时间戳和水平精度以确保读数确实良好的所有操作。如果在合理的等待后无法获得合适的位置读数,您还需要确保超时并报告失败。一种方法是在您第一次开始位置更新时启动一个“放弃”计时器,并在您获得良好的阅读后,将其终止。如果计时器触发,请停止位置更新并向您的用户报告“无法获得良好的位置读数”错误。了解需要 10 或 15 秒才能获得体面的准确读数的情况并不少见。

【讨论】:

哦哇很高兴知道。在这个应用案例中,我正在显示潮汐,因此它是最近的潮汐站点,感谢上帝不需要超级准确的读数,但无论如何,在将数据返回给用户之前,我仍然应该考虑这些事情。欣赏它。

以上是关于确保 locationManager 已完成然后执行请求的主要内容,如果未能解决你的问题,请参考以下文章

android检查位置服务启用播放服务位置api

Android 光标错误 - 确保光标已正确初始化

使用 LocationManager.SetProviderLocation 模拟位置,如何使位置完整

iBeacons - locationManager:didEnterRegion 回调和 UUID

如何确保文件在复制前完成?

locationManager:didExitRegion: 应用程序运行时未调用