![](/img/trans.png)
[英]iBeacon: didRangeBeacons is not getting called when running app
[英]iBeacon Notification when the app is not running
我设法制作了一个iBeacon,当该信标在范围内时,它会在我的iPhone上触发本地推送通知。 当应用程序处于后台模式时,它可以完美运行。
我的问题是:即使应用未运行,甚至不在后台,我都可以触发通知吗?
我以为这是可能的,但我不确定。 如果是这样,我该怎么做?
谢谢!
是的,这是可能的,应该是自动的。
创建CLBeaconRegion并开始对其进行监视之后,即使您的应用程序未运行,Location Services也会跟踪您的手机在该区域内还是不在该区域之外。 如果您的应用程序在过渡期间没有运行,iOS将在后台启动您的应用程序几秒钟,以调用适当的CLLocationManagerDelegate方法。
我通过试验自己的应用程序发现了上述行为,但还通过Apple的AirLocate示例程序进行了见证。 使用AirLocate,如果您设置了监视区域,然后重新启动电话,则AirLocate仍会在电话进入该区域后立即发出本地通知。
测试时要小心,因为有时在打开/关闭iBeacon之后最多需要4分钟才能使iOS识别区域状态转换。 编辑 :从iPhone 5开始,应用程序通常会在几秒钟内使用硬件加速来检测信标,如果硬件加速不可用,则可能最多需要15分钟。
编辑3:在iOS 13上,您必须确保用户实际上授予了后台权限,而不是“仅一次”或“使用时”权限,这些权限由操作系统在向用户显示的对话框中大量推送。 有关详细信息,请参见此处 。
编辑2:从iOS 8开始,您需要确保已调用并成功获取locationManager.requestAlwaysAuthorization()
作为locationManager.requestWhenInUseAuthorization()
仅允许在前台检测信标。
好的,我已经使它能够正常工作并对其进行了实验,因此这就是答案。 这是在终止应用程序后越过信标区域边界时要使应用程序被调用所需的操作(假设您的应用程序在前景中运行正常):
AppDelegate.m
模块内实现CLLocation
委托。 此委托是由iOS调用的,因此,如果您在AppDelegate.m
没有CLLocation
委托代码,则您的应用终止后将无法响应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的文档。
您需要为CLBeaconRegion切换notifyEntryStateOnDisplay = YES,以使系统为iBeacon进入/退出事件唤醒您的应用程序。
但是有一个棘手的部分。 如果您的应用程序未在运行, 那么如果您的应用程序先前由于系统内存不足而终止,则系统只会唤醒您的应用程序以进行信标进入/退出处理。 如果用户通过在任务视图中向上滑动来杀死应用程序,则系统将不会唤醒您的应用程序。 要验证此行为,请启动您的应用程序,将其置于后台,然后连续启动多个消耗内存的应用程序。 在我的应用由于内存压力而被系统终止之前,我启动了一些3D游戏。
只需将您的iOS版本升级到7.1并设置“ notifyEntryStateOnDisplay = YES”,即使您的应用未运行,它也应该像超级按钮一样工作。 我之前有这个问题,但是一旦完成升级,它就可以解决! 请享用..
我能够进行这项工作的唯一方法是监视似乎可以解决问题的主要位置更改。 请注意,我尚未针对所有设备或用例场景对此进行测试。
是的,我们可以按照杀死状态或后台状态显示本地通知,只需按照以下步骤操作,
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方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.