2016-11-17 4 views
5

Dies ist, was Apple-Dokumentation sagt in Bezug auf suspend Methode der NSURLSessionTask KlasseNSURLSessionTask. Suspend funktioniert nicht

Eine Aufgabe, während des Abbruchs, erzeugt kein Netzwerkverkehr und unterliegt nicht Timeouts.

Ok. So laufe ich den folgenden einfachen Code:

 let url = NSURL(string: "http://httpbin.org/delay/10")! 
     let urlRequest = NSURLRequest(URL: url) 

     self.task = NSURLSession.sharedSession().dataTaskWithURL(urlRequest.URL!, completionHandler: { 

      data, response, error in print("completion ERROR \(error)") 
     }) 

     self.task.resume() 

     print("Start") 
     delay(5, closure: { 

      self.task.suspend() 

      print("Suspend") 
     }) 

Funktion delay ist einfach ein Wrapper um dispatch_after und eine Anforderung an http://httpbin.org/delay/10 gibt Antwort nach 10 Sekunden. Während ich auf eine Antwort warte, suspendiere ich die Aufgabe. Das funktioniert jedoch nicht. In 60 Sekunden wird der Completion-Block mit Timeout-Fehler aufgerufen. Kann mir bitte jemand erklären, was los ist?

+0

Können Sie den Wrapper um 'dispatch_after' zeigen? –

Antwort

5

Dies scheint ein normales Verhalten zu sein, jedoch wäre eine ausführlichere Dokumentation von Apple nützlich, um zu klären, was wir sehen.

Die Dokumentation von Apple bietet keine detaillierte Erklärung, wie das Aussetzen funktioniert oder wann es verwendet werden sollte. Jedoch, meine Ansicht (basierend auf Tests und Forschung) ist, dass suspend() sollte nur zum Download Aufgaben verwendet werden. Datenaufgaben sollten nur resume() (um die Aufgabe zu starten) und cancel(), wenn angemessen.

Meine Tests, bei denen Xcode und Charles Proxy verwendet wurden, ergaben, dass eine Task für ausgesetzte Daten keine Auswirkungen auf den Netzwerkverkehr hat, wie in der Dokumentation von Apple angegeben. Mit anderen Worten, es wird Netzwerkverkehr erzeugt.

beobachtete ich zwei Dinge mit suspendieren und Daten Aufgaben:

1) Wenn es direkt nach dem Lebenslauf genannt wird, es keine Auswirkungen auf die Daten Aufgabe hat. Der Netzwerkverkehr wird nicht unterbrochen, und es werden keine Probleme mit dem Netzwerk oder dem Server verursacht. Eine erfolgreiche Antwort wird im Rückruf empfangen.

2) Wenn es im Callback dispatch.asyncAfter aufgerufen wird, unterbricht es noch nicht den Netzwerkverkehr, jedoch erhält der Callback einen "Request Timeout" Fehler anstelle einer erfolgreichen Antwort. Laut Charles Proxy ist die Anfrage jedoch erfolgreich. Es ist dieses Ergebnis, das zu der Annahme führt, dass suspend() nicht mit Datenaufgaben verwendet werden sollte. Das Ergebnis dieses Rückrufs ist meines Erachtens im Grunde nutzlos.

Abbrechen eines Daten Aufgabe:

cancel() funktioniert wie erwartet. Der Client (Sie) schließt die Verbindung, bevor eine vollständige Antwort vom Server empfangen wird. Dies kann direkt nach dem Anruf resume() oder zu einem späteren Zeitpunkt erfolgen (bevor die Anfrage natürlich abgeschlossen wurde).

+0

"Die Anfrage ist abgelaufen."? Was ist das? Der Fehler wurde in den Abschlussblock übernommen? So funktioniert es für dich genauso wie für mich, daher ist es normales Verhalten für eine suspendierte Aufgabe, oder? Wenn ja, warum brauchen wir überhaupt auszusetzen? Oder habe ich etwas falsch verstanden? –

+0

@AndreyChernukha Es tut mir leid, es scheint, ich habe Ihre Frage falsch interpretiert. Ich dachte, dass Sie die "Suspend" Nachricht in der Konsole nicht sehen. –

+0

@AndreyChernukha Sie haben Recht, ich habe meine Antwort aktualisiert, um weitere Details zur Verfügung zu stellen. Es scheint ein normales Verhalten für eine Datenaufgabe zu sein. Ein Download-Task würde vermutlich nicht an den Completion-Block übergeben werden, bis der Task wieder aufgenommen und abgeschlossen ist. –

0

Ich akzeptiere, dass Suspend() hat keine Auswirkung auf URLSessionDataTask

    let dataTask = URLSession.shared.dataTask(with: request) { (data, urlResponse, error) in       
        print("response is received all the time") 
        } 
       } 
       dataTask.resume() 
       dataTask.suspend() 

Allerdings, wenn ich Cancelling versuchen, es nicht

let dataTask = URLSession.shared.dataTask(with: request) { (data, urlResponse, error) in       
        print("response is cancelled") 
        } 
       } 
       dataTask.resume() 
       dataTask.cancel() 
Verwandte Themen