Я использую новую среду фоновых задач iOS13 с реализацией типа BGAppRefreshTask. Моя проблема в том, что мое устройство никогда не вызывает задачу, даже после ожидания нескольких часов, но я могу успешно выполнить код, используя прием отладчика вызова _simulateLaunchForTaskWithIdentifier.
Я настроил следующее:
- Включено мое приложение с возможностью «Фоновые режимы», проверка «Фоновая выборка».
- Добавлен мой идентификатор фона в Info.plist в разделе «Разрешенные идентификаторы планировщика фоновых задач»: «com.XYZ .PearWeather.backgroundAlerts ".
Я зарегистрировал задачу из приложения (didFinishLaunchingWithOptions) в моем AppDelegate:
BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.XYZ.PearWeather.backgroundAlerts", using: nil) { task in
self.backgroundAlerts(task: task as! BGAppRefreshTask)
}
Я планирую задачу в забавном c в AppDelegate и вызов его из моего SceneDelegate sceneDidEnterBackground (). Первоначально это было stati c fun c, но теперь я изменил его на экземпляр fun c и получаю экземпляр AppDelegate (так как я попробовал много изменений в отчаянии):
func sceneDidEnterBackground(_ scene: UIScene) {
(UIApplication.shared.delegate as! AppDelegate).scheduleBackgroundAlerts()
}
func scheduleBackgroundAlerts() {
let request = BGAppRefreshTaskRequest(identifier: "com.XYZ.PearWeather.backgroundAlerts")
request.earliestBeginDate = Date(timeIntervalSinceNow: 5 * 60)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh: \(error)")
}
}
По крайней мере в сценарии отладчика, нет ошибки при вызове отправки. Я пробовал много разных значений для параметра timeIntervalSinceNow выше. Я также вызываю этот scheduleBackgroundAlerts () fun c из самого обработчика задачи, а именно:
func backgroundAlerts(task: BGAppRefreshTask) {
scheduleBackgroundAlerts()
task.expirationHandler = {
// After all operations are cancelled, the completion block below is called to set the task to complete.
task.setTaskCompleted(success: false)
}
AlertsOperation.showNotification()
task.setTaskCompleted(success: true)
}
Эта реализация сильно изменилась - я изначально использовал OperationQueue, пытался разместить scheduleBackgroundAlerts () вызов в начале и в конце веселья c, et c. Теперь это урезано. AlertOperation.showNotification () теперь также очень прост:
static func showNotification() {
let now = Date()
let bg = Locale.currentLocale().formattedTime(date: now)
SettingsManager.shared.settings.bg = bg
}
Это просто сохранение значения в UserDefaults (в моем SettingsManager, подробности которого здесь не актуальны), которое я могу прочитать обратно в мое приложение, чтобы увидеть, произошло ли что-нибудь.
Теперь оригинальная реализация этого забавного c выдает локальное уведомление с использованием UNUserNotificationCenter et c, что я и пытаюсь сделать в этой фоновой задаче. Это хорошо работало с отладчиком, но я сократил его до этого простого кода, просто чтобы сделать очень маленькую реализацию.
Как я уже сказал, вызов обработчика задач из отладчика работает нормально, используя:
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.XYZ.PearWeather.backgroundAlerts"]
Но с самого устройства ничего не происходит. Я не вижу, что я пропустил. Я также не знаю, как регистрировать какие-либо исключения из обработчика фоновых задач.
Я новичок в Swift и iOS, поэтому любые указатели приветствуются. Большая часть приведенного выше кода является почти копией множества учебников по этой теме. Для меня, однако, все не работает, и у меня закончились варианты!