Подтвердить что ты не робот

Скачать AlamoFire в фоновом режиме

Я использую Alamofire в новом приложении (образец диспетчера загрузки на основе Alamofire). Мне нужны некоторые разъяснения о загрузке файлов с использованием фонового сеанса. Мне нужно переопределить SessionDelegate, чтобы он работал? Или просто backgroundCompletionHandler?

Каковы шаги для обработки загрузок в фоновом режиме с использованием Alamofire? И как я могу справиться со случаем, когда мое приложение обновлено, с загрузками в потоке.

4b9b3361

Ответ 1

Update

Основываясь на этом удивительном учебнике, я собрал примерный проект, доступный на GitHub. Он имеет пример управления фоновым сеансом.

Согласно Apple Руководство по программированию URL-адреса URL:

В iOS и OS X, когда пользователь перезагружает ваше приложение, ваше приложение должен немедленно создавать фоновые объекты конфигурации с помощью те же идентификаторы, что и любые сеансы, у которых были приложение было выполнено в последний раз, затем создайте сеанс для каждого из этих объекты конфигурации. Эти новые сеансы аналогично автоматически reassociated с текущей фоновой деятельностью.

Таким образом, по-видимому, используя соответствующие экземпляры конфигурации фонового сеанса, ваши загрузки никогда не будут "in flux".

Я также нашел этот ответ действительно полезным.

Оригинальный ответ

Из Alamofire Страница GitHub:

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

По умолчанию методы верхнего уровня используют общий экземпляр Manager с настройкой сеанса по умолчанию. Однако вы можете создать менеджера с настройкой фонового сеанса следующим образом:

let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("com.example.app.background")
let manager = Alamofire.Manager(configuration: configuration)

Затем вы можете создавать запросы, используя этот Manager экземпляр.

manager.startRequestsImmediately = true
let request = NSURLRequest(URL: NSURL(string: "your.url.here")!)
manager.request(request)

Изучая его реализацию, он также имеет свойство backgroundCompletionHandler, поэтому вы можете добавить блок завершения:

manager.backgroundCompletionHandler = {
        // do something when the request has finished
    }

Ответ 2

На Alamofire это очень легко:

1) ваш Alamofire.Manager должен быть настроен с идентификатором фонового сеанса:

class NetworkManager {
    ...
    private lazy var backgroundManager: Alamofire.SessionManager = {
        let bundleIdentifier = ...
        return Alamofire.SessionManager(configuration: URLSessionConfiguration.background(withIdentifier: bundleIdentifier + ".background"))
    }()
    ...
}

2) в App Delegate реализуют application(_:handleEventsForBackgroundURLSession:completionHandler: и передают обработчик завершения Alamofire.SessionManager.backgroundCompletionHandler.

В моем случае метод делегирования приложения выглядит как

func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
    NetworkManager.default.backgroundCompletionHandler = completionHandler
}

и мой менеджер сети имеет вычисленное свойство, подобное этому, чтобы установить свойство Manager:

var backgroundCompletionHandler: (() -> Void)? {
    get {
        return backgroundManager.backgroundCompletionHandler
    }
    set {
        backgroundManager.backgroundCompletionHandler = newValue
    }
}

Ответ 3

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

enter image description here

Все остальное было сделано, как описано выше. AppDelegate:

func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
        BackendAPIManager.sharedInstance.backgroundCompletionHandler = completionHandler
    }

Синглтон:

import Alamofire

class BackendAPIManager: NSObject {
    static let sharedInstance = BackendAPIManager()

    var alamoFireManager : Alamofire.SessionManager!

    var backgroundCompletionHandler: (() -> Void)? {
        get {
            return alamoFireManager?.backgroundCompletionHandler
        }
        set {
            alamoFireManager?.backgroundCompletionHandler = newValue
        }
    }

    fileprivate override init()
    {
        let configuration = URLSessionConfiguration.background(withIdentifier: "com.url.background")
        configuration.timeoutIntervalForRequest = 200 // seconds
        configuration.timeoutIntervalForResource = 200
        self.alamoFireManager = Alamofire.SessionManager(configuration: configuration)
    }
}

И звонки выполняются следующим образом:

BackendAPIManager.sharedInstance.alamoFireManager.upload(multipartFormData: { (multipartFormData) in ...

Ответ 4

BackendAPIManager.sharedInstance.alamoFireManager!.download(url,to:destination).downloadProgress { (progress) in 

           self.UpdateProgress(progress: progress.fractionCompleted)


        }
        .responseData { (data) in

            if  data.error == nil
            {
              self.DownloadComplete()
            }
            else
            {
                self.DowonloadFiled()
            }

    }

Все отлично работает, но когда приложение переходит в фоновый режим, оно возвращается в forground

 self.UpdateProgress(progress: progress.fractionCompleted)

не называть. Как это исправить?