web-dev-qa-db-fra.com

Télécharger AlamoFire en session d'arrière-plan

J'utilise Alamofire dans une nouvelle application (un exemple de gestionnaire de téléchargement basé sur Alamofire) J'ai besoin de clarifications sur le téléchargement de fichiers à l'aide de la session d'arrière-plan. J'ai besoin de remplacer SessionDelegate pour que cela fonctionne? Ou simplement backgroundCompletionHandler?

Quelles sont généralement les étapes pour gérer les téléchargements en arrière-plan à l'aide d'Alamofire? Et comment gérer le cas où mon application est relachée, avec des téléchargements en flux.

37
LastMove

Mise à jour

Sur la base de cet incroyable tutoriel , j'ai mis en place un exemple de projet disponible sur GitHub . Il contient un exemple de gestion de session en arrière-plan.

Selon le guide de programmation du système de chargement d'URL d'Apple :

Dans iOS et OS X, lorsque l'utilisateur relance votre application, votre application doit immédiatement créer des objets de configuration en arrière-plan avec les mêmes identificateurs que toutes les sessions qui avaient des tâches en suspens lors de la dernière exécution de votre application, puis créer une session pour chacun de ces objets de configuration . Ces nouvelles sessions sont également automatiquement réassociées à une activité de fond en cours.

Donc, apparemment, en utilisant les instances de configuration de session d'arrière-plan appropriées, vos téléchargements ne seront jamais "en flux".

J'ai également trouvé cette réponse vraiment utile.

Réponse originale

Depuis la page GitHub d'Alamofire :

Les applications peuvent créer des gestionnaires pour les sessions d'arrière-plan et éphémères, ainsi que de nouveaux gestionnaires qui personnalisent la configuration de session par défaut, comme pour les en-têtes par défaut (HTTPAdditionalHeaders) ou l'intervalle de temporisation (timeoutIntervalForRequest).

Par défaut, les méthodes de niveau supérieur utilisent une instance partagée de Manager avec la configuration de session par défaut. Vous pouvez cependant créer un gestionnaire avec une configuration de session en arrière-plan comme ceci:

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

Vous pouvez ensuite effectuer des requêtes à l'aide de cette instance Manager.

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

En regardant son implémentation, il possède également une propriété appelée backgroundCompletionHandler, vous pouvez donc ajouter un bloc de complétion:

manager.backgroundCompletionHandler = {
        // do something when the request has finished
    }
31
József Vesza

C'est en fait très simple avec Alamofire:

1) votre Alamofire.Manager doit être configuré avec un identifiant de session d'arrière-plan:

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

2) dans le délégué d'application, implémentez application(_:handleEventsForBackgroundURLSession:completionHandler: et passez le gestionnaire d'achèvement à Alamofire.SessionManager.backgroundCompletionHandler.

Dans mon cas, la méthode de délégué d'application ressemble à

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

et mon gestionnaire de réseau a une propriété calculée comme celle-ci pour définir la propriété Manager:

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

Je cherchais la solution assez longtemps. Jusqu'à lire l'article mentionné ci-dessus. Le problème pour moi était - je devais activer la communication externe des accessoires

enter image description here

Tout le reste a été fait comme décrit ci-dessus. AppDelegate:

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

Singleton:

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)
    }
}

Et les appels se font de la manière suivante:

BackendAPIManager.sharedInstance.alamoFireManager.upload(multipartFormData: { (multipartFormData) in ...
8
Naloiko Eugene