Фоновая задача, не вызывающая класс в Swift

У меня есть фоновая задача, которая должна возвращать массив курсов, которые затем отправляются на часы с яблоками. Я вызываю задачу внутри didReceiveMessageчерез WatchConnectivity.

Фоновая задача должна выполнять несколько операций, таких как открытие базы данных области, запрос результатов и доступ к каталогу документов, прежде чем вернуть ответ на словарь курсов. Логика, похоже, работает, так как часы выходят из получаемых данных курса. Проблема в том, что я не думаю, что фоновая задача на самом деле вызывает методgetWatchCourses()

DispatchQueue.global().async {

    var foundCourses = [[String : Any]]()
    let application = UIApplication.shared
    backgroundTask = application.beginBackgroundTask(withName: "app.test.getCourses") {
        let watchModel = WatchCourseModel()
        let courses = watchModel.getWatchCourses()
        print("Courses: (courses)")
        foundCourses.append(contentsOf: courses)
    }
    replyHandler(["response": foundCourses])
    application.endBackgroundTask(backgroundTask)
    backgroundTask = UIBackgroundTaskInvalid
}

Это также не работает, если getWatchCourses()результат жестко запрограммирован. Может ли приложение выполнить эту логику в фоновом режиме или работать?

Также стоит отметить, что нигде в Интернете это не задокументировано. Они всегда ссылаются на отправку простых текстовых ответов на часы, а не на то, что процессор интенсивный :(

благодаря

ios,swift,watchkit,uibackgroundtask,

2

Ответов: 3


2

Вы делаете свою операцию в закрывающем закрытии, которое используется для очистки. И еще, что вы заканчиваете фоновое задание, как только оно начинается, так что ваше закрытие никогда не вызовет.

Вот рабочий пример работы фоновой задачи

 var backgroundTaskIdentifier:UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
 var updateTimer: Timer?

Теперь, когда вы запускаете свою операцию для примера запуска таймера

  updateTimer = Timer.scheduledTimer(timeInterval: 0.5, target: self,
                                     selector: #selector(calculateNextNumber), userInfo: nil, repeats: true)
  // register background task
  beginBackgroundTask()

и когда вы заканчиваете конец таймера фоновой задачей; всегда должен заканчивать фоновые задачи

func beginBackgroundTask () {
    backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask(expirationHandler: { [weak self] in
      self?.endBackgroundTask() // It will call to cleanup 
    })
    assert(backgroundTaskIdentifier != UIBackgroundTaskInvalid)
  }

  func endBackgroundTask () {
    UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier)
    backgroundTaskIdentifier = UIBackgroundTaskInvalid
  }

Итак, в вашем случае

  • Зарегистрируйтесь для фоновой задачи
  • Запросить свою базу данных (выполнить все операции)
  • Когда вы закончите фоновое задание завершения вызова

Примечание. Также обратите внимание на ограничение времени, заданное яблоком для выполнения фоновой задачи

РЕДАКТИРОВАТЬ

Удостоверьтесь, что вы включили возможности фона, используя параметры проекта

Попробуйте

    beginBackgroundTask()

    let watchModel = WatchCourseModel()
    let courses = watchModel.getWatchCourses()
    print("Courses: (courses)")
    foundCourses.append(contentsOf: courses)
    endBackgroundTask()

1

Если вы проверите документацию, вы увидите, что полный прототип функцииbeginBackgroundTask(withName:expirationHandler:)

Код, который вы указали с помощью закрывающего закрытия, expirationHandler- это код, который вызывается, если вы не вызываете endBackgroundTaskдо того, как исчерпано допустимое время выполнения фона. Обработчик срока действия дает вам окончательную возможность выполнить любую очистку до того, как ваше приложение будет завершено за превышение его фонового времени.

Поскольку вы почти сразу вызываете endBackgroundTaskи возвращаетесь из функции, обработчик истечения не будет вызываться.

То, что вы действительно хотите, это что-то вроде:

var foundCourses = [[String : Any]]()
let application = UIApplication.shared
backgroundTask = application.beginBackgroundTask(withName: "app.test.getCourses") {
DispatchQueue.global().async {
    let watchModel = WatchCourseModel()
    let courses = watchModel.getWatchCourses()
    print("Courses: (courses)")
    foundCourses.append(contentsOf: courses)
    replyHandler(["response": foundCourses])
    application.endBackgroundTask(backgroundTask)
    backgroundTask = UIBackgroundTaskInvalid
}

Это запустит фоновое задание, затем вы выполните работу асинхронно и передайте результат обратно на часы и завершите фоновое задание.


0

Вы можете создать фоновое задание, используя тип QOS как .background

DispatchQueue.global(qos: .background).async {
        //background code
        var foundCourses = [[String : Any]]()
        let application = UIApplication.shared
        backgroundTask = application.beginBackgroundTask(withName: "app.test.getCourses") {
            let watchModel = WatchCourseModel()
            let courses = watchModel.getWatchCourses()
            print("Courses: (courses)")
            foundCourses.append(contentsOf: courses)
        }
        replyHandler(["response": foundCourses])
        DispatchQueue.main.async {
            //your main thread
        }
    }
ИОС, быстры, watchkit, uibackgroundtask,
Похожие вопросы
Яндекс.Метрика