Ranging Beacons работает только при запуске приложения?

У меня возникают трудности с тем, чтобы это работало, когда приложение не работает. Я реализовал locationManager:didRangeBeacons:inRegion: и вызывается, когда приложение работает на переднем плане или в фоновом режиме, однако, похоже, что он ничего не делает, когда я выхожу из приложения и блокирую экран. Значок служб местоположения уходит, и я никогда не знаю, что я вошел в диапазон маяков. Должна ли функция LocalNotification работать?

У меня есть обновления местоположения и используются аксессуары Bluetooth LE, выбранные в фоновых режимах (XCode 5). Я не думал, что они мне нужны.

Любая помощь очень ценится.

-(void)watchForEvents { // this is called from application:didFinishLaunchingWithOptions
    id class = NSClassFromString(@"CLBeaconRegion");
    if (!class) {
        return;
    }

    CLBeaconRegion * rflBeacon = [[CLBeaconRegion alloc] initWithProximityUUID:kBeaconUUID identifier:kBeaconString];
    rflBeacon.notifyOnEntry = YES;
    rflBeacon.notifyOnExit = NO;
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    [self.locationManager startRangingBeaconsInRegion:rflBeacon];
    [self.locationManager startMonitoringForRegion:rflBeacon];
}

-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
    if (beacons.count == 0 || eventRanged) { // breakpoint set here for testing
        return;
    }

    eventRanged = YES;
    if (backgroundMode) { // this is set in the EnterBackground/Foreground delegate calls
        UILocalNotification *notification = [[UILocalNotification alloc] init];
        notification.alertBody = [NSString stringWithFormat:@"Welcome to the %@ event.",region.identifier];
        notification.soundName = UILocalNotificationDefaultSoundName;
        [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
    }

    // normal processing here...
}

Ответ 1

Мониторинг может запустить приложение, которое не работает. Ранжирование не может.

Ключ к мониторингу запуска вашего приложения - установить этот плохо документированный флаг на CLBeaconRegion: r egion.notifyEntryStateOnDisplay = YES; Это может привести к появлению вашего приложения при переходе к региону даже после полной перезагрузки телефона. Но есть несколько предостережений:

  • Ваше приложение запускается в фоновом режиме всего несколько секунд. (Попробуйте добавить операторы NSLog в applicationDidEnterBackground и другие методы в AppDelegate, чтобы узнать, что происходит.)
  • iOS может принять собственное сладкое время, чтобы решить, что вы ввели CLBeaconRegion. Я видел, что это занимает до четырех минут.

Что касается выбора диапазона, несмотря на то, что вы не можете развернуть пробуждение своего приложения, вы можете сделать так, чтобы ваше приложение одновременно контролировало и оценивало. Если мониторинг пробуждает ваше приложение и помещает его в фоновом режиме в течение нескольких секунд, сразу же запускаются обратные вызовы. Это дает вам возможность выполнять любые действия быстрого действия, пока ваше приложение все еще работает.

РЕДАКТИРОВАТЬ: Дальнейшее исследование доказывает, что notifyEntryStateOnDisplay не влияет на фоновый мониторинг, поэтому вышеупомянутое должно работать независимо от того, есть ли у вас этот флаг. См. это подробное объяснение и обсуждение задержек, которые могут возникнуть

Ответ 2

Ниже приведен процесс, который вам нужно выполнить для выбора в фоновом режиме:

  • Для любого CLBeaconRegion всегда следите за тем, на заднем плане или переднем плане, и сохраняйте notifyEntryStateOnDisplay = YES
  • notifyEntryStateOnDisplay вызывает locationManager:didDetermineState:forRegion: в фоновом режиме, поэтому реализуйте этот вызов делегата...

... вот так:

- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{

   if (state == CLRegionStateInside) {


        //Start Ranging
        [manager startRangingBeaconsInRegion:region];
    }

   else{

        //Stop Ranging
        [manager stopRangingBeaconsInRegion:region];
    }

}

Надеюсь, это поможет.

Ответ 3

Код для iOS 9 для диапазона маяков в фоновом режиме, используя Обновления местоположений:

  • Открыть настройки проекта → Возможности → Режимы фона → Переключить Location Updates и Uses Bluetooth LE accessories на ON.

  • Создайте авторизацию мониторинга CLLocationManager, request Always (не забудьте добавить Application does not run in background в NO и NSLocationAlwaysUsageDescription в приложении info.plist) и установить следующие свойства:

    locationManager!.delegate = self
    locationManager!.pausesLocationUpdatesAutomatically = false
    locationManager!.allowsBackgroundLocationUpdates = true;
    
  • Начало диапазона для маяков и области мониторинга:

    locationManager!.startMonitoringForRegion(yourBeaconRegion)
    locationManager!.startRangingBeaconsInRegion(yourBeaconRegion)
    locationManager!.startUpdatingLocation()
    
    // Optionally for notifications
    UIApplication.sharedApplication().registerUserNotificationSettings(
        UIUserNotificationSettings(forTypes: .Alert, categories: nil))
    
  • Внесите CLLocationManagerDelegate и в didEnterRegion отправьте как сообщения startRangingBeaconsInRegion(), так и startUpdatingLocation() (дополнительно отправьте уведомление) и установите stopRangingBeaconsInRegion() и stopUpdatingLocation() в didExitRegion

Помните, что это решение работает, но Apple не рекомендуется Apple из-за потребления батареи и конфиденциальности клиента.

Подробнее здесь: https://community.estimote.com/hc/en-us/articles/203914068-Is-it-possible-to-use-beacon-ranging-in-the-background-

Ответ 4

Здесь вы делаете две отдельные операции - "дальнобойность" маяков и мониторинг для региона. Вы можете отслеживать область в фоновом режиме, но не располагать маяками.

Следовательно, ваша реализация locationManager:didRangeBeacons:inRegion: не будет вызвана в фоновом режиме. Вместо этого ваш вызов startMonitoringForRegion приведет к вызову одного из следующих методов:

– locationManager:didEnterRegion:
– locationManager:didExitRegion:
– locationManager:didDetermineState:forRegion:

Они будут вызваны в фоновом режиме. Вы можете в этот момент вызвать локальное уведомление, как в вашем исходном коде.

Ответ 5

Ваше приложение должно в настоящее время проснуться, если вы просто хотите получить уведомление, когда вы входите в зону маяка. Единственное ограничение фона, которое я знаю о проблемах, которое фактически поддерживает iBeacon на устройстве iOS. В этом случае приложение должно быть физически открыто на переднем плане. Для этой ситуации вам будет лучше просто выполнить прямую реализацию CoreBluetooth CBPeripheralManager. Таким образом, у вас будут некоторые рекламные способности в фоновом режиме.

Ответ 6

Вы можете делать в фоновом режиме. Однако есть улов. Пользователь должен перенести приложение на передний план, то есть когда вы начинаете ранжировать. Затем, даже если пользователь блокирует экран, и приложение идет в фоновом режиме, оно будет продолжать диапазон и вызывать обратный вызов didRangeBeacons каждые 1 секунду навсегда.

Чтобы включить обновления фонового местоположения, выберите свой проект, перейдите в раздел "Информация" и добавьте строку "Требуемые фоновые режимы". Затем добавьте релевантные элементы: обновления местоположения, обмениваются данными/передают данные через corebluetooth и т.д.

Теперь, как только вы получите обратный вызов при входе в регион, ваше приложение просыпается в фоновом режиме и уведомляет пользователя. Пользователь открывает приложение, чтобы перенести приложение на передний план. На этом этапе вы можете запустить процесс ранжирования, вызвав startRangingBeaconsInRegion. Кроме того, вызовите метод startUpdatingLocation, который обновит местоположение в фоновом режиме.