我设法制作了一个iBeacon,当信标在范围内时,它会在我的iPhone上触发本地推送通知。当应用程序处于后台模式时,它完全正常工作。
我的问题是:即使应用未运行,我是否可以触发通知,甚至不在后台运行?
我认为这是可能的,但我不确定。 如果是这样,我怎么能做到这一点?
谢谢!
答案 0 :(得分:64)
是的,这是可能的,应该是自动的。
创建CLBeaconRegion并开始对其进行监控后,即使您的应用未运行,位置服务也会跟踪您的手机是否进入该区域。如果您的应用程序在转换期间未运行,iOS将在后台启动您的应用程序几秒钟以调用相应的CLLocationManagerDelegate方法。
我通过自己的应用程序实验发现了上述行为,但也见证了Apple的AirLocate示例程序。使用AirLocate,如果您设置监控区域然后重新启动手机,AirLocate仍会在手机进入该区域后立即发送本地通知。
测试时要小心,因为有时在iOS识别区域状态转换之前打开/关闭iBeacon需要4分钟。 编辑:从iPhone 5开始,应用程序通常会在几秒钟内使用硬件加速来检测信标,如果硬件加速不可用,则最多可能需要15分钟。
编辑:从iOS 8开始,您需要确保已调用并成功获取locationManager.requestAlwaysAuthorization()
locationManager.requestWhenInUseAuthorization()
仅允许在前台检测到信标。
我已经在this blog post.
中详细讨论了这一切是如何运作的答案 1 :(得分:18)
好的,我已经让它正常工作并进行了实验,所以这就是答案。这是您在应用程序终止后跨越信标区域边界时调用应用程序所需要执行的操作(假设您的应用程序在前台时正常工作):
CLLocation
模块 中实施AppDelegate.m
代理 。此委托是iOS调用的内容,因此如果CLLocation
中没有AppDelegate.m
委托代码,则当您的应用终止时,您将无法响应iOS。这就是Apple的AirLocate示例应用程序。因此,在AppDelegate.m
内你需要以下内容(你还需要链接到CoreLocation.h
):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
// This location manager will be used to notify the user of region state transitions when the app has been previously terminated.
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
return YES;
}
在AppDelegate.m
内,您需要实现 locationManager didDetermineState 方法,如下所示:
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{
UILocalNotification *notification = [[UILocalNotification alloc] init];
if(state == CLRegionStateInside)
{
notification.alertBody = [NSString stringWithFormat:@"You are inside region %@", region.identifier];
}
else if(state == CLRegionStateOutside)
{
notification.alertBody = [NSString stringWithFormat:@"You are outside region %@", region.identifier];
}
else
{
return;
}
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
- >因此,如果您的应用已被终止(必须至少运行一次),当设备在您正在监控的信标边界上转换时,iOS将调用您的应用并调用AppDelegate.m模块中的locationManager:didDetermineState
方法。在此方法中,您可以设置并调用presentLocalNotificationNow。如果发生这种情况,您的应用程序不在前台,即使已锁定,iOS也会在屏幕上显示通知。然后,用户必须调用该应用程序以获取更多信息。
我很确定内存压力与此无关。此外,设置notifyEntryStateOnDisplay
也与此问题无关。设置notifyEntryStateOnDisplay
仅在用户打开iOS设备显示时使用(即点击“主页”或左上键)。如果用户执行此操作且notifyEntryStateOnDisplay
为TRUE
,并且设备位于您正在监控的信标区域内,那么此时您将在显示屏上收到通知。如果此属性设置为FALSE
,则不会。
当然,您需要运行iOS 7.1才能使这些内容正常工作。
有关详细信息,请访问Apple的documentation
答案 2 :(得分:9)
您需要为CLBeaconRegion切换notifyEntryStateOnDisplay = YES,以便系统唤醒您的应用程序以进行iBeacon进入/退出事件。
但有一个棘手的部分。如果您的应用程序未运行,系统将仅唤醒您的应用程序进行信标进入/退出处理如果您的应用程序之前由于系统内存压力而终止。如果用户通过在应用程序中向上滑动来杀死应用程序任务视图,系统不会唤醒您的应用程序。要验证此行为,请启动应用程序,将其置于后台,然后连续启动多个内存消耗应用程序。由于记忆压力,我的应用程序被系统终止之前,我推出了几款3D游戏。
答案 3 :(得分:6)
只需将您的iOS版本升级到7.1并设置" notifyEntryStateOnDisplay = YES"即使你的应用程序没有运行,它也应该像魅力一样工作。我之前遇到过这个问题但是一旦我升级了就修好了!享受..
答案 4 :(得分:2)
我能够完成这项工作的唯一方法是监控主要的位置变化,这似乎可以解决问题。请注意,我没有对所有设备或用例场景进行测试。
答案 5 :(得分:1)
是的,我们可以在kill状态或后台状态下显示本地通知,只需按照步骤进行操作,
1)使用CLLocationManager类启动位置管理器。
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy=kCLLocationAccuracyBest;
locationManager.distanceFilter=kCLDistanceFilterNone;
2)创建CLBeaconRegion,例如
CLBeaconRegion *beacon_Region = [[CLBeaconRegion alloc] initWithProximityUUID:uuid major:mjorVa minor:minorVa identifier:identifier];
beacon_Region.notifyEntryStateOnDisplay = YES;
beacon_Region.notifyOnEntry=YES;
beacon_Region.notifyOnExit=YES;
3)实现两个位置管理器委托方法,如
-didEnterRegion
-didExitRegion
以上两种位置管理器方法即使你的应用程序被杀死或在后台也可以使用。系统将跟踪您的信标,当它超出范围时,系统将触发didExitRegion方法,当进入系统时将触发didEnterRegion方法。