Это правильный способ использовать фоновую задачу для дополнительного HTTP-запроса после завершения фоновой загрузки / выгрузки? - PullRequest
0 голосов
/ 27 декабря 2018

Я хочу сделать дополнительный HTTP-запрос после фоновой загрузки / выгрузки, чтобы подтвердить, что приложение завершило загрузку / выгрузку.Позвольте мне показать вам простой пример.

Сначала нам нужно создать задачу загрузки / выгрузки.

let configuration = URLSessionConfiguration.background(withIdentifier: UUID().uuidString)
configuration.sessionSendsLaunchEvents = true
configuration.isDiscretionary = true
let session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
session.downloadTask(with: largeFileURL).resume()

Затем нам нужно запустить дополнительный запрос после завершения загрузки / выгрузки.Чтобы предотвратить приостановку приложения, я использую фоновую задачу.

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {

    backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask(expirationHandler: { [weak self] in
        finishBackgroundTask()
    })

    let task = URLSession.shared.dataTask(with: someURL) { data, response, error in
        // Process response.
        finishBackgroundTask()
    }
    task.resume()    
}

private func finishBackgroundTask() {
    UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier)
    backgroundTaskIdentifier = .invalid
}

Последнее, что нужно реализовать, - реализовать метод делегата приложения:

func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {

}

Вопрос

Это правильный способ сделать какую-то работу после фоновой передачи?

Ответы [ 2 ]

0 голосов
/ 02 января 2019

Я предлагаю создать завершениеHandler в свой AppDelegate

var backgroundSessionCompletionHandler: (() -> Void)?

Затем в методе handleEventsForBackgroundURLSession UIApplicationDelegate вы определяете свой обработчик завершения

func application(_ application: UIApplication, handleEventsForBackgroundURLSession 
identifier: String, completionHandler: @escaping () -> Void) {
    backgroundSessionCompletionHandler = {
        // Execute your additional HTTP request
    }
}

Последний шаг - вызвать этот обработчик завершениякогда загрузка закончится

func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
    if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
        if let completionHandler = appDelegate.backgroundSessionCompletionHandler {
            appDelegate.backgroundSessionCompletionHandler = nil
            DispatchQueue.main.async(execute: {
                completionHandler()
            })
        }
    }
}

Надеюсь, это поможет.

0 голосов
/ 27 декабря 2018

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

...