应用程序未运行时的iBeacon通知

Lap*_*dus 57 ios core-bluetooth ios7 ibeacon

我设法制作了一个iBeacon,当信标在范围内时,它会在我的iPhone上触发本地推送通知.当应用程序处于后台模式时,它完全正常工作.

我的问题是:即使应用程序没有运行,我是否可以触发通知,甚至不在后台运行?

我认为这是可能的,但我不确定.如果是这样,我怎么能做到这一点?

谢谢!

dav*_*ung 65

是的,它是可能的,应该是自动的.

创建CLBeaconRegion并开始对其进行监控后,即使您的应用未运行,位置服务也会跟踪您的手机是否在该区域内.如果您的应用程序在转换期间未运行,iOS将在后台启动您的应用程序几秒钟以调用相应的CLLocationManagerDelegate方法.

我通过自己的应用程序实验发现了上述行为,但也见证了Apple的AirLocate示例程序.使用AirLocate,如果您设置监控区域然后重新启动手机,AirLocate仍会在手机进入该区域后立即发送本地通知.

在测试时要小心,因为有时在iOS识别区域状态转换之前打开/关闭iBeacon需要4分钟. 编辑:从iPhone 5开始,应用程序通常会在几秒钟内使用硬件加速来检测信标,如果硬件加速不可用,则最多可能需要15分钟.

编辑: 从iOS 8开始,您需要确保已经调用并成功获取,locationManager.requestAlwaysAuthorization()因为locationManager.requestWhenInUseAuthorization()只有前景中可以检测到信标.

我已经在这篇博客文章中详细讨论了这一切是如何运作的.

  • @davidgyoung好的,在对我可能想到的所有事物进行了大量测试之后,由于某种原因,设备重启后,`-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region`将被触发,但是`didEnterRegion`将不会被触发。我已经将逻辑转移到该方法中。很奇怪 (2认同)

TNB*_*ech 18

好的,我已经让它正常工作并进行了实验,所以这就是答案.这是您在应用程序终止后跨越信标区边界时调用应用程序所需要执行的操作(假设您的应用程序在前台时正常工作):

  1. 您必须模块中实现CLLocation委托.此委托是iOS调用的,因此如果您没有委托代码,则在您的应用程序终止时,您将无法响应iOS.这就是Apple的AirLocate示例应用程序所做的.AppDelegate.mCLLocationAppDelegate.m

所以,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;
}
Run Code Online (Sandbox Code Playgroud)
  1. 在里面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];
     }
    
    Run Code Online (Sandbox Code Playgroud)

- >因此,如果您的应用程序已被终止(它必须至少运行一次),当设备在您正在监视的信标边界上转换时,iOS将调用您的应用程序并locationManager:didDetermineState在AppDelegate.m模块中调用该方法.在此方法中,您可以设置并调用presentLocalNotificationNow.如果发生这种情况,您的应用程序不在前台,即使已锁定,iOS也会在屏幕上显示通知.然后,用户必须调用该应用程序以获取更多信息.

我很确定内存压力与此无关.此外,该设置notifyEntryStateOnDisplay也与此问题无关.设置notifyEntryStateOnDisplay仅在用户打开iOS设备显示屏时使用(即点击"主页"或左上键).如果用户执行此操作并且notifyEntryStateOnDisplayTRUE,并且设备位于您正在监视的信标区域内,那么此时您将在显示屏上收到通知.如果将此属性设置为FALSE,则不会.

当然,您需要运行iOS 7.1才能使这些东西正常工作.

有关更多详细信息,请访问Apple的文档

  • CLLocation委托给AppDelegate +1,谢谢! (3认同)

小智 9

您需要为CLBeaconRegion切换notifyEntryStateOnDisplay = YES,以便系统唤醒您的应用程序以进行iBeacon进入/退出事件.

但有一个棘手的部分.如果您的应用程序未运行,系统将仅唤醒您的应用程序以进行信标进入/退出处理(如果您的应用程序之前由于系统内存压力而终止).如果用户通过在任务视图中向上滑动来杀死应用程序,系统将不会唤醒您的应用程序.要验证此行为,请启动应用程序,将其置于后台,然后连续启动多个内存消耗应用程序.由于内存压力,我的应用程序被系统终止之前,我推出了几款3D游戏.

  • 您的评论似乎仅适用于iOS 7.0.使用iOS 7.1,应用程序似乎无论如何都会唤醒:http://beekn.net/2014/03/apple-ios-7-1-launches-major-ibeacon-improvement/ (4认同)

Hug*_*zue 6

只需将您的iOS版本升级到7.1并设置"notifyEntryStateOnDisplay = YES",即使您的应用未运行,它也应该像魅力一样.我之前遇到过这个问题但是一旦我升级了就修好了!请享用..