NSURLSession-Hintergrund-Upload funktioniert nicht

8

Ich versuche, eine Reihe von Dateien vom iPhone auf einen Server hochzuladen, mit der Absicht, dass das Hochladen dieser Dateien auch dann erfolgt, wenn die App im Hintergrund oder gesperrt ist.

Ich verwende die Hintergrundübertragung , die von NSURLSession und seiner API-Reihe bereitgestellt wird.

Was merkwürdig war, war, dass es vor zwei Wochen voll funktionierte . Wie in:

  1. Ich würde auf die Schaltfläche "upload" auf der Benutzeroberfläche klicken
  2. Dateien würden nacheinander auf meinem Server erscheinen
  3. Ich tippe auf die Schaltfläche "Home" auf dem iPhone, damit die App in den Hintergrund tritt
  4. Dateien werden weiterhin auf den Server hochgeladen, bis alle fertig sind

In den letzten paar Tagen habe ich etwas außerhalb des Netzwerkmoduls refactoring gemacht. Als ich vor ein paar Tagen den Upload erneut versuchte, sobald ich den "Home" -Button gedrückt habe, schreite (3) oben. Datei-Upload würde aufhören, wenn ich wieder in die App gehe. Der Upload wird fortgesetzt.

Es ist, als würde der Hintergrund-Upload nicht einmal funktionieren (für eine Datei, geschweige denn mehrere Dateien).

Ich habe den Code mehrmals ausgeführt und ungefähr 1/50 Mal gefunden, dass es funktioniert. Aber die anderen 49 mal nicht. Ich habe auch die Version des Codes überprüft, die früher funktioniert hat (sowohl Server als auch iOS), und es funktioniert nicht mehr - oder besser gesagt, die Arbeit variiert selten (1/50)

Nachdem Sie die Regeln für die Hintergrundübertragung und Lebenszyklus der URL-Sitzung um sicherzustellen, dass ich bin Nach den von Apple vorgeschlagenen Richtlinien halte ich mich an das, was kaputt gegangen ist. Es verwirrt den Verstand, wie unlogisch das ist - Ich vermute, es ist etwas anderes als Code-Implementierung.

Also jede Hilfe wird geschätzt ...

Implementierung

1) In init Methode für meine Netzwerkklasse (ein Singleton) initialisiere ich NSURLSessionConfiguration und NSURLSession :

%Vor%

2) Es gibt eine bequeme Methode, um den eigentlichen Upload durchzuführen. Es gibt nur 1 Upload-Aufgabe pro Sitzung:

%Vor%

3) Im Delegierten didCompleteWithError überprüfe ich, ob alle Dateien hochgeladen wurden, wenn nicht, gehe zur nächsten Datei - GLOBAL.uploadQueue ist wo ich einen Verweis auf alle Dateien behalte, die ich hochladen muss, GLOBAL.uploadQueueIndexNextFile

%Vor%

processNextFileInUploadQueue bereitet die Datei vor und ruft die Convenience-Methode für den Upload auf ((2) oben).

Hier sehen Sie eine Beispielausgabe von Caveman Debugging (für Datei 2 - 4). Beachten Sie, dass der Upload gestoppt wird, sobald die App in den Hintergrund tritt.

Beachten Sie, ich habe auch länger gewartet als die 10 Sekunden in der Ausgabe unten gezeigt. Am längsten war ich zum Abendessen (30 Minuten), kam zurück und der Upload endete damit. Das Betriebssystem hat es nie aufgenommen, sobald sich die App im Hintergrund befindet.

%Vor%

Ich bin froh, an dieser Stelle alles versuchen zu können. Danke!

BEARBEITEN # 1

Wird beobachtet, wenn der Hintergrund-Upload funktioniert. application:handleEventsForBackgroundURLSession:completionHandler: wird vom Betriebssystem aufgerufen. Ausnahmslos wird dieser Rückruf nie gemacht, wenn es nicht funktioniert.

Ich bin mir nicht sicher, ob eine Voraussetzung für den Upload im Hintergrund ist, dass das Betriebssystem die App zuerst beenden muss. Wenn ja, unter welchen Bedingungen geschieht dies? Und können wir es veranlassen?

Wie bereits erwähnt, 49 von 50, OS wird die App im Hintergrund behalten, und Upload wird angehalten.

    
snowbound 21.02.2016, 09:34
quelle

4 Antworten

2

Es gibt eine Sache, die klarstellen wollte, dass man im Hintergrund keine Aufgabe länger ausführen kann, wie Apple es nicht zulässt. Nur in besonderen Fällen denkt Apple darüber nach. Am besten erklärt in Hintergrunddienste in iOS ausführen

Wenn Sie jetzt auf Ihr Frageproblem mit Ihrer Implementierung zurückkommen, funktioniert es nur im Hintergrund für Upload-Aufgaben, die initiiert werden, wenn die App aktiv war und die Aufgabe noch nicht abgeschlossen ist. Das ist der Grund für 1 von 50 Versuchen, dass die Aufgabe im Hintergrund funktioniert.

Um Ihr Problem jetzt zu lösen, müssen Sie alle / mehrere Upload-Dateien gleichzeitig initiieren, damit Ihre App auch Dateien hochladen kann, wenn die App im Hintergrund läuft. Dieses brillante Tutorial erläutert verschiedene Fälle im Zusammenhang mit der Übertragung im Hintergrund.

Sie können auch eine mehrteilige AFNetworking Anfrage zum Hochladen ausprobieren.

%Vor%     
aman.sood 26.02.2016 07:13
quelle
1

Ich habe auch die gleichen Bedenken in einer meiner Video-App. Dieses Problem tritt nach dem 14. Februar auf. Ich habe viel gegraben und festgestellt, dass dies geschieht, nachdem Apple seine weltweiten Zertifikate geändert hat. Bitte überprüfen Sie dieses https://developer.apple.com/support/certificates/expiration/ . Die Lösung besteht darin, zunächst vorhandene Zertifikate aus dem Keychain-Zugriff zu entfernen und dann neue Entwicklungs- / Distributionszertifikate, eine neue App-ID und ein neues Bereitstellungsprofil hinzuzufügen. Es wird definitiv funktionieren.

    
Nirajkumar Prasad 29.02.2016 14:10
quelle
1

Ich denke, das Problem liegt beim Hochladen. Sie initiieren die nächste Upload-Aufgabe, nachdem Sie die vorherige abgeschlossen haben, und erstellen Sie alle Upload-Aufgaben einmalig. Speichern Sie in Ihrem AppDelegate den Beendigungshandler von application:handleEventsForBackgroundURLSession:completionHandler: als Eigenschaft. Rufen Sie den Abschlussblock in NSURLSessionDelegate URLSessionDidFinishEventsForBackgroundURLSession: delegate-Methode von NSURLSessionDelegate auf. Stellen Sie sicher, dass alle Upload-Aufgaben abgeschlossen sind, bevor Sie den Anruf tätigen. Dieses Tutorial Ссылка erklärt die Download-Aufgabe gut. Möglicherweise können Sie die gleichen Regeln für Ihre Upload-Aufgabe anwenden.

    
Ronald 01.03.2016 13:32
quelle
1

Ich hatte ein ähnliches Problem, die Dateien wurden im Vordergrund hochgeladen. Es hörte im Hintergrund auf.

Nachdem ich ein paar Tage damit verbracht habe, die Dokumentation und ähnliche Antworten zu lesen. Diese Lösung hat für mich funktioniert

>
  1. UIBackgroundTaskIdentifier ist eine der wichtigen Eigenschaften, die sehr nützlich wäre. Erstellen Sie diese in der App-Delegate-Klasse, und initialisieren Sie sie in UIBackgroundTaskInvalid in didFinishLaunchingWithOptions .

-

%Vor%
  1. Während die App ihren Status wechselt, wechselt sie von Vordergrund zu Hintergrund oder umgekehrt. Wir müssen sicherstellen, dass diese Eigenschaft in ihren relevanten Delegate-Methoden überprüft wird.
  

beginBackgroundTaskWithExpirationHandler   ist sehr wichtig, um den Hintergrund Task im Hintergrund zu starten.

-

%Vor%

Sie können den Code in einem echten Gerät debuggen und unter den richtigen Netzwerkbedingungen überprüfen.

  1. Sie können auch die folgende Delegate-Methode hinzufügen, um den bytesSent nachzuverfolgen.

-

%Vor%

Ich hoffe, es hilft jemandem.

    
Santosh 11.02.2017 14:20
quelle