我有一个简单的位置图,当用户接近远程文件中列出的位置时,我想发出应用提示音

列出的位置在我的服务器上,名为locations.txt

我如何每1分钟检查一次location.txt,以查看用户是否在某个位置的300m之内?

最佳答案

如《位置感知指南》中所述,此问题的标准答案是Shape-Based Regions。通常,如果您的区域数量有限,那么基于形状的区域就是您的最佳选择。但是,由于您需要很多区域,因此可能必须“自己滚动”:

  • 打开定位服务并监视您的位置。参见Location Awareness Programming Guide。如果您使用标准的位置服务,请确保设置的desiredAccuracy尽可能低,以实现功能需求(例如kCLLocationAccuracyHundredMeters)。
  • 成功收到第一个 didUpdateLocations 后,如果您真的想检查每一分钟,则可以在此时创建一​​个计时器。如果该计时器的目的只是检查用户的位置,那么确实不需要计时器,您可以等待didUpdateLocations的出现。
  • 您可以遍历位置数组以进行监视(我会将它们转换为CLLocation对象),只需使用 distanceFromLocation 即可。

  • 不过,有几点观察:
  • 建议您每分钟检查一次locations.txt,以查看用户是否在位置300m之内。我可以想象出您可能提出该解决方案的两个原因:
  • 服务器的locations.txt更改了吗?如果这是您要解决的问题,则更好的解决方案是push notifications(又称“远程通知”),并且您要确保客户端可以访问最新信息。不断重新检索文件的过程非常昂贵(就带宽,电池,计算而言);或
  • 用户移动了吗?如果您担心用户是否已移动,则正确的解决方案不是每分钟检查一次,而是等待[CLLocationManagerDelegate]实例方法 didUpdateLocations 被调用。如果要避免进行过多的冗余检查,则始终可以跟踪最近的请求是否在不到一分钟之前发生,然后仅在超过一分钟之前再次进行检查。但这与每分钟检查是否需要有很大不同。
  • 您建议使用文本文件。您可能想考虑使用JSON文件(或XML文件),这是从服务器检索数据的更好的机制。


  • 例如,如果您具有JSON格式的文本文件,则可以用另一行代码( JSONObjectWithData )解析结果。为了说明这一点,让我向您展示一个JSON文件的外观(方括号指定一个数组,花括号指定一个字典,因此这是一个字典数组):
    [
      {
        "name" : "Battery Park",
        "latitude" : 40.702,
        "longitude" : -74.015
      },
      {
        "name" : "Grand Central Station",
        "latitude" : 40.753,
        "longitude" : -73.977
      }
    ]
    

    然后,您的应用程序可以轻松地通过两行内容来检索结果:
    NSData *locationsData = [NSData dataWithContentsOfURL:url];
    NSArray *locationsArray = [NSJSONSerialization JSONObjectWithData:locationsData options:0 error:&error];
    

    因此,您需要启动定位服务:
    if (nil == self.locationManager)
       self.locationManager = [[CLLocationManager alloc] init];
    
    self.locationManager.delegate = self;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
    
    // Set a movement threshold for new events.
    self.locationManager.distanceFilter = 500;
    
    [self.locationManager startUpdatingLocation];
    

    然后,您将有一个例程来检查当前位置:
    - (void)checkLocation
    {
        NSURL *url = [NSURL URLWithString:kLocationsUrlString];
        NSData *locationsData = [NSData dataWithContentsOfURL:url];
        NSAssert(locationsData, @"failure to download data"); // replace this with graceful error handling
    
        NSError *error;
        NSArray *locationsArray = [NSJSONSerialization JSONObjectWithData:locationsData
                                                                  options:0
                                                                    error:&error];
        NSAssert(locationsArray, @"failure to parse JSON");   // replace with with graceful error handling
    
        for (NSDictionary *locationEntry in locationsArray)
        {
            NSNumber *longitude = locationEntry[@"longitude"];
            NSNumber *latitude = locationEntry[@"latitude"];
            NSString *locationName = locationEntry[@"name"];
    
            CLLocation *location = [[CLLocation alloc] initWithLatitude:[latitude doubleValue]
                                                              longitude:[longitude doubleValue]];
            NSAssert(location, @"failure to create location");
    
            CLLocationDistance distance = [location distanceFromLocation:self.locationManager.location];
    
            if (distance <= 300)
            {
                NSLog(@"You are within 300 meters (actually %.0f meters) of %@", distance, locationName);
            }
            else
            {
                NSLog(@"You are not within 300 meters (actually %.0f meters) of %@", distance, locationName);
            }
        }
    }
    

    当用户位置更改时,将调用此方法:
    // this is used in iOS 6 and later
    
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
    {
        [self checkLocation];
    }
    
    // this is used in iOS 5 and earlier
    
    - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
    {
        if ([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0)
            [self checkLocation];
    }
    

    该实现可能类似于this test project on GitHub。这是一个准系统的实现,但是它为您提供了一些手头工具,即检索locations.json文件并将其与设备检索到的位置进行比较。

    10-08 17:49
    查看更多