Диапазон маяков в фоновом режиме

#ios #api #background #ibeacon

#iOS #API #фон #ibeacon

Вопрос:

Я разрабатываю приложение, которое подключается к маякам. Я могу запускать приложение, а также обнаруживать маяки, когда приложение работает в фоновом режиме (я отправляю локальные уведомления в методе didRangeBeacons и получаю их). Мне нужно запустить фрагмент кода в фоновом режиме при обнаружении маяка. Как я могу сделать? Я попытался записать свой вызов Alamofire точно после отправки локального уведомления, но ничего не происходит. Какие-то предложения?

Ответ №1:

Когда приложение работает в фоновом режиме и получает didRangeBeacons обратный вызов, операционная система запускает его всего за 5 секунд до того, как оно будет приостановлено. Это закроет все открытые в это время подключения к веб-службам. По запросу вы можете увеличить время работы в фоновом режиме с 5 секунд до 180 секунд. Ниже приведен пример в Swift 3, который показывает, как это сделать.

 var threadStarted = false
var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid

func extendBackgroundRunningTime() {
  if (self.backgroundTask != UIBackgroundTaskInvalid) {
    // if we are in here, that means the background task is already running.
    // don't restart it.
    return
  }

  print("Attempting to extend background running time")

  self.backgroundTask = UIApplication.shared.beginBackgroundTask(withName: "DummyTask", expirationHandler: {
    UIApplication.shared.endBackgroundTask(self.backgroundTask)
    self.backgroundTask = UIBackgroundTaskInvalid
  })

  if threadStarted {
    print("Background task thread already started.")
  }
  else {
    threadStarted = true
    DispatchQueue.global(priority: DispatchQueue.GlobalQueuePriority.default).async {
      while (true) {
        // A dummy tasks must be running otherwise iOS suspends immediately
        Thread.sleep(forTimeInterval: 1);
      }
    }
  }
}
  

Добавляя подобный код, гораздо более вероятно, что вызов вашей веб-службы завершится до того, как iOS приостановит ваше приложение.

Вы можете вызвать extendBackgroundRunningTime() из своих didRangeBeacons didEnterRegion методов или.

Комментарии:

1. Кажется, это работает довольно хорошо! Спасибо! У меня проблема только с методом didRangeBeacons, который через некоторое время вызывает это сообщение в отладчике: «Завершено из-за проблемы с памятью». Я предполагаю, что это вызвано слишком большим количеством вызовов веб-службы, поэтому теперь мне нужно каким-то образом регулировать вызовы

2. Очевидно, что вы не можете запускать вызов веб-службы при каждом обратном вызове диапазона — это будет ставить его в очередь каждую секунду. Возможно, я бы установил флаг при выполнении вызова, очистил его при его возврате и не выполнял новый вызов, если флаг установлен.

3. да, это может быть идеей, или даже постоянно сохранять временную метку последнего вызова и создавать новую, только если текущая временная метка составляет не менее, idk, 5 минут после последнего, что-то вроде этого.

Ответ №2:

У вас есть только ограниченное время для выполнения работы в фоновом режиме, когда вы получаете обратный вызов didEnter / didRange.

Вы должны проверить фоновые задачи, чтобы получить больше времени в фоновом режиме для вызова вашего сервера.