0

Si j'exécute le code suivant et que l'application est en arrière-plan, le téléchargement continue. Enfin, lorsque le téléchargement est terminé, je peux obtenir le bon rappel.NSURLSession, après que la tâche de données est convertie en tâche de téléchargement, elle ne peut pas être téléchargée en arrière-plan

let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(SessionProperties.identifier) 
let backgroundSession = NSURLSession(configuration: configuration, delegate: self.delegate, delegateQueue: nil) 

let url = NSURLRequest(URL: NSURL(string: data[1])!) 
let downloadTask = backgroundSession.downloadTaskWithRequest(url) 
    downloadTask.resume() 

Mais j'ai besoin, soit je dois juger ce que le serveur renvoie à moi, si c'est un JSON, je ne fais pas le téléchargement, donc je veux obtenir d'abord l'en-tête de réponse, alors si elle a besoin de télécharger, je change la tâche de données à télécharger tâche, donc je l'ai fait que le code suivant

let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(SessionProperties.identifier) 
let backgroundSession = NSURLSession(configuration: configuration, delegate: self.delegate, delegateQueue: nil) 

let url = NSURLRequest(URL: NSURL(string: data[1])!) 
//I change the downloadTaskWithRequest to dataTaskWithRequest 
let downloadTask = backgroundSession.dataTaskWithRequest(url) 
downloadTask.resume() 

alors je peux obtenir l'en-tête de réponse dans le rappel, et si elle a besoin de télécharger le fichier, je peut changer la tâche de données pour télécharger la tâche, comme suit

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) { 
    if let response = response as? NSHTTPURLResponse { 
     let contentType = response.allHeaderFields["Content-Type"] as! String 
     if contentType == "image/jpeg" { 
      //change the data task to download task 
      completionHandler(.BecomeDownload) 
      return 
     } 
    } 
    completionHandler(.Allow) 

} 

Jusqu'ici tout va bien. Lorsque je cours l'application au premier plan, l'effet est comme ce que je pensais. Mais une fois l'application exécutée en arrière-plan, le téléchargement est arrêté, puis lorsque j'ouvre l'application, la console indique "Connexion perdue au service de transfert en arrière-plan". Je pensais qu'Apple est si intelligente, il nous donne beaucoup de rappels utiles, mais maintenant, je ne savais pas où je me trompe, et je vois aussi le code source de AFNetworking et Alamofire, mais je n'ai pas trouvé la chose référente.

Je pense aussi que c'est une exigence commune, mais je ne trouve aucune information utile sur internet, c'est trop bizarre.

Alors j'espère que vous pouvez m'aider, merci un milliard.

+0

Comme l'a dit un membre du personnel d'Apple, c'est un bug de la part de l'OS. Donc, je quitte de cette façon. La nouvelle façon dont je le fais maintenant est de créer une tâche de téléchargement. Une fois les données téléchargées, pour juger l'en-tête de réponse, si les données sont une image, transférez les données à un autre endroit, si c'est un json, lisez-le à partir du fichier tmp et effectuez le traitement de référence. – Changwei

Répondre

0

Activer le mode d'arrière-plan dans Xcode-> Cible-> Capacités-> En mode arrière-plan et sélectionnez l'option Extraction de l'arrière-plan.

0

Le problème principal que je vois est que vous appelez le completionHandler deux fois. Vous devez revenir sur votre type de contenu conditionnel comme ceci:

if contentType == "image/jpeg" { 
    //change the data task to download task 
    completionHandler(.BecomeDownload) 
    return 
} 

Sinon, il semble que vous utilisez correctement la logique. J'espère que cela pourra aider.

+0

Merci pour votre réponse, je suis désolé j'ai copié le code avec une mauvaise logique. En face, même si j'écris seulement un code de ligne - "completionHandler (.BecomeDownload)" dans le rappel "didReceiveResponse". J'ai eu la même erreur. J'ai créé une démo sur github, si cela vous convient, téléchargez-la et lancez-la, quand elle commence à télécharger, vous cliquez sur le bouton d'accueil, puis ouvrez à nouveau l'application, vous verrez l'erreur. https://github.com/tuchangwei/data_task_convert_to_download_task – Changwei

0

Le problème est évident à partir de votre propre réponse. Ce n'est pas un bogue, vous ne pouviez tout simplement pas utiliser les tâches de données pour les transferts en arrière-plan, il suffit de télécharger des tâches.

Here est la bonne réponse complète.

+0

Merci, lisez les données du fichier tmp est un bon moyen de juger si je télécharge est un fichier multimédia ou des données json. – Changwei