Как выполнить некоторые действия в фоновом режиме - PullRequest
1 голос
/ 09 января 2020

Я делаю скачивание некоторых файлов с сервера. После завершения загрузки я должен распаковать их, и после этого я показываю локальное уведомление pu sh о результатах шоу. Чтобы не блокировать пользовательский интерфейс, я добавил наблюдателей для показа пользовательской строки прогресса без индикатора активности, и обновление этой строки зависит от состояния.

Я хочу дать пользователю возможность сделать все это в фоновом режиме.

Для загрузка Я создаю URLSession с конфигурацией bg следующим образом:

  private lazy var urlSession: URLSession = {
    let config = URLSessionConfiguration.background(withIdentifier: "MySession")
    config.isDiscretionary = true
    config.sessionSendsLaunchEvents = true
    return URLSession(configuration: config, delegate: self, delegateQueue: nil)
    }()

И все отлично работает для загрузки. Но моя распаковка веселья c по-прежнему работает только на переднем плане. Как я могу использовать это в фоновом режиме?

Для распаковки я использую lib ZIPFoundation. И код ниже:

public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        downloadService.update(state: .unpacking, for: downloadTask)
        do {
            let documentsDir = try self.fileManager.url(
                for: .documentDirectory,
                in: .userDomainMask,
                appropriateFor: nil,
                create: false
            )
            let newLocation = documentsDir.appendingPathComponent(location.lastPathComponent)
            try fileManager.moveItem(at: location, to: newLocation)
            DispatchQueue.global(qos: .background).async { [weak self] in
                guard let self = self else { return }
                do {
                    let path = try self.fileManager.url(
                        for: .documentDirectory,
                        in: .userDomainMask,
                        appropriateFor: nil,
                        create: false
                    )
                        .appendingPathComponent("store")
                    try self.fileManager.unzipItem(at: newLocation, to: path, progress: downloadTask.progress)
                    try self.fileManager.removeItem(at: newLocation)
                    DispatchQueue.main.async {
                        self.notificationCenter.add(.languageIsDownloaded)
                        self.downloadService.update(state: .finished, for: downloadTask)
                    }
                } catch {
                    DispatchQueue.main.async {
                        self.errorHandler.handle(error)
                        self.downloadService.update(state: .failed, for: downloadTask)
                    }
                }
            }
        } catch {
            errorHandler.handle(error)
            downloadService.update(state: .failed, for: downloadTask)
        }
    }

1 Ответ

0 голосов
/ 09 января 2020

Если вы выполняете какую-либо операцию, которая может потребовать времени, и вы не хотите ее убивать, вы можете продлить время для своей операции, выполнив в UIBackground Task

{
    UIBackgroundTaskIdentifier  taskId = 0;
    taskId = [application beginBackgroundTaskWithExpirationHandler:^{
        taskId = UIBackgroundTaskInvalid;
    }];

// Execute long process. This process will have 10 mins even if your app goes in background mode.

}

Аргумент блока, называемый " обработчик "- это то, что произойдет, когда истечет время фоновой задачи (10 минут). Вот ссылка на документацию

...