#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.
Вы должны проверить фоновые задачи, чтобы получить больше времени в фоновом режиме для вызова вашего сервера.