如何在iOS上使用基于地理位置的推送通知?
当应用程序被终止(不在后台)时,是否可以在iOS上使用基于地理位置的推送通知?如何在iOS上使用基于地理位置的推送通知?
我有兴趣创建一个应用程序,用户可以在地图上选择一个位置,然后如果他/她靠近该区域,则会触发本地基于地理位置的推送通知。
但是这个“想法”甚至可能吗?当应用程序被终止并运行时,GPS是否可以运行并比较坐标,并在何时到位时通知用户?是否有关于我可以阅读的主题的任何类型的教程/文章/更多信息?
我在网上阅读的大部分信息更像是一般性思想,没有任何具体的实现。
用于跟踪用户的位置,而应用程序没有运行(即先前已终止),有两种选择:
-
从iOS app programming guide“跟踪用户的位置”下:
强烈建议对不需要高精度位置数据的应用程序进行重大更改的位置服务。有了这项服务,只有当用户的位置发生重大变化时才会生成位置更新;因此,它非常适合向用户提供非关键的位置相关信息的社交应用或应用。如果应用程序在发生更新时暂停,系统会在后台将其唤醒以处理更新。 如果应用程序启动此服务,然后终止,系统会在新位置可用时自动重新启动应用程序。此服务在iOS 4及更高版本中可用,并且仅在包含蜂窝无线电的设备上可用。
然而,根据CLLocationManager class reference,这不是太准确,更新不频繁:
注:应用程序能够尽快期望通知,该设备从之前通知移动500米以上。它不应该比每五分钟更频繁地发出通知。如果设备能够从网络中检索数据,位置管理器更有可能及时发送通知。
-
Region Monitoring作品以类似的方式 - 包括重新启动被终止后的应用程序 - 但以更高的精度(取决于WiFi网络和蜂窝塔的情况而定):
的具体阈值距离确定通过当前可用的硬件和位置技术。例如,如果Wi-Fi已禁用,则区域监控的精确度会大大降低。但是,出于测试目的,您可以假定最小距离大约为200米。
另一个区域监测考虑是(根据CLLocationManager class reference)区域的进入和退出的通知可能仅交叉的区域的边界之后接收到3-5分钟左右。
根据实际需要,区域监控可用于获取“粗略”位置,然后当用户在特定区域内时,在位置管理器上启动更精确的基于GPS的服务。当用户离开感兴趣的区域时,关闭GPS服务以保存电池并再次返回粗略位置监测服务(即区域监测)。这是一个基本的实现:
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
是的,它看起来确实如此!尽管我们在这种情况下谈论什么精度,你有什么想法吗?因为我见过一些应用程序(没有下载它们,因为它们很昂贵),这将支持地理推送,但精度为500米左右。这对我的目的来说太过分了。我不知道你是否可以选择大约50-100米的精度,然而它总是需要多少电池才能运行。我现在更多地了解它 – donparalias 2013-03-23 22:21:41
由于重大变更的位置服务依赖于设备更换单元塔,因此可能不够好。 – gavdotnet 2013-03-23 22:32:22
但是,应该可以监听将应用程序唤醒(如果已终止)的“重大更改”通知,然后开始使用标准的后台位置服务 - 这会提供更好的准确性 - 直到应用程序再次终止。当应用程序未运行时,您当然会失去一些准确性,但其余时间与任何后台应用程序一样准确。 – gavdotnet 2013-03-23 22:45:50
的为什么你不希望在后台运行的应用程序(应用程序杀死后指)?我在我的应用程序中使用了与后台运行功能相同的概念。你能详细说明一下吗?例如, – 2013-03-23 19:57:18
。让我们说用户提醒,他想去看他的祖母时看到它。这可能是下周。肯定电话可能会被重置,或者他可能已经从后台删除了应用程序。所以即使应用没有在后台运行,我也需要推动它。你能告诉我的应用程序的名称,我真的很感兴趣,看看你已经实现:) – donparalias 2013-03-23 20:38:59
1.当应用程序死亡不可能时,GPS没有运行。 2.当您评论一个示例时,您可以从CMS端对提醒时间设置推送通知。在网络服务上,您可以设计一种算法,通过移动提醒设置发送推送通知。 – 2013-03-24 07:03:24