Sdílet prostřednictvím


Přenos na pozadí a NSURLSession v Xamarin.iOS

Přenos na pozadí se zahájí konfigurací pozadí NSURLSession a zařazením úkolů nahrávání nebo stahování. Pokud se úkoly dokončí, když je aplikace na pozadí, pozastavena nebo ukončena, iOS aplikaci upozorní voláním obslužné rutiny dokončení v AppDelegate aplikace. Následující diagram znázorňuje tuto akci:

Přenos na pozadí se zahájí konfigurací NSURLSession na pozadí a zařazením úloh nahrávání nebo stahování.

Konfigurace relace na pozadí

Pokud chcete vytvořit relaci na pozadí, vytvořte novou NSUrlSession a nakonfigurujte ji pomocí objektu NSUrlSessionConfiguration .

Objekt konfigurace určuje, co může relace dělat, a druhy úloh, které může spustit. Relace nakonfigurované pomocí CreateBackgroundSessionConfiguration této metody se budou spouštět v samostatném procesu a provádět volitelné přenosy (Wi-Fi), aby se zachovala životnost dat a baterie. Následující ukázka kódu ukazuje správné nastavení relace přenosu na pozadí pomocí CreateBackgroundSessionConfiguration metody a jedinečného identifikátoru řetězce:

public partial class SimpleBackgroundTransferViewController : UIViewController
{
  NSUrlSession session = null;

  NSUrlSessionConfiguration configuration =
      NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration ("com.SimpleBackgroundTransfer.BackgroundSession");
  session = NSUrlSession.FromConfiguration
      (configuration, new MySessionDelegate(), new NSOperationQueue());

}

Kromě objektu konfigurace vyžaduje relace také delegáta relace a frontu. Fronta určuje pořadí, ve kterém budou úkoly dokončeny. Delegát relace chaperone proces přenosu a zpracovává ověřování, ukládání do mezipaměti a další problémy související s relacemi.

Práce s úkoly a delegáty

Teď, když jsme nakonfigurovali relaci na pozadí, zahájíme úlohy pro zpracování přenosu. Tyto úlohy můžeme sledovat pomocí NSUrlSessionDelegate instance, která se nazývá delegát relace. Delegát relace zodpovídá za probuzení ukončené nebo pozastavené aplikace na pozadí za účelem zpracování ověřování, chyb nebo dokončení přenosu.

Poskytuje NSUrlSessionDelegate následující základní metody pro kontrolu stavu přenosu:

  • DidFinishEventsForBackgroundSession – Tato metoda se volá, když jsou dokončeny všechny úkoly a přenos je dokončen.
  • DidReceiveChallenge – Volá se k vyžádání přihlašovacích údajů, pokud je vyžadována autorizace.
  • DidBecomeInvalidWithError – Volá se, pokud dojde k NSURLSession zneplatnění.

Relace na pozadí vyžadují specializovanější delegáty v závislosti na typech spuštěných úloh. Relace na pozadí jsou omezené na dva typy úloh:

  • Nahrání úkolů – Úkoly typu NSUrlSessionUploadTask používají INSUrlSessionTaskDelegate rozhraní, které implementuje INSUrlSessionDelegate. Poskytuje další metody pro sledování průběhu nahrávání, zpracování přesměrování PROTOKOLU HTTP a další.
  • Download Tasks - Tasks of type NSUrlSessionDownloadTask use the INSUrlSessionDownloadDelegate interface, které implementuje INSUrlSessionDelegate a INSUrlSessionTaskDelegate. To poskytuje všechny metody pro nahrávání úkolů a také metody specifické pro stahování ke sledování průběhu stahování a určení, kdy se úloha stahování obnovila nebo dokončila.

Následující kód definuje úlohu, kterou lze použít ke stažení obrázku z adresy URL. Úloha se spustí voláním CreateDownloadTask relace na pozadí a předáním požadavku adresy 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);

Dále vytvořte delegáta pro stahování nové relace, abyste měli přehled o všech úkolech stahování v této relaci. Třída delegáta by měla dědit a NSObject implementovat požadované rozhraní:

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
    });
  }
  ...
}

Pokud chcete zjistit průběh úlohy stahování, přepište metodu DidWriteData sledování průběhu a dokonce aktualizujte uživatelské rozhraní. Aktualizace uživatelského rozhraní se zobrazí okamžitě, pokud je aplikace v popředí nebo bude čekat na uživatele při příštím otevření aplikace.

Rozhraní API delegáta relace poskytuje širokou sadu nástrojů pro interakci s úlohami. Úplný seznam metod delegáta relace najdete v NSUrlSessionDelegate dokumentaci k rozhraní API.

Důležité

Relace na pozadí se spouští ve vlákně na pozadí, takže všechna volání k aktualizaci uživatelského rozhraní musí být explicitně spuštěna ve vlákně uživatelského rozhraní voláním InvokeOnMainThread , aby se zabránilo ukončení aplikace pro iOS.

Zpracování dokončení převodu

Posledním krokem je dát aplikaci vědět, kdy byly dokončeny všechny úkoly přidružené k relaci, a zpracovat nový obsah.

V okně AppDelegate, přihlásit se k odběru HandleEventsForBackgroundUrl události. Když aplikace přejde na pozadí a spustí se relace přenosu, volá se tato metoda a systém nám předá obslužnou rutinu dokončení:

public System.Action backgroundSessionCompletionHandler;

public void HandleEventsForBackgroundUrl (UIApplication application, string sessionIdentifier, System.Action completionHandler)
{
  this.backgroundSessionCompletionHandler = completionHandler;
}

Pomocí obslužné rutiny dokončení dejte iOSu vědět, kdy je naše aplikace dokončena zpracování.

Vzpomeňte si, že relace může vytvořit několik úloh pro zpracování přenosu. Po dokončení posledního úkolu se pozastavená nebo ukončená aplikace znovu spustí na pozadí. Aplikace se pak znovu připojí k NSURLSession pomocí jedinečného identifikátoru relace a zavolá DidFinishEventsForBackgroundSession delegáta relace. Tato metoda je příležitostí aplikace zpracovat nový obsah, včetně aktualizace uživatelského rozhraní tak, aby odrážel výsledky přenosu:

public void DidFinishEventsForBackgroundSession (NSUrlSession session) {
  // Handle new information, update UI, etc.
}

Po dokončení zpracování nového obsahu zavolejte obslužnou rutinu dokončení, aby systém věděl, že je bezpečné pořídit snímek aplikace a vrátit se do režimu spánku:

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 ();
  }
}

Tento názorný postup popisuje základní kroky implementace služby pro přenos na pozadí v iOSu 7 a novějším.