BGAppRefreshTask Фоновая задача не выполняется - PullRequest
0 голосов
/ 10 апреля 2020

Я использую новую среду фоновых задач 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, поэтому любые указатели приветствуются. Большая часть приведенного выше кода является почти копией множества учебников по этой теме. Для меня, однако, все не работает, и у меня закончились варианты!

...