当应用程序没有运行时,iBeacon通知。

时间:2023-01-23 14:59:50

I managed to make an iBeacon which triggers a local push notification on my iPhone when the beacon is in range. It's perfectly working when the app is in background mode.

我成功地制作了一个iBeacon,当beacon在我的iPhone上时,它会在我的iPhone上触发一个本地推送通知。当应用处于后台模式时,它运行得很好。

My question is: Can I trigger the notification even when the app is not running, not even in the background?

我的问题是:即使应用程序没有运行,即使在后台,我也能触发通知吗?

I thought this was possible but I'm not sure. If so, how can I accomplish this?

我以为这是可能的,但我不确定。如果是的话,我该怎么做呢?

Thanks!

谢谢!

6 个解决方案

#1


64  

Yes, it's possible and should be automatic.

是的,这是可能的,应该是自动的。

After you have created a CLBeaconRegion and started monitoring on it, Location Services will keep track of whether your phone is in or out of the region, even when your app isn't running. If you app isn't running during a transition, iOS will launch your app into the background for a few seconds to call the appropriate CLLocationManagerDelegate methods.

创建了CLBeaconRegion并开始对其进行监视之后,位置服务将跟踪您的手机是在该区域内还是在该区域外,即使您的应用程序没有运行。如果您的应用程序在转换过程中没有运行,iOS会将您的应用程序启动到后台几秒钟,以调用适当的CLLocationManagerDelegate方法。

I found out the above behavior through experimentation with my own app, but have also witnessed it with Apple's AirLocate sample program. With AirLocate, if you set up a monitoring region then reboot your phone, AirLocate will still deliver a local notification as soon as the phone enters the region.

通过我自己的应用程序,我通过实验发现了上述行为,但也在苹果的AirLocate sample程序中看到了它。使用AirLocate,如果你设置了一个监控区域,然后重新启动你的手机,一旦手机进入该区域,AirLocate仍然会发送一个本地通知。

Take care when testing this, because sometimes it takes up to 4 minutes after turning on/off an iBeacon before iOS recognizes the region state transition. EDIT: As of the iPhone 5, apps will typically use hardware acceleration to detect beacons within a few seconds, and if hardware acceleration is not available, it can take up to 15 minutes.

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

EDIT: As of iOS 8, you need to make sure you have called and successfully obtained locationManager.requestAlwaysAuthorization() as locationManager.requestWhenInUseAuthorization() only lets beacons be detected in the foreground.

编辑:在ios8中,您需要确保已经调用并成功获得locationManager.requestAlwaysAuthorization()作为locationManager.requestWhenInUseAuthorization()只允许在前台检测信标。

I have posted a detailed discussion on how this all works in this blog post.

我在这篇博文中详细讨论了这一切是如何运作的。

#2


18  

OK I've gotten this to work correctly and experimented around with it so here is the answer. This is what you need to do to get your app to be invoked when crossing a beacon region boundary after the app has been terminated (assuming your app works properly when in the foreground):

好的,我已经把它正确地进行了实验,这就是答案。这是你需要做的,当你的应用程序在结束后跨越信标区域边界时(假设你的应用程序在前景中正常工作):

  1. You must implement a CLLocation delegate inside your AppDelegate.m module. This delegate is what gets invoked by iOS so if you don't have the CLLocation delegate code in AppDelegate.m, you won't be able to respond to iOS when your app has been terminated. This is what Apple's AirLocate sample app does.
  2. 您必须在AppDelegate中实现CLLocation委托。m模块。这个委托被iOS调用,如果AppDelegate中没有CLLocation委托代码。m,当你的应用程序被终止时,你将无法回复iOS。这就是苹果的AirLocate示例应用程序所做的。

So, inside AppDelegate.m you need the following (you also need to link in CoreLocation.h):

所以,在AppDelegate。m您需要以下(您还需要在coreloc.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;
}
  1. Inside AppDelegate.m, you need to implement the locationManager didDetermineState method, like this:

    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];
     }
    

--> So if your app has been terminated (it must be run at least ONCE), when the device transitions across a beacon boundary that you are monitoring, iOS will invoke your app and call the locationManager:didDetermineState method in your AppDelegate.m module. Inside this method you can then set up and call presentLocalNotificationNow. If your app is NOT in the foreground when this happens, iOS will present the notification on the screen even if it is locked. The user will then have to invoke the app for more information.

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

I'm pretty sure that memory pressure has nothing to do with this. Also, the setting notifyEntryStateOnDisplay has nothing to do this this issue either. Setting notifyEntryStateOnDisplay is only used when the user turns on the iOS device display (ie hits "home" or top left button). If the user does this and notifyEntryStateOnDisplay is TRUE, AND the device is INSIDE the beacon region you are monitoring for, THEN you get a notification on the display at that time. If this property is set to FALSE, you don't.

我很确定记忆压力和这个没有关系。同样,设置notifyEntryStateOnDisplay也没有处理此问题。设置notifyEntryStateOnDisplay只在用户打开iOS设备显示(即点击“home”或左上角按钮)时使用。如果用户这样做并且notifyEntryStateOnDisplay是TRUE,并且设备位于您要监视的beacon区域内,那么此时您将在显示中获得通知。如果该属性被设置为FALSE,则不会。

Of course, you need to be running iOS 7.1 in order for this stuff to work correctly.

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

For more details, visit Apple's documentation

有关更多细节,请访问苹果的文档

#3


9  

You need to switch notifyEntryStateOnDisplay=YES for CLBeaconRegion for the system to wake your app for iBeacon entry/exit event.

您需要切换notifyEntryStateOnDisplay=YES for CLBeaconRegion for the system以唤醒iBeacon进入/退出事件的应用程序。

But there is one tricky part. If your app is not running the system will only wake your app for beacon entry/exit handling if your app was terminated previously due to system memory pressure. If the user kills the app by swiping it up in the task view, the system will not wake your app. To verify this behaviour, launch you app, put it to background, then consecutively launch several memory consuming apps. I launched several 3D games before my app gets terminated by the system due to memory pressure.

但有一个棘手的部分。如果您的应用程序没有运行,系统只会唤醒您的应用程序进行信标进入/退出处理,如果您的应用程序之前由于系统内存压力而终止。如果用户通过在任务视图中滑动来关闭应用程序,系统将不会唤醒你的应用程序。为了验证这种行为,启动你的应用程序,把它放到后台,然后连续启动几个内存消耗应用程序。在我的应用程序因为内存压力而被系统终止之前,我发布了几个3D游戏。

#4


6  

Just upgrade your iOS version to 7.1 and set "notifyEntryStateOnDisplay=YES" and it should work like a charm even when your app is not running. I was having this problem earlier but it got fixed once I did this upgrade! Enjoy..

只要将你的iOS版本升级到7.1,并设置“notifyEntryStateOnDisplay=YES”,即使你的应用程序没有运行,它也会像魔法一样发挥作用。我之前遇到过这个问题,但是当我升级的时候它就被修复了!享受. .

#5


2  

The only way I have been able to make this work is by monitoring for major location changes which seem to do the trick. Be warned I have not tested this for all of the device or use case scenarios.

我能做这项工作的唯一方法是通过监控主要的位置变化,而这些变化似乎可以做到这一点。请注意,我没有对所有设备或用例场景进行测试。

#6


1  

Yes, we can present the local notification in kill state or in the background state, just follow the steps,

是的,我们可以在kill状态或background状态下显示本地通知,按照下面的步骤,

1) Start location manager using CLLocationManager class.

1)使用CLLocationManager类启动位置管理器。

locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy=kCLLocationAccuracyBest;
locationManager.distanceFilter=kCLDistanceFilterNone;

2) Create CLBeaconRegion like,

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) Implement two location manager delegate method like,

3)实现两个位置管理器委托方法,

-didEnterRegion
-didExitRegion

The above two location manager method will work even your app is kill or in background. The system will keep track of your beacon and when it goes out of the range the system will fire the didExitRegion method and when comes in the system will fire the didEnterRegion method.

以上两个位置管理器方法将会工作,甚至你的应用程序被杀死或在后台。系统会跟踪你的信标,当信标超出范围时系统会触发didExitRegion方法,当系统进入时,系统会触发didEnterRegion方法。

#1


64  

Yes, it's possible and should be automatic.

是的,这是可能的,应该是自动的。

After you have created a CLBeaconRegion and started monitoring on it, Location Services will keep track of whether your phone is in or out of the region, even when your app isn't running. If you app isn't running during a transition, iOS will launch your app into the background for a few seconds to call the appropriate CLLocationManagerDelegate methods.

创建了CLBeaconRegion并开始对其进行监视之后,位置服务将跟踪您的手机是在该区域内还是在该区域外,即使您的应用程序没有运行。如果您的应用程序在转换过程中没有运行,iOS会将您的应用程序启动到后台几秒钟,以调用适当的CLLocationManagerDelegate方法。

I found out the above behavior through experimentation with my own app, but have also witnessed it with Apple's AirLocate sample program. With AirLocate, if you set up a monitoring region then reboot your phone, AirLocate will still deliver a local notification as soon as the phone enters the region.

通过我自己的应用程序,我通过实验发现了上述行为,但也在苹果的AirLocate sample程序中看到了它。使用AirLocate,如果你设置了一个监控区域,然后重新启动你的手机,一旦手机进入该区域,AirLocate仍然会发送一个本地通知。

Take care when testing this, because sometimes it takes up to 4 minutes after turning on/off an iBeacon before iOS recognizes the region state transition. EDIT: As of the iPhone 5, apps will typically use hardware acceleration to detect beacons within a few seconds, and if hardware acceleration is not available, it can take up to 15 minutes.

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

EDIT: As of iOS 8, you need to make sure you have called and successfully obtained locationManager.requestAlwaysAuthorization() as locationManager.requestWhenInUseAuthorization() only lets beacons be detected in the foreground.

编辑:在ios8中,您需要确保已经调用并成功获得locationManager.requestAlwaysAuthorization()作为locationManager.requestWhenInUseAuthorization()只允许在前台检测信标。

I have posted a detailed discussion on how this all works in this blog post.

我在这篇博文中详细讨论了这一切是如何运作的。

#2


18  

OK I've gotten this to work correctly and experimented around with it so here is the answer. This is what you need to do to get your app to be invoked when crossing a beacon region boundary after the app has been terminated (assuming your app works properly when in the foreground):

好的,我已经把它正确地进行了实验,这就是答案。这是你需要做的,当你的应用程序在结束后跨越信标区域边界时(假设你的应用程序在前景中正常工作):

  1. You must implement a CLLocation delegate inside your AppDelegate.m module. This delegate is what gets invoked by iOS so if you don't have the CLLocation delegate code in AppDelegate.m, you won't be able to respond to iOS when your app has been terminated. This is what Apple's AirLocate sample app does.
  2. 您必须在AppDelegate中实现CLLocation委托。m模块。这个委托被iOS调用,如果AppDelegate中没有CLLocation委托代码。m,当你的应用程序被终止时,你将无法回复iOS。这就是苹果的AirLocate示例应用程序所做的。

So, inside AppDelegate.m you need the following (you also need to link in CoreLocation.h):

所以,在AppDelegate。m您需要以下(您还需要在coreloc.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;
}
  1. Inside AppDelegate.m, you need to implement the locationManager didDetermineState method, like this:

    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];
     }
    

--> So if your app has been terminated (it must be run at least ONCE), when the device transitions across a beacon boundary that you are monitoring, iOS will invoke your app and call the locationManager:didDetermineState method in your AppDelegate.m module. Inside this method you can then set up and call presentLocalNotificationNow. If your app is NOT in the foreground when this happens, iOS will present the notification on the screen even if it is locked. The user will then have to invoke the app for more information.

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

I'm pretty sure that memory pressure has nothing to do with this. Also, the setting notifyEntryStateOnDisplay has nothing to do this this issue either. Setting notifyEntryStateOnDisplay is only used when the user turns on the iOS device display (ie hits "home" or top left button). If the user does this and notifyEntryStateOnDisplay is TRUE, AND the device is INSIDE the beacon region you are monitoring for, THEN you get a notification on the display at that time. If this property is set to FALSE, you don't.

我很确定记忆压力和这个没有关系。同样,设置notifyEntryStateOnDisplay也没有处理此问题。设置notifyEntryStateOnDisplay只在用户打开iOS设备显示(即点击“home”或左上角按钮)时使用。如果用户这样做并且notifyEntryStateOnDisplay是TRUE,并且设备位于您要监视的beacon区域内,那么此时您将在显示中获得通知。如果该属性被设置为FALSE,则不会。

Of course, you need to be running iOS 7.1 in order for this stuff to work correctly.

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

For more details, visit Apple's documentation

有关更多细节,请访问苹果的文档

#3


9  

You need to switch notifyEntryStateOnDisplay=YES for CLBeaconRegion for the system to wake your app for iBeacon entry/exit event.

您需要切换notifyEntryStateOnDisplay=YES for CLBeaconRegion for the system以唤醒iBeacon进入/退出事件的应用程序。

But there is one tricky part. If your app is not running the system will only wake your app for beacon entry/exit handling if your app was terminated previously due to system memory pressure. If the user kills the app by swiping it up in the task view, the system will not wake your app. To verify this behaviour, launch you app, put it to background, then consecutively launch several memory consuming apps. I launched several 3D games before my app gets terminated by the system due to memory pressure.

但有一个棘手的部分。如果您的应用程序没有运行,系统只会唤醒您的应用程序进行信标进入/退出处理,如果您的应用程序之前由于系统内存压力而终止。如果用户通过在任务视图中滑动来关闭应用程序,系统将不会唤醒你的应用程序。为了验证这种行为,启动你的应用程序,把它放到后台,然后连续启动几个内存消耗应用程序。在我的应用程序因为内存压力而被系统终止之前,我发布了几个3D游戏。

#4


6  

Just upgrade your iOS version to 7.1 and set "notifyEntryStateOnDisplay=YES" and it should work like a charm even when your app is not running. I was having this problem earlier but it got fixed once I did this upgrade! Enjoy..

只要将你的iOS版本升级到7.1,并设置“notifyEntryStateOnDisplay=YES”,即使你的应用程序没有运行,它也会像魔法一样发挥作用。我之前遇到过这个问题,但是当我升级的时候它就被修复了!享受. .

#5


2  

The only way I have been able to make this work is by monitoring for major location changes which seem to do the trick. Be warned I have not tested this for all of the device or use case scenarios.

我能做这项工作的唯一方法是通过监控主要的位置变化,而这些变化似乎可以做到这一点。请注意,我没有对所有设备或用例场景进行测试。

#6


1  

Yes, we can present the local notification in kill state or in the background state, just follow the steps,

是的,我们可以在kill状态或background状态下显示本地通知,按照下面的步骤,

1) Start location manager using CLLocationManager class.

1)使用CLLocationManager类启动位置管理器。

locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy=kCLLocationAccuracyBest;
locationManager.distanceFilter=kCLDistanceFilterNone;

2) Create CLBeaconRegion like,

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) Implement two location manager delegate method like,

3)实现两个位置管理器委托方法,

-didEnterRegion
-didExitRegion

The above two location manager method will work even your app is kill or in background. The system will keep track of your beacon and when it goes out of the range the system will fire the didExitRegion method and when comes in the system will fire the didEnterRegion method.

以上两个位置管理器方法将会工作,甚至你的应用程序被杀死或在后台。系统会跟踪你的信标,当信标超出范围时系统会触发didExitRegion方法,当系统进入时,系统会触发didEnterRegion方法。