2013-10-04 10 views
18

Po przeczytaniu dokumentacji Apple o pobieraniu w tle z nowym apletem iOS7 (NSURLSession), jestem nieco rozczarowany. Byłem pewien, że Apple zarządzał pauza/wznowienie nad dostępności sieci w tle (lub zapewnić odpowiednią opcję, aby to zrobić), ale nie ...Pobieranie tła NSURLSession - wznowienie przez awarię sieci

Więc czytanie dokumentacji, to co mamy:

https://developer.apple.com/library/ios/documentation/cocoa/Conceptual/URLLoadingSystem/NSURLSessionConcepts/NSURLSessionConcepts.html

When any task completes, the NSURLSession object calls the delegate’s URLSession:task:didCompleteWithError: method with either an error object, or nil if the task completed successfully. If the task is a resumable download task, the NSError object’s userInfo dictionary contains a value for the NSURLSessionDownloadTaskResumeData key. Your app should use reachability APIs to determine when to retry, and should then call downloadTaskWithResumeData: or downloadTaskWithResumeData:completionHandler: to create a new download task to continue that download. Go to step 3 (creating and resuming task objects).

dotychczas rozumiem rozwiązanie, ale moje pytanie brzmi: Jaka architektura jest najlepszy do obsługi utratę sieci i wznowić pobieranie w tle?

Po mojej stronie używam osiągalności i za każdym razem, gdy sieć jest dostępna, wznawiam wszystkie zadania (odwołuję się do NSArray podczas tworzenia) i zawieszam je, gdy sieć zostanie utracona. Działa to dobrze na pierwszym planie, ale na tle Potrzebuję pomocy w następujących punktach:

  • Jeśli moja aplikacja nie ma połączenia w planie, jeśli pójdę do tła bez łączności wszystkie moje zadania pozostaje zawieszony i nie będzie wrócił, jeśli sieć jest dostępna ...

  • Utrata sieci w tle, zatrzymanie wszystkich pobrań/zadań. Scenariusz:

    • W planie, ja rozpocząć pobieranie moich zadań
    • idę do tła i po 10s przełączyć się na „tryb aireplan”
    • Wszystkie moje zadania dostaje błąd. Tak więc w metodzie URLSession: task: didCompleteWithError: Wznawiam je za pomocą downloadTaskWithResumeData lub jeśli nie mogę (ponieważ niektóre nie mają wystarczającej ilości danych do wznowienia), tworzę nowe zadanie bez wznawiania go (z wyjątkiem sytuacji, gdy sieć powraca w tym czasie).
    • Następnie kładę wifi się
    • Ponieważ jestem nadal w tle nie może wywołać „resume”, gdy sieć jest z powrotem bez konieczności uruchamiania aplikacji ...

Jak mogę rozwiązać te punkty ? Czy coś przeoczyłem?

+0

Dzielę się rozczarowaniem. Wspomniałeś, że czekasz na odpowiedź od Apple na ten temat. Czy słyszałeś od nich? Jaka jest rozdzielczość? – gavdotnet

+0

Mam dużo wymiany z Apple, ale nie było produktywne, zalecenie jest użycie flagi dyskrecjonalnej, która powinna zająć się tymi przypadkami (ale bez gwarancji wyników w czasie). Ten tryb nie był moim celem, ale nie skupiałem się na tym, ale mój test się nie powiódł. Jeśli przetestowałeś tę część, która nadal byłaby interesująca dla uzyskania informacji. – Gros

Odpowiedz

3

Ponieważ jestem nadal w tle nie może wywołać „resume”, gdy sieć jest z powrotem bez konieczności uruchamiania aplikacji ...


można użyć „tło fetch”, gdy aplikacja jest uruchomiona przez sprowadzić, następnie możesz sprawdzić sieć i wznowić zadanie pobierania.

+0

To może być obejście problemu ... Czekam teraz na odpowiedź od Apple. – Gros

+0

@Gros czy otrzymałeś od Apple odpowiedź na ten temat? Mam ten sam problem. – Keith

+0

Jakieś słowo na ten temat? – Siriss

2

Powinieneś utworzyć NSURLSession z konfiguracją tła, wtedy twoje zadanie zostanie wysłane do demona tła, a twoja aplikacja zostanie wywołana po jej zakończeniu.

2

wykonawcze:

application:handleEventsForBackgroundURLSession:completionHandler: 

w app delegata - bez wywoływania completionHandler - powoduje, że aplikacja do obijać się w tle po urządzenie utraci połączenie podczas zawieszone.W ten sposób aplikacja nadal będzie mogła wysłuchać powiadomień o osiągalności i ponownie uruchomić pobieranie, gdy połączenie sieciowe stanie się ponownie dostępne. Jest to jednak dość podejrzane podejście i może nie być zgodne z wytycznymi dotyczącymi składania aplikacji sklepu Apple. Ponadto takie podejście nie pomaga, gdy połączenie zostanie utracone, gdy aplikacja znajduje się na pierwszym planie, a połączenie odzyskasz, gdy aplikacja zostanie zawieszona.

W końcu zrobiłem następujący:

  • wykorzystały powiadomienia application:handleEventsForBackgroundURLSession:completionHandler: wstrzymać moje pobieranie w tle.
  • Wykorzystano powiadomienie o przyspieszonym pobraniu tła (np. application:performFetchWithCompletionHandler:completionHandler), aby sprawdzić stan połączenia i ponownie uruchomić wszelkie wstrzymane pobrania. (hat-tip @gugupluto)

To nadal nie zapewnia optymalnej wydajności pobierania i może skłonić użytkowników do zastanowienia się, dlaczego ich "pobieranie w tle" nie zakończyło się po ponownym otwarciu aplikacji, ale wydaje się, że na co możemy teraz liczyć od Apple.

+0

O ile mogę powiedzieć, aplikacja ma określoną ilość czasu (około 30 sekund) na wywołanie programu obsługi zakończenia, a jeśli tego nie zrobi, zostanie zabity przez watchdoga, * z wyjątkiem *, gdy jest debugowanie, tj. uruchamiane przez Xcode, które może sprawić, że niektórzy deweloperzy myślą, że zignorowanie programu obsługi zakończenia jest poprawnym obejściem, gdy tak nie jest. –

+0

@oscahie To miałoby sens, ale to nie było to, czego byłem świadkiem, kiedy testowałem to na moim iPadzie 4. generacji. Wygląda na to, że aplikacja pozostawała w tle przez czas nieokreślony i odpowiadała na powiadomienia o osiągalności sieci. – gavdotnet

Powiązane problemy