如何在iOS上使用基于地理位置的推送通知?

当应用程序被终止(不在后台)时,是否可以在iOS上使用基于地理位置的推送通知?

我感兴趣的是构build一个应用程序,用户将在地图上select一个位置,然后如果他/她靠近该区域,则会触发本地的基于地理位置的推送通知。

然而这个“主意”甚至可能吗? 当应用程序被终止并运行时,GPS是否可以运行并比较坐标,并在何时到位时通知用户? 是否有任何关于这个问题的教程/文章/更多的信息,我可以读?

我在网上阅读的大部分信息,更像是一般的想法,没有任何具体的事情。

为了在应用程序没有运行的情况下跟踪用户的位置(即以前被终止),有两种select:

  1. 从“跟踪用户位置”下的iOS应用程序编程指南 :

    对于不需要高精度位置数据的应用,强烈推荐重大变更的位置服务。 有了这项服务,只有当用户的位置变化很大时才会生成位置更新; 因此,它非常适合为用户提供非关键的位置相关信息的社交应用或应用。 如果应用程序在发生更新时被挂起,系统会在后台将其唤醒以处理更新。 如果应用程序启动此服务,然后终止,系统将自动重新启动应用程序,当一个新的位置变得可用 。 此服务在iOS 4及更高版本中可用,并且仅在包含蜂窝无线电的设备上可用。

    但是,根据CLLocationManager类的引用 ,它不是太准确,更新不常见:

    注意:只要设备从先前的通知移动500米或更远,应用程序就会收到通知。 它不应该比每五分钟一次更频繁地发出通知。 如果设备能够从networking中检索数据,则位置pipe理者更可能及时地发送通知。

  2. 区域监控以类似的方式工作 – 包括在终止后重新启动应用 – 但具有更高的准确性(取决于Wifinetworking和蜂窝塔的可用性):

    特定的阈值距离由当前可用的硬件和位置技术确定。 例如,如果Wi-Fi已禁用,则区域监视的准确性将大大降低。 但是,出于testing目的,您可以假设最小距离大约为200米。

    另一个区域监视考虑是(根据CLLocationManager类参考 )区域进入和退出通知可能只有在跨越区域边界之后3-5分钟才能被接收。

    根据实际需求,区域监测可用于获取“粗略”位置,然后当用户处于特定区域内时,在位置pipe理器上启动更精确的基于GPS的服务。 当用户离开感兴趣的区域时,closuresGPS服务以保存电池并再次返回到粗略的位置监测服务(即区域监测)。 这是一个基本的实现:

    SomeViewController.m

    ... @interface SomeViewController () <CLLocationManagerDelegate> @property (nonatomic, strong) CLLocationManager *locationManager; @property (nonatomic, strong) CLRegion *someRegion; @end @implementation SomeViewController - (void)viewDidLoad { [super viewDidLoad]; self.locationManager = [[CLLocationManager alloc] init]; CLLocationDistance radius = 10; // 10 metre sensitivity self.someRegion = [[CLRegion alloc] initCircularRegionWithCenter:someCoordinates radius:radius identifier:@"Smithtown Dry Cleaners"]; self.locationManager.delegate = self; [self.locationManager startMonitoringForRegion:self.someRegion]; self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; self.locationManager.distanceFilter = 10; [self.locationManager startUpdatingLocation]; } - (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region { [self.locationManager startUpdatingLocation]; } - (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region { [self.locationManager stopUpdatingLocation]; } // Delegate method from the CLLocationManagerDelegate protocol. - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { CLLocation* location = [locations lastObject]; // If the user's current location is not within the region anymore, stop updating if ([self.someRegion containsCoordinate:location.coordinate] == NO) { [self.locationManager stopUpdatingLocation]; } NSString *locationData = [NSString stringWithFormat:@"latitude %+.6f, longitude %+.6f\n", location.coordinate.latitude, location.coordinate.longitude]; NSLog(@"%@", locationData); UILocalNotification *localNotification = [[UILocalNotification alloc] init]; localNotification.alertBody = locationData; localNotification.alertAction = @"Location data received"; localNotification.hasAction = YES; [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification]; } 

    请记住将相应的条目添加到应用程序的plist文件中,以便应用程序可以在后台运行,并访问相应的资源:

    MyApp-Info.plist

     <key>UIBackgroundModes</key> <array> ... <string>location</string> </array> <key>UIRequiredDeviceCapabilities</key> <array> ... <string>location-services</string> <string>gps</string> </array> 

    上面的代码假定使用iOS6和ARC