Фоновая задача в расширении действия iOS - PullRequest
0 голосов
/ 05 июня 2018

Я работаю над расширением действия для приложения, которое подготавливает некоторые данные для пользователя, а затем использует MailCore2 для отправки этой информации на SMTP-сервер.Подготовка данных выполняется очень быстро, но отправка электронного письма может занять некоторое время (в зависимости от его размера).Вот почему я ищу способ обработки операций отправки в фоновом режиме.Но это приводит к некоторым проблемам с различными решениями:

  1. Использование URLSession .Это первый способ обработки больших загрузок или загрузок в расширении iOS.Но проблема в том, что MailCore2 не использует URLSessions для передачи данных на почтовый сервер.Так что это не пригодно для использования.Или возможно как-то «обернуть» этот вызов в URLSession?

  2. Использование UNUserNotificationCenter и отправить локальное уведомление от расширения после подготовки данных.Идея состоит в том, чтобы запустить задачу отправки в главном приложении после получения этого уведомления.Проблема: метод уведомлений userNotificationCenter didReceive вызывается только тогда, когда пользователь щелкает уведомление.Простое уведомление о значке не вызывает метод делегата.

  3. Использование Фоновая выборка .Это нормально работает в симуляторе, но на устройстве iOS возникает ошибка при подключении к SMTP-серверу.Я столкнулся с той же проблемой HELO, которая описана в github.com / MailCore / mailcore2 / Issues / 252 .Для этой проблемы решение должно быть MCOSMTPSession.isUseHeloIPEnabled = true, но это может не работать для всех серверов.Так что тоже не идеальное решение.

Есть идеи, как справиться с такой задачей?Или как справиться с одним из упомянутых выше решений?

Редактировать: , поскольку на этот вопрос еще не получено ответов: что неясно или какая дополнительная информация требуется?

Ответы [ 3 ]

0 голосов
/ 18 марта 2019

Похоже, что вы не можете запланировать длительно выполняющиеся задачи в фоновом режиме из расширения. Ссылка здесь (некоторые API недоступны для расширений приложения)

Среди предложенных вами решений я бы хотел попробовать тихие push-уведомления , вы можете вызвать API на этапе подготовки данных, а затем отправить немоенажать от сервера и выполнить фоновую задачу, когда приходит тихий push.

0 голосов
/ 21 марта 2019

Наиболее полезным решением является использование push-уведомлений.Решение, которое я использовал в своем собственном приложении:

  1. Создайте простой сервер, который может получать простой запрос: токен устройства и время, когда вы хотите включить ваше устройство.
  2. Когда приложение переходит в фоновый режим, отправьте запрос на сервер, чтобы позже разбудить устройство.Например, 5 минут / 20 минут и т. Д. func applicationWillEnterForeground(_ application: UIApplication) { внутри AppDelegate.
  3. Не забудьте разрешить приложению работать в фоновом режиме, насколько это возможно.

Например,

   @UIApplicationMain
    class AppDelegate: UIResponder {
    var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid
    func application(_ application: UIApplication,
                         didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                         fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
            if UIApplication.shared.applicationState != .active {
                doFetch(completionHandler: completionHandler)
            } else {
                // foreground here
                completionHandler(UIBackgroundFetchResult.noData)
            }
        }
    func application(_ application: UIApplication,
                         performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
            doFetch(completionHandler: completionHandler)
        }
    private func doFetch(completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    sendTheRequestToWakeApp()
    backgroundTask = UIApplication.shared.beginBackgroundTask { [weak self] in
                self?.endBackgroundTask()
            }
/// do work here
    completionHandler(UIBackgroundFetchResult.noData)
    }
    private func endBackgroundTask() {
            print("Background task ended.")
            UIApplication.shared.endBackgroundTask(backgroundTask)
            backgroundTask = UIBackgroundTaskInvalid
        }
    private func sendTheRequestToWakeApp() {
    /// Implement request using native library or Alamofire. etc.
    }
    }

на стороне сервера используют простое время или цикл.

Недостатки,

  1. Требуется Интернет
  2. Это не 'т отлично работает.Когда батарея разряжена, фоновый режим ограничен.

Не забудьте настроить проект:

proejct screenshot

0 голосов
/ 15 июня 2018

Судя по вашему ответу, ваши трудности заключаются в том, что вам нужно разрешить второстепенные действия.Вы можете сделать это, следуя учебному пособию, подобному этому .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...