Microsoft Azure

Zeitweise verbundene Daten in plattformübergreifenden mobilen Apps

Kevin Ashley

Laden Sie die Codebeispiele herunter

Die meisten mobilen Apps müssen für bestimmte Zeiträume offline geschaltet werden, und die Benutzer mobiler Geräte erwarten, dass ihre Apps im verbundenen sowie im getrennten Zustand ordnungsgemäß funktionieren. Hunderte Millionen Benutzer von mobilen Geräten sind sich möglicherweise nicht der Anforderungen bewusst, die Apps bezüglich des Online- und Offlinezustands stellen. Sie erwarten einfach, dass ihre Apps unter allen Umständen funktionieren. In diesem Artikel erfahren Sie, wie Ihre mobilen Apps in beiden Zuständen funktionieren und ordnungsgemäß Daten mit der Cloud in Windows, iOS und Android mithilfe von plattformübergreifenden Xamarin-Tools und Microsoft Azure Mobile Services synchronisieren können.

Da ich selbst mobile Apps entwickle, war es mir schon sehr früh klar, dass Offlinedaten synchronisiert werden müssen. Bei meiner Ski-App von Winter Sports (winter-sports.co) und der Active Fitness-Aktivitätsnachverfolgungs-App (activefitness.co) ist es nicht überraschend, dass auf der Piste oder während des Laufens die Verbindung schlecht ist. Daher müssen diese Apps in der Lage sein, offline erfasste Daten zu synchronisieren, ohne dass sich dies auf die Akkulaufzeit und die Zuverlässigkeit auswirkt. Anders ausgedrückt, müssen die Apps unter allen Bedingungen effizient funktionieren. 

Persistenter Speicher ist jedoch komplexer als auf den ersten Blick ersichtlich. Für die Synchronisierung sind mehrere Ansätze verfügbar. Sie kann in einer App oder als Hintergrundprozess im Betriebssystem ausgeführt werden. Außerdem sind verschiedene Typen von Datenspeichern verfügbar, z. B. halbstrukturierte Daten von Sensoren und potenzielle, in SQLite gespeicherte relationale Daten. Außerdem ist es wichtig, eine Richtlinie für die Konfliktlösung zu implementieren, damit Datenverluste und Leistungsverschlechterungen so gering wie möglich ausfallen. Schließlich muss noch eine große Vielzahl von Datenformaten verwaltet werden, z. B. Binärdaten, JSON-, XML- und benutzerdefinierte Formate.

Mobile Apps speichern normalerweise mehrere Datentypen. Strukturierte Daten (z. B. JSON oder XML) werden in der Regel für lokale Einstellungen, lokale Dateien oder Caching verwendet. Sie können Daten nicht nur in Dateien speichern, sondern wahlweise auch Speichermodule (z. B. SQLite) zum Speichern und Abfragen von Daten verwenden. Mobile Apps können auch BLOBs, Mediendateien und andere Typen von großen binären Daten speichern. Für diese Datentypen zeige ich Techniken, die die Datenübertragung auf gelegentlich verbundenen Geräten zuverlässiger machen. Ich werden mehrere Technologien im Überblick vorstellen. Anstatt beispielsweise die Offlinesynchronisierung für strukturierte Daten allein in den Vordergrund zu stellen, zeige ich Ihnen breiter angelegte Techniken für die Synchronisierung strukturierter und unstrukturierter Daten (BLOBs). Außerdem verwende ich in allen Beispielen einen plattformübergreifenden Ansatz.

Der plattformübergreifende Ansatz

Da es sich zunehmender Beliebtheit erfreut, mit Sensoren ausgestattete Geräte mit der Cloud zu verbinden, habe ich auch Daten von Gerätesensoren in meinem Projekt berücksichtigt, um verschiedene Methoden der Synchronisierung mit der Cloud zu zeigen. Ich werde drei Szenarien behandeln: Offlinedatensynchronisierung, manuelle Datensynchronisierung und die Synchronisierung großer Mediendateien und Binärdaten. Das begleitende Codebeispiel ist ohne Einschränkungen plattformübergreifend und kann zu 100 % für Android, iOS und Windows verwendet werden. Ich habe „Xamarin.Forms“ verwendet, um dieses Ziel zu erreichen – plattformübergreifende XAML/C#-Tools, die gut unter iOS, Android und Windows funktionieren und zurzeit in die Visual Studio-Tools integriert werden (siehe Microsoft Channel 9-Video „Cross-Platform Mobile Development Using Visual Studio“ unter bit.ly/1xyctO2).

Im Codebeispiel sind zwei Klassen vorhanden, die plattformübergreifende Datenmodelle verwalten: „SensorDataItem“ und „SensorModel“. Dieser Ansatz kann von zahlreichen Sport- und Fitness-Apps (z. B. Active Fitness) oder von Apps verwendet werden, die eine Synchronisierung strukturierter Daten aus dem lokalen Speicher mit der Cloud ausführen müssen. Ich habe der Klasse „SensorDataItem “ die Angaben „latitude“ (Breitengrad), „longitude“ (Längengrad), „speed“ (Geschwindigkeit) und „distance“ (Wegstrecke) als Beispiel für von Sensoren (z. B. GPS) erfasste Daten hinzugefügt, um das Konzept zu verdeutlichen. Die Datenstruktur in der eigentlichen App kann natürlich komplexer sein (und Abhängigkeiten enthalten) – mein Beispiel verdeutlicht jedoch die Idee, die hinter diesem Konzept steht.

Synchronisieren strukturierter Daten mit Offlinesynchronisierung

Offlinesynchronisierung ist ein leistungsfähiges neues Feature in Azure Mobile Services. Sie können in Ihrem Visual Studio-Projekt mithilfe von NuGet auf das Azure Mobile Services-Paket verweisen. Außerdem ist durch die neue Version des Azure Mobile Services SDKs wichtige Unterstützung für plattformübergreifende Apps verfügbar. Dies bedeutet, dass Sie dieses Feature in Ihren Windows-, iOS- und Android-Apps verwenden können, die gelegentlich eine Verbindung mit der Cloud herstellen und ihre Zustände synchronisieren müssen.

Zuerst stelle ich einige Konzepte vor.

Synchronisierungstabelle. Dies ist ein neues Objekt im Azure Mobile Services SDK, das erstellt wurde, um Tabellen unterscheiden zu können, die Synchronisierung aus „lokalen“ Tabellen unterstützen. Synchronisierungstabellen implementieren die IMobileServiceSyncTable<T>-Schnittstelle und enthalten zusätzliche „Synchronisierungsmethoden“, z. B. „PullAsync“, „PushAsync“ und „Purge“. Wenn Sie Ihre Offlinesensordaten mit der Cloud synchronisieren möchten, müssen Sie Synchronisierungstabellen anstelle von Standardtabellen verwenden. In meinem Codebeispiel initialisiere ich meine Sensordaten-Synchronisierungstabelle mithilfe des Aufrufs „GetSyncTable<T>“. Im Azure Mobile Services-Portal habe ich eine reguläre Tabelle namens „SensorDataItem“ erstellt und den Code aus Abbildung 1 der Clientinitialisierung hinzugefügt (Sie können den vollständigen Quellcode unter bit.ly/11yZyhN herunterladen).

Der Synchronisierungskontext. Dieser ist für die Synchronisierung von Daten zwischen lokalen und Remotespeichern verantwortlich. Im Lieferumfang von Azure Mobile Services ist SQLiteStore enthalten. Dieses Produkt basiert auf der beliebten SQLite-Bibliothek. Der Code in Abbildung 1 führt einige Aufgaben aus. Er überprüft, ob bereits ein Synchronisierungskontext initialisiert wurde. Wenn dies nicht der Fall ist, erstellt er eine neue Instanz des SQLite-Speichers aus der Datei „local.db“, definiert die Tabelle basierend auf der Klasse „SensorDataItem“ und initialisiert den Speicher. Zur Verarbeitung ausstehender Vorgänge verwendet der Synchronisierungskontext eine Warteschlange, auf die über die Eigenschaft „PendingOperations“ zugegriffen werden kann. Der von Azure Mobile Services bereitgestellte Synchronisierungskontext ist außerdem „intelligent“ genug, um Aktualisierungsvorgänge unterscheiden zu können, die im lokalen Speicher stattfinden. Die Synchronisierung erfolgt automatisch durch das System. Sie müssen also nicht manuell und unnötigerweise einen Aufruf in die Cloud senden, um Daten persistent zu speichern. Dies ist sinnvoll, weil der Datenverkehr verringert und die Lebensdauer des Geräteakkus verlängert wird.

Abbildung 1 – Nutzen des MobileServiceSQLiteStore-Objekts für die Synchronisierung

// Initialize the client with your app URL and key
client = new MobileServiceClient(applicationURL, applicationKey);
// Create sync table instance
todoTable = client.GetSyncTable<SensorDataItem>();
// Later in code
public async Task InitStoreAsync()
{
  if (!client.SyncContext.IsInitialized)
  {
    var store = new MobileServiceSQLiteStore(syncStorePath);
    store.DefineTable<SensorDataItem>();
    await client.SyncContext.InitializeAsync(store,
      new MobileServiceSyncHandler   ());
  }
}

Der Pushvorgang. Mit diesem können Sie explizit Daten zwischen dem lokalen Speicher und dem Cloud-Speicher synchronisieren, indem Sie lokale Daten mithilfe von Push an den Server senden. Sie müssen unbedingt beachten, dass Push und Pull in der aktuellen Version des Azure Mobile Services SDKs explizit aktiviert werden müssen, um den Kontext zu synchronisieren. Der Pushvorgang wird für den gesamten Synchronisierungskontext ausgeführt, damit die Beziehungen zwischen Tabellen erhalten bleiben. Wenn Beziehungen zwischen Tabellen bestehen, ruft der erste Einfügevorgang eine ID des Objekts ab, und nachfolgende Einfügevorgänge behalten die referenzielle Integrität bei:

 

await client.SyncContext.PushAsync();

Der Pullvorgang. Mit diesem Vorgang können Sie Daten explizit synchronisieren, indem Sie Daten mithilfe von Pull aus einem Remotespeicher in den lokalen Speicher abrufen. Sie können LINQ zum Angeben einer Datenuntermenge oder eine beliebige OData-Abfrage verwenden. Im Gegensatz zu Pushvorgängen, die für den gesamten Kontext ausgeführt werden, finden Pullvorgänge auf Tabellenebene statt. Wenn Elemente in der Synchronisierungswarteschlange ausstehend sind, erfolgt der Pushvorgang für diese Elemente zuerst – bevor Pullvorgänge ausgeführt werden –, um Datenverluste zu verhindern (ein weiterer Vorteil der Verwendung von Azure Mobile Services für die Datensynchronisierung). In diesem Beispiel rufe ich mithilfe von Pull Daten ab, deren Geschwindigkeit ungleich null ist (z. B. von meinem GPS-Sensor erfasste Daten), die zuvor auf dem Server gespeichert wurden:

var query = sensorDataTable.Where(s => s.speed > 0);
await sensorDataTable.PullAsync(query);

Der Bereinigungsvorgang. Dieser Vorgang löscht angegebene Daten aus den lokalen Tabellen und den Remotetabellen und bewirkt die Synchronisierung. Analog zum Pullvorgang können Sie LINQ zum Angeben einer Datenuntermenge oder eine beliebige OData-Abfrage verwenden. In diesem Beispiel bereinige ich die Daten, deren Wegstrecke null ist (Daten, die ggf. ebenfalls von meinem GPS-Sensor stammen), aus meinen Tabellen:

var query = sensorDataTable.Where(s => s.distance == 0);
await sensorDataTable.PurgeAsync(query);

Geeignete Konfliktbehandlung. Dies ist ein wichtiger Teil Ihrer Datensynchronisierungsstrategie, wenn Geräte online und offline geschaltet werden. Konflikte werden auftreten, und das Azure Mobile Services SDK stellt Verfahren zum Behandeln von Konflikten zur Verfügung. Damit die Konfliktlösung funktioniert, habe ich die Eigenschaftenspalte „Version“ für das SensorDataItem-Objekt aktiviert. Außerdem habe ich die Klasse „ConflictHandler“ erstellt, die die IMobileServiceSyncHandler-Schnittstelle implementiert. Wenn Sie einen Konflikt lösen müssen, stehen drei Optionen zur Verfügung: Beibehalten des Clientwerts, Beibehalten des Serverwerts oder Abbrechen des Pushvorgangs.

Überprüfen Sie in meinem Beispiel die Klasse „ConflictHandler“. Nach ihrer Initialisierung lege ich im Konstruktor eine der drei Richtlinien für Konfliktlösung fest:

public enum ConflictResolutionPolicy
{
  KeepLocal,
  KeepRemote,
  Abort
}

Abhängig von der Methode wende ich bei jedem Auftreten eines Konflikts in der Methode „ExecuteTableOperationAsync“ automatisch meine Richtlinie für Konfliktlösung an. Wenn ich meinen Synchronisierungskontext initialisiere, übergeben ich meine Klasse „ConflictHandler“ an den Synchronisierungskontext mit meiner Standardrichtlinie für Konfliktlösung:

await client.SyncContext.InitializeAsync(
  store,
  new ConflictHandler(client, ConflictResolutionPolicy.KeepLocal)
);

Weitere Informationen zur Konfliktlösung finden Sie im MSDN-Beispiel „Azure Mobile Services – Behandeln von Konflikten mit Offline WP8“ unter bit.ly/14FmZan sowie im Artikel zur Azure-Dokumentation „Behandeln von Konflikten bei der Synchronisierung von Offlinedaten in Mobile Services“ unter bit.ly/1zA01eo.

Manuelles Synchronisieren serialisierter Daten

Vor der Bereitstellung von Funktionen für die Offlinesynchronisierung durch Azure Mobile Services mussten Entwickler Datensynchronisierung manuell implementieren. Wenn Sie also eine App entwickeln, die gelegentlich Daten synchronisieren muss, und Sie verwenden das Offlinesynchronisierungsfeature von Azure Mobile Services nicht, können Sie die Synchronisierung manuell ausführen (auch wenn ich Ihnen unbedingt empfehle, sich das Offlinesynchronisierungsfeature anzusehen). Sie können direkte Objektserialisierung (z. B. mit einem JSON-Serialisierer) in Dateien oder Serialisierung in Datenspeichermodule wie etwa SQLite ausführen. Der Hauptunterschied zwischen dem Offlinesynchronsierungsmechanismus und der manuellen Synchronisierung besteht darin, dass Sie im letztgenannten Fall die meiste Arbeit selbst erledigen müssen. Eine Methode zum Ermitteln, ob Daten synchronisiert wurden, besteht im Verwenden der Eigenschaft „Id“ eines beliebigen Objekts in Ihrem Datenmodell. Sehen Sie sich z. B. die Klasse „SensorDataItem“ an, die in meinem Beispiel oben verwendet wurde. Beachten Sie dabei die in Abbildung 2 gezeigten Felder „Id“ und „Version“.

Abbildung 2 – Datenstruktur für Datensynchronisierung

public class SensorDataItem
{
  public string Id { get; set; }
  [Version]
  public string Version { get; set; }
  [JsonProperty]
  public string text { get; set; }
  [JsonProperty]
  public double latitude { get; set; }
  [JsonProperty]
  public double longitude { get; set; }
  [JsonProperty]
  public double distance { get; set; }
  [JsonProperty]
  public double speed { get; set; }
}

Wenn ein Datensatz in eine Remotedatenbank eingefügt wird, erstellt Azure Mobile Services automatisch eine ID und weist diese dem Objekt zu. Die ID ist also ein Wert ungleich null, nachdem der Datensatz eingefügt wurde, und null, wenn der Datensatz niemals mit der Datenbank synchronisiert wurde:

// Manually synchronizing data
if (item.Id == null)
{
  await this.sensorDataTable.InsertAsync(item);
}

Das manuelle Synchronisieren von Löschungen und Aktualisierungen ist ein weitaus komplexerer Vorgang und stellt die größere Herausforderung dar. Dieser Vorgang geht jedoch über den Rahmen dieses Artikels hinaus. Wenn Sie auf der Suche nach einer umfassenden Synchronisierungslösung sind, sollten Sie die Offlinesynchronisierungsfeatures des Azure Mobile Services SDKs in Betracht ziehen. Dieses Beispiel ist im Vergleich zu Szenarien aus der Praxis sicher einfach. Wenn Sie jedoch planen, manuelle Datensynchronisierung zu implementieren, kann es ein erster Hinweis sein, wie Sie beginnen können. Da das Azure Mobile Services SDK eine getestete, gut durchdachte Lösung zum Synchronisieren von Daten bereitstellt, empfehle ich Ihnen, den Offlinesynchronisierungsansatz auszuprobieren. Dies gilt insbesondere für Apps, die ein solides, getestetes Verfahren für die Synchronisierung von lokalen und Remotedaten erfordern.

Übertragen von Binärdaten, Fotos und Mediendateien in die Cloud

Apps müssen neben strukturierten Daten häufig unstrukturierte oder Binärdaten oder -dateien synchronisieren. Dies gilt z. B. für eine mobile Foto-App oder eine App, die eine Binärdatei in die Cloud hochladen muss, z. B. ein Foto oder ein Video. Da ich dieses Thema in einem plattformübergreifenden Kontext behandele, müssen die unterschiedlichen Funktionen der verschiedenen Plattformen berücksichtigt werden. Sind diese Funktionen jedoch wirklich so unterschiedlich? Die Synchronisierung von BLOB-Daten kann auf verschiedene Weise erreicht werden, z. B. als ein In-Process-Dienst oder durch Nutzen eines plattformspezifischen Out-of-Process-Übertragungsdiensts im Hintergrund. Damit Downloads verwaltet werden können, habe ich auch eine einfache Klasse „TransferQueue “ bereitgestellt, die auf „ConcurrentQueue“ basiert. Jedes Mal, wenn ich eine Datei für den Upload oder Download übermitteln möchte, füge ich der Warteschlange ein neues Job-Objekt hinzu. Dieses Muster wird auch in der Cloud häufig verwendet, wenn Sie nicht fertiggestellte Arbeit in einer Warteschlange speichern, die von einem anderen Hintergrundprozess aus der Warteschlange gelesen und dann fertiggestellt wird.

In-Process-Dateiübertragung. Manchmal müssen Sie Dateien direkt aus Ihrer App übertragen. Dies ist die offensichtlichste Art der BLOB-Übertragung, besitzt jedoch – wie bereits erwähnt – Nachteile. Damit die Benutzererfahrung geschützt wird, führt das Betriebssystem eine Kappung der Bandbreiten- und Ressourcenverwendung Ihrer App aus. Dabei wird jedoch vorausgesetzt, dass der Benutzer die App zum Arbeiten verwendet. Im Fall von gelegentlich getrennten Apps ist dies möglicherweise nicht der beste Ansatz. Der Vorteil der direkten Übertragung von Dateien aus einer App besteht darin, dass die App die vollständige Kontrolle über die Datenübertragung besitzt. Durch die vollständige Kontrolle kann eine App SAS-Methoden zum Verwalten von Uploads und Downloads nutzen. Diese Vorteile werden im Beitrag „Introducing Table SAS (Shared Access Signature), Queue SAS and Update to Blob SAS“ unter bit.ly/1t1Sb94 des Blogs des Microsoft Azure Storage-Teams vorgestellt. Nicht in allen Plattformen ist diese Funktion integriert. Wenn Sie jedoch einen auf REST basierenden Ansatz in Betracht ziehen, können Sie SAS-Schlüssel aus Azure Storage Services sicher nutzen. Zwei Nachteile sind mit der direkten Übertragung von Dateien aus einer App verbunden. Einerseits müssen Sie mehr Code schreiben. Andererseits muss die App ausgeführt werden. Sie verringert dabei potenziell die Akkulebensdauer und schränkt die Benutzererfahrung ein. Die besten Lösungen nutzen einen Teil der Eleganz integrierter Datensynchronisierungstechniken.

Ich habe Quellcode für einen grundlegenden Upload- und Downloadvorgang in einer plattformübergreifenden Xamarin-App in der Datei „BlobTransfer.cs“ (siehe begleitender Codedownload) bereitgestellt. Dieser Code sollte unter iOS, Android und Windows funktionieren. Damit plattformunabhängiger Dateispeicher verwendet werden kann, habe ich das NuGet-Paket „PCLStorage“ („Install-Package PCLStorage“) verwendet, das eine Abstraktion von Dateivorgängen unter iOS, Android und Windows ermöglicht.

Zum Initiieren einer In-Process-Übertragung rufe ich meine Methode „TransferQueue AddInProcessAsync“ auf:

var ok = await queue.AddInProcessAsync(new Job {
  Id = 1, Url = imageUrl, LocalFile = String.Format("image{0}.jpg", 1)});

Durch diesen Vorgang wird ein typischer In-Process-Downloadvorgang geplant, der im BlobTransfer-Objekt wie in Abbildung 3 gezeigt definiert ist.

Abbildung 3 – Downloadvorgang (plattformübergreifender Code)

public static async Task<bool> DownloadFileAsync(
  IFolder folder, string url, string fileName)
{
  // Connect with HTTP
  using (var client = new HttpClient())
  // Begin async download
  using (var response = await client.GetAsync(url))
  {
    // If ok?
    if (response.StatusCode == System.Net.HttpStatusCode.OK)
    {
      // Continue download
      Stream temp = await response.Content.ReadAsStreamAsync();
      // Save to local disk
      IFile file = await folder.CreateFileAsync(fileName,
        CreationCollisionOption.ReplaceExisting);
      using (var fs =
        await file.OpenAsync(PCLStorage.FileAccess.ReadAndWrite))
      {
        // Copy to temp folder
        await temp.CopyToAsync(fs); 
        fs.Close();
        return true;
      }
    }
    else
    {
      Debug.WriteLine("NOT FOUND " + url);
      return false;
    }
  }
}

Wenn Sie eine Datei hochladen möchten, können Sie dies natürlich In-Process mithilfe der in Abbildung 4 gezeigten Methode ausführen.

Abbildung 4 – Uploadvorgang (plattformübergreifender Code)

public static async Task UploadFileAsync(
  IFolder folder, string fileName, string fileUrl)
{
  // Connect with HTTP
  using (var client = new HttpClient()) 
  {
    // Start upload
    var file = await folder.GetFileAsync(fileName);
    var fileStream = await file.OpenAsync(PCLStorage.FileAccess.Read);
    var content = new StreamContent(fileStream);
    // Define content type for blob
    content.Headers.Add("Content-Type", "application/octet-stream");
    content.Headers.Add("x-ms-blob-type", "BlockBlob");
    using (var uploadResponse = await client.PutAsync(
      new Uri(fileUrl, UriKind.Absolute), content))
    {
      Debug.WriteLine("CLOUD UPLOADED " + fileName);
      return;
    }
  }
}

Out-of-Process-Dateiübertragung mithilfe eines betriebssystemspezifischen Übertragungsdiensts. Das Herunterladen und Hochladen von Dateien mithilfe integrierter Dateiübertragungsdienste besitzt zahlreiche Vorteile. Die meisten Plattformen stellen einen Dienst zur Verfügung, der große Dateien (Upload und Download) autonom als Hintergrunddienst übertragen kann. Sie sollten solche Dienste nach Möglichkeit nutzen, weil sie Out-of-Process ausgeführt werden – dies bedeutet, das keine Kappung Ihrer App für die tatsächliche Datenübertragung stattfindet. Diese kann hinsichtlich der genutzten Ressourcen recht teuer sein. Außerdem muss Ihre App nicht während der gesamten Übertragung von Dateien im In-Memory-Status verbleiben, und das Betriebssystem stellt normalerweise einen Konfliktlösungsmechanismus (Wiederholungsversuche) zum Neustarten von Uploads und Downloads zur Verfügung. Weitere Vorteile bestehen darin, dass weniger Code geschrieben werden muss, die App nicht aktiv sein muss (das Betriebssystem verwaltet seine eigene Warteschlange für Uploads und Downloads) und die App eine größere Arbeitsspeicher-/Ressourceneffizienz aufweist. Die Herausforderung liegt jedoch darin, dass für diese Methode eine plattformspezifische Implementierung erforderlich ist: iOS, Windows Phone usw. verfügen über eigene Implementierungen für die Datenübertragung im Hintergrund.

Unter konzeptuellen Gesichtspunkten ähnelt ein zuverlässiger Upload für Dateien in einer mobilen App mithilfe eines betriebssystemspezifischen Out-of-Process-Diensts der Implementierung in der App. Die eigentliche Verwaltung der Upload-/Downloadwarteschlange wird jedoch ausgelagert und vom Übertragungsdienst des Betriebssystems übernommen. Für Windows Phone Store-Apps und Windows Store-Apps können Entwickler BackgroundDownloader- und BackgroundUploader-Objekte verwenden. Für iOS 7 und höher stellt „NSUrlSession“ die Methoden „CreateDownloadTask“ und „CreateUploadTask“ zum Initiieren von Downloads und Uploads bereit.

Mithilfe meines weiter oben beschriebenen Beispiels muss ich nun meine Out-of-Process-Methode aufrufen, um einen Aufruf mithilfe des betriebssystemspezifischen Hintergrundübertragungsdiensts auszuführen. Da der Dienst vom Betriebssystem verarbeitet wird, plane ich 10 Downloads, um zu zeigen, dass die App nicht blockiert und die Ausführung vom Betriebssystem verarbeitet wird (in diesem Beispiel habe ich den iOS-Hintergrundübertragungsdienst verwendet):

for (int i = 0; i < 10; i++)
{
  queue.AddOutProcess(new Job { Id = i, Url = imageUrl,
    LocalFile = String.Format("image{0}.jpg", i) });
}

Ein Beispiel für einen Hintergrundübertragungsdienst für iOS finden Sie in der Datei „BackgroundTransferService.cs“. In iOS müssen Sie zuerst eine Hintergrundsitzung mit „CreateBackgroundSessionConfiguration“ initialisieren (beachten Sie, dass dies nur mit iOS 8 oder höher fuktioniert):

using (var configuration = NSUrlSessionConfiguration.
  CreateBackgroundSessionConfiguration(sessionId))
{
  session = NSUrlSession.FromConfiguration(configuration);
}

Anschließend können Sie einen Upload- oder Downloadvorgang mit langer Ausführungszeit übermitteln, und das Betriebssystem übernimmt diesen unabhängig von Ihrer App:

using (var uri = NSUrl.FromString(url))
using (var request = NSUrlRequest.FromUrl(uri))
{
  downloadTask = session.CreateDownloadTask(request);
  downloadTask.Resume();
}

Sie müssen außerdem einen Warteschlangenmechanismus berücksichtigen, um BLOBs erfolgreich hoch- und herunterzuladen.

Beispielcode und nächste Schritte

Der gesamte Beispielcode für diesen Artikel ist auf GitHub unter bit.ly/11yZyhN verfügbar. Wenn Sie diesen Quellcode verwenden möchten, können Sie mit Visual Studio mit Xamarin oder mit Xamarin Studio arbeiten. Dieses Produkt kann von xamarin.com bezogen werden. Das Projekt verwendet plattformübergreifende Xamarin.Forms-Tools und die Azure Mobile Services-Bibliothek mit Offlinesynchronisierung. In den nächsten Schritten wäre es interessant zu sehen, wenn ein Out-of-Process-Dienst den Communitybibliotheken hinzugefügt würde, z. B. Xamarin Labs, sowie Warteschlangenfunktionen und Konfliktlösung ähnlich den Lösungen für strukturierte Daten, die im Azure Mobile Services Offline Sync SDK bereitgestellt werden.

Zusammengefasst lässt sich sagen, dass Microsoft Azure Mobile Services ein leistungsfähiges und effizientes Verfahren zum Synchronisieren von Offlinedaten bereitstellen. Sie können diese Dienste in einem plattformübergreifenden Szenario unter Windows, Android und iOS verwenden. Microsoft stellt außerdem einfach zu verwendende, systemeigene SDKs zur Verfügung, die auf jeder Plattform funktionieren. Sie können die Zuverlässigkeit Ihrer App in getrennten Szenarien optimieren, indem Sie diese Dienste integrieren und Ihren Apps Offlinesynchronisierung hinzufügen.


Kevin Ashley ist ein Architect Evangelist bei Microsoft. Er ist ein Mitautor von „Professional Windows 8 Programming“ (Wrox, 2012) sowie Entwickler erstklassiger Apps und Spiele, insbesondere von Active Fitness (activefitness.co). Er stellt häufig auf verschiedenen Events und Branchenmessen sowie in Webcasts Technologien vor. Er arbeitet mit Startupunternehmen und Partnern zusammen und berät diese bezüglich des Softwareentwurfs, der Geschäfts- und Technologiestrategie, der Architektur und der Entwicklung. Folgen Sie ihm auf seinem Blog unter kevinashley.com und bei Twitter unter twitter.com/kashleytwit.

Unser Dank gilt den folgenden technischen Experten von Microsoft für die Durchsicht dieses Artikels: Greg Oliver und Bruno Terkaly