Transfer w tle i NSURLSession w środowisku Xamarin.iOS
Transfer w tle jest inicjowany przez skonfigurowanie w tle NSURLSession
i kolejkowanie zadań przekazywania lub pobierania. Jeśli zadania zostaną ukończone, gdy aplikacja jest w tle, wstrzymana lub zakończona, system iOS powiadomi aplikację przez wywołanie procedury obsługi uzupełniania w aplikacji AppDelegate. Na poniższym diagramie przedstawiono to działanie:
Konfigurowanie sesji w tle
Aby utworzyć sesję w tle, utwórz nową NSUrlSession
i skonfiguruj ją przy użyciu NSUrlSessionConfiguration
obiektu.
Obiekt konfiguracji określa, co może wykonywać sesja i jakie rodzaje zadań może uruchomić.
Sesje skonfigurowane przy użyciu CreateBackgroundSessionConfiguration
metody będą uruchamiane w osobnym procesie i wykonują uznaniowe transfery (Wi-Fi), aby zachować dane i żywotność baterii.
Poniższy przykład kodu demonstruje właściwą konfigurację sesji transferu w tle przy użyciu CreateBackgroundSessionConfiguration
metody i unikatowego identyfikatora ciągu:
public partial class SimpleBackgroundTransferViewController : UIViewController
{
NSUrlSession session = null;
NSUrlSessionConfiguration configuration =
NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration ("com.SimpleBackgroundTransfer.BackgroundSession");
session = NSUrlSession.FromConfiguration
(configuration, new MySessionDelegate(), new NSOperationQueue());
}
Oprócz obiektu konfiguracji sesja wymaga również delegata sesji i kolejki. Kolejka określa kolejność, w jakiej zadania zostaną wykonane. Delegat sesji chaperone proces transferu i obsługuje uwierzytelnianie, buforowanie i inne problemy związane z sesją.
Praca z zadaniami i delegatami
Teraz, gdy skonfigurowaliśmy sesję w tle, zacznijmy od zadań do obsługi transferu. Możemy śledzić te zadania przy użyciu NSUrlSessionDelegate
wystąpienia nazywanego pełnomocnikiem sesji. Pełnomocnik sesji jest odpowiedzialny za przebudzenie zakończonej lub zawieszonej aplikacji w tle w celu obsługi uwierzytelniania, błędów lub ukończenia transferu.
Element NSUrlSessionDelegate
udostępnia następujące podstawowe metody sprawdzania stanu transferu:
- DidFinishEventsForBackgroundSession — ta metoda jest wywoływana po zakończeniu wszystkich zadań, a transfer zostanie ukończony.
- DidReceiveChallenge — wywoływana w celu żądania poświadczeń, gdy jest wymagana autoryzacja.
- DidBecomeInvalidWithError — wywoływana, jeśli właściwość
NSURLSession
stanie się unieważniona.
Sesje w tle wymagają bardziej wyspecjalizowanych delegatów w zależności od typów uruchomionych zadań. Sesje w tle są ograniczone do dwóch typów zadań:
- Przekazywanie zadań — zadania typu
NSUrlSessionUploadTask
używają interfejsuINSUrlSessionTaskDelegate
, który implementujeINSUrlSessionDelegate
element . Zapewnia to dodatkowe metody śledzenia postępu przekazywania, obsługi przekierowania HTTP i nie tylko. - Download Tasks — zadania typu
NSUrlSessionDownloadTask
używają interfejsuINSUrlSessionDownloadDelegate
, który implementujeINSUrlSessionDelegate
iINSUrlSessionTaskDelegate
. Zapewnia to wszystkie metody przekazywania zadań, a także metody specyficzne dla pobierania, aby śledzić postęp pobierania i określić, kiedy zadanie pobierania zostało wznowione lub ukończone.
Poniższy kod definiuje zadanie, które może służyć do pobierania obrazu z adresu URL. Zadanie jest uruchamiane przez wywołanie CreateDownloadTask
sesji w tle i przekazanie żądania adresu URL:
const string DownloadURLString = "http://xamarin.com/images/xamarin.png"; // or other hosted file
public NSUrlSessionDownloadTask downloadTask;
NSUrl downloadURL = NSUrl.FromString (DownloadURLString);
NSUrlRequest request = NSUrlRequest.FromUrl (downloadURL);
downloadTask = session.CreateDownloadTask (request);
Następnie utwórz nowy delegat pobierania sesji, aby śledzić wszystkie zadania pobierania w tej sesji. Klasa delegata powinna dziedziczyć i NSObject
implementować wymagany interfejs:
public class MySessionDelegate : NSObject, INSUrlSessionDownloadDelegate
{
public void DidWriteData (NSUrlSession session, NSUrlSessionDownloadTask downloadTask, long bytesWritten, long totalBytesWritten, long totalBytesExpectedToWrite)
{
Console.WriteLine (string.Format ("DownloadTask: {0} progress: {1}", downloadTask, progress));
InvokeOnMainThread( () => {
// update UI with progress bar, if desired
});
}
...
}
Aby dowiedzieć się, jak postęp zadania pobierania, przesłoń DidWriteData
metodę do śledzenia postępu, a nawet zaktualizuj interfejs użytkownika. Aktualizacje interfejsu użytkownika będą wyświetlane natychmiast, jeśli aplikacja znajduje się na pierwszym planie lub będzie czekać na użytkownika przy następnym otwarciu aplikacji.
Interfejs API delegata sesji udostępnia szeroki zestaw narzędzi do interakcji z zadaniami. Pełną listę metod delegatów sesji można znaleźć w dokumentacji interfejsu NSUrlSessionDelegate
API.
Ważne
Sesje w tle są uruchamiane w wątku w tle, dlatego wszystkie wywołania aktualizacji interfejsu użytkownika muszą być jawnie uruchamiane w wątku interfejsu użytkownika, wywołując metodę InvokeOnMainThread
w celu uniknięcia zakończenia aplikacji przez system iOS.
Obsługa uzupełniania transferu
Ostatnim krokiem jest poinformowanie aplikacji o zakończeniu wszystkich zadań skojarzonych z sesją i obsłużenie nowej zawartości.
W pliku zasubskrybuj AppDelegate
HandleEventsForBackgroundUrl
zdarzenie. Po przejściu aplikacji w tle i uruchomieniu sesji transferu ta metoda jest wywoływana, a system przekazuje nam procedurę obsługi ukończenia:
public System.Action backgroundSessionCompletionHandler;
public void HandleEventsForBackgroundUrl (UIApplication application, string sessionIdentifier, System.Action completionHandler)
{
this.backgroundSessionCompletionHandler = completionHandler;
}
Użyj programu obsługi uzupełniania, aby poinformować system iOS o zakończeniu przetwarzania aplikacji.
Pamiętaj, że sesja może zduplikować kilka zadań w celu przetworzenia transferu. Po zakończeniu ostatniego zadania aplikacja zawieszona lub zakończona zostanie ponownie uruchomiona w tle. Następnie aplikacja ponownie nawiązuje połączenie z NSURLSession
użyciem unikatowego identyfikatora sesji i wywołuje delegata DidFinishEventsForBackgroundSession
sesji. Ta metoda umożliwia aplikacji obsługę nowej zawartości, w tym aktualizowanie interfejsu użytkownika w celu odzwierciedlenia wyników transferu:
public void DidFinishEventsForBackgroundSession (NSUrlSession session) {
// Handle new information, update UI, etc.
}
Po zakończeniu obsługi nowej zawartości wywołaj procedurę obsługi uzupełniania, aby poinformować system, że można bezpiecznie utworzyć migawkę aplikacji i wrócić do trybu uśpienia:
public void DidFinishEventsForBackgroundSession (NSUrlSession session) {
var appDelegate = UIApplication.SharedApplication.Delegate as AppDelegate;
// Handle new information, update UI, etc.
// call completion handler when you're done
if (appDelegate.backgroundSessionCompletionHandler != null) {
NSAction handler = appDelegate.backgroundSessionCompletionHandler;
appDelegate.backgroundSessionCompletionHandler = null;
handler.Invoke ();
}
}
W tym przewodniku opisano podstawowe kroki implementowania usługi transferu w tle w systemie iOS 7 i nowszych.