Уведомление iBeacon, когда приложение не запущено

Мне удалось создать iBeacon, который запускает локальное push-уведомление на моем iPhone, когда маяк находится в зоне действия. Он отлично работает, когда приложение находится в фоновом режиме.

Мой вопрос: могу ли я инициировать уведомление, даже если приложение не работает, даже не в фоновом режиме?

Я думал, что это возможно, но я не уверен. Если да, то как я могу это сделать?

Спасибо!

Ответ 1

Да, это возможно и должно быть автоматическим.

После того, как вы создали CLBeaconRegion и начали мониторинг на нем, Location Services будет отслеживать, находится ли ваш телефон в регионе или за его пределами, даже если ваше приложение не работает. Если ваше приложение не работает во время перехода, iOS на несколько секунд запустит ваше приложение в фоновом режиме, чтобы вызвать соответствующие методы CLLocationManagerDelegate.

Я обнаружил вышеупомянутое поведение, экспериментируя с моим собственным приложением, но также засвидетельствовал это с примером программы Apple AirLocate. С AirLocate, если вы настроили регион мониторинга, а затем перезагрузили свой телефон, AirLocate все равно будет доставлять локальное уведомление, как только телефон войдет в регион.

Будьте внимательны при тестировании, потому что иногда может потребоваться до 4 минут после включения/выключения iBeacon, прежде чем iOS распознает изменение состояния региона. РЕДАКТИРОВАТЬ. Начиная с iPhone 5, приложения обычно используют аппаратное ускорение для обнаружения маяков в течение нескольких секунд, а если аппаратное ускорение недоступно, это может занять до 15 минут.

ОБНОВЛЕНИЕ 3: Как и в iOS 13, вы должны убедиться, что пользователь фактически предоставляет фоновое разрешение, а не разрешение "только один раз" или "при использовании", которые сильно выдвигаются операционной системой в диалоговых окнах, которые они представляют пользователю, Подробности смотрите здесь.

ОБНОВЛЕНИЕ 2: Начиная с iOS 8, вам нужно убедиться, что вы вызвали и успешно получили locationManager.requestAlwaysAuthorization(), поскольку locationManager.requestWhenInUseAuthorization() позволяет только маяки обнаруживаться на переднем плане.

Я опубликовал подробное обсуждение того, как все это работает, в этой записи блога.

Ответ 2

OK Я получил это, чтобы работать правильно и экспериментировать с ним, вот и вот ответ. Это то, что вам нужно сделать, чтобы заставить ваше приложение вызываться при пересечении границы области маяка после того, как приложение было прервано (если ваше приложение работает правильно на переднем плане):

  • Вы должны реализовать делегат 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;
}
  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];
     }
    

- > Итак, если ваше приложение было прервано (оно должно выполняться как минимум ONCE), когда устройство переходит на границу маяка, которую вы контролируете, iOS вызовет ваше приложение и вызовет метод locationManager:didDetermineState в вашем Модуль AppDelegate.m. Внутри этого метода вы можете настроить и вызвать presentLocalNotificationNow. Если ваше приложение НЕ находится на переднем плане, когда это произойдет, iOS представит уведомление на экране, даже если оно заблокировано. Затем пользователю необходимо будет вызвать приложение для получения дополнительной информации.

Я почти уверен, что давление памяти не имеет к этому никакого отношения. Кроме того, установка notifyEntryStateOnDisplay не имеет ничего общего с этой проблемой. Настройка notifyEntryStateOnDisplay используется только тогда, когда пользователь включает дисплей устройства iOS (т.е. попадает в "домашнюю" или верхнюю левую кнопку). Если пользователь делает это, а notifyEntryStateOnDisplay - TRUE, И устройство INSIDE - область маяка, на которую вы отслеживаете, THEN вы получаете уведомление на дисплее в это время. Если для этого свойства установлено значение FALSE, вы этого не сделаете.

Конечно, для корректной работы этого материала вам нужно запустить iOS 7.1.

Для получения дополнительной информации посетите Apple documentation

Ответ 3

Вам нужно переключить notifyEntryStateOnDisplay = YES для CLBeaconRegion, чтобы система разбудила ваше приложение для входа/выхода iBeonon.

Но есть одна сложная часть. Если ваше приложение не запущено, система только разбудит ваше приложение для входа/выхода с маяком , если ваше приложение было прервано ранее из-за давления в системной памяти. Если пользователь убил приложение, проверив его в задача, система не разбудит ваше приложение. Чтобы проверить это поведение, запустите приложение, поместите его в фоновый режим, затем последовательно запустите несколько приложений, потребляющих память. Я запустил несколько 3D-игр, прежде чем мое приложение завершится системой из-за давления в памяти.

Ответ 4

Просто обновите версию iOS до 7.1 и установите "notifyEntryStateOnDisplay = YES", и она должна работать как шарм, даже если ваше приложение не работает. У меня была эта проблема раньше, но она была исправлена ​​после того, как я сделал это обновление! Наслаждайтесь..

Ответ 5

Единственный способ, которым я смог выполнить эту работу, - это мониторинг основных изменений местоположения, которые, похоже, делают трюк. Будьте осторожны, я не тестировал это для всего устройства или сценариев использования.

Ответ 6

Да, мы можем представить локальное уведомление в состоянии 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.