Teilen über


watchOS-Hintergrundaufgaben in Xamarin

Mit watchOS 3 gibt es drei Standard Möglichkeiten, wie eine Watch-App ihre Informationen auf dem neuesten Stand halten kann:

  • Verwenden sie eine der verschiedenen neuen Hintergrundaufgaben.
  • Eine seiner Komplikationen auf der Uhrsicht zu haben (es gibt zusätzliche Zeit, um zu aktualisieren).
  • Lassen Sie den Benutzer an die App an das neue Dock anheften (wo er häufig im Arbeitsspeicher gespeichert und aktualisiert wird).

Halten einer App auf dem neuesten Stand

Bevor Sie alle Möglichkeiten besprechen, wie ein Entwickler die Daten und die Benutzeroberfläche einer WatchOS-App aktuell und aktualisiert halten kann, wird dieser Abschnitt einen Blick auf einen typischen Satz von Verwendungsmustern werfen und wie ein Benutzer zwischen seinem i Telefon und seiner Apple Watch im Laufe des Tages wechseln kann, basierend auf der Tageszeit und der Aktivität, die sie derzeit ausführen (z. B. Fahren).

Betrachten Sie das folgende Beispiel:

Wie ein Benutzer während des tages zwischen i Telefon und der Apple Watch wechseln kann

  1. Am Morgen, während er auf einen Kaffee wartet, durchsucht der Benutzer die aktuellen Nachrichten auf dem i Telefon mehrere Minuten.
  2. Bevor sie den Café verlassen, überprüfen sie schnell das Wetter mit einer Komplikation auf ihrem Watch-Gesicht.
  3. Vor dem Mittagessen verwenden sie die Karten App auf dem i Telefon um ein restaurant in der Nähe zu finden und eine Reservierung zu buchen, um einen Kunden zu treffen.
  4. Während sie ins Restaurant reisen, erhalten sie eine Benachrichtigung auf ihrer Apple Watch und mit einem schnellen Blick, sie wissen, dass ihr Mittagessen spät läuft.
  5. Am Abend verwenden sie die Karten-App auf dem i Telefon, um den Verkehr vor dem Heimfahren zu überprüfen.
  6. Auf dem Weg nach Hause erhalten sie eine iMessage-Benachrichtigung auf ihrer Apple Watch, die sie auffordern, milch aufzunehmen, und sie verwenden die Funktion "Schnelle Antwort", um die Antwort "OK" zu senden.

Aufgrund des "Schnellen Blicks" (weniger als drei Sekunden) gibt es in der Regel nicht genügend Zeit für die App, um die gewünschten Informationen abzurufen und die Benutzeroberfläche zu aktualisieren, bevor sie dem Benutzer angezeigt wird.

Mit den neuen APIs, die Apple in watchOS 3 enthalten hat, kann die App eine Hintergrundaktualisierung planen und die gewünschten Informationen bereit haben, bevor der Benutzer sie anfordert. Nehmen Sie sich das Beispiel der oben beschriebenen Wetterkomplikation an:

Beispiel für die Wetterkomplikation

  1. Die App plant, das System zu einem bestimmten Zeitpunkt aufzuwachen.
  2. Die App ruft die Informationen ab, die zum Generieren des Updates erforderlich sind.
  3. Die App generiert die Benutzeroberfläche neu, um die neuen Daten widerzuspiegeln.
  4. Wenn der Benutzer auf die Komplikation der App blickt, enthält er aktuelle Informationen, ohne dass der Benutzer auf das Update warten muss.

Wie oben gezeigt, aktiviert das WatchOS-System die App mit einem oder mehreren Aufgaben, von denen es über einen sehr begrenzten Pool verfügt:

Das WatchOS-System aktiviert die App mit einem oder mehreren Aufgaben

Apple schlägt vor, diesen Vorgang optimal zu machen (da es sich um eine solche begrenzte Ressource für die App handelt), indem er sie gedrückt hält, bis die App den Prozess der Aktualisierung selbst abgeschlossen hat.

Das System liefert diese Aufgaben, indem die neue HandleBackgroundTasks Methode des WKExtensionDelegate Delegaten aufgerufen wird. Zum Beispiel:

using System;
using Foundation;
using WatchKit;

namespace MonkeyWatch.MonkeySeeExtension
{
  public class ExtensionDelegate : WKExtensionDelegate
  {
    #region Constructors
    public ExtensionDelegate ()
    {
    }
    #endregion

    #region Override Methods
    public override void HandleBackgroundTasks (NSSet<WKRefreshBackgroundTask> backgroundTasks)
    {
      // Handle background request here
      ...
    }
    #endregion
  }
}

Wenn die App die angegebene Aufgabe abgeschlossen hat, wird sie durch Markieren der Aufgabe an das System zurückgegeben:

Der Vorgang kehrt zum System zurück, indem er als erledigt markiert wird.

Neue Hintergrundaufgaben

watchOS 3 führt mehrere Hintergrundaufgaben ein, mit denen eine App ihre Informationen aktualisieren kann, um sicherzustellen, dass der Benutzer über die Inhalte verfügt, die der Benutzer benötigt, bevor sie die App öffnen, z. B.:

  • Aktualisierung der Hintergrund-App – Die WKApplicationRefreshBackgroundTask-Aufgabe ermöglicht der App das Aktualisieren des Zustands im Hintergrund. In der Regel umfasst dies eine weitere Aufgabe, z. B. das Herunterladen neuer Inhalte aus dem Internet mithilfe einer NSUrlSession.
  • Aktualisierung der Hintergrundmomentaufnahme – Mit der WKSnapshotRefreshBackgroundTask-Aufgabe kann die App sowohl deren Inhalt als auch die Benutzeroberfläche aktualisieren, bevor das System eine Momentaufnahme verwendet, die zum Auffüllen des Docks verwendet wird.
  • Hintergrundüberwachung Verbinden ivity – Die WKWatch Verbinden ivityRefreshBackgroundTask-Aufgabe wird für die App gestartet, wenn sie Hintergrunddaten von der gekoppelten i Telefon empfängt.
  • Hintergrund-URL-Sitzung – Die WKURLSessionRefreshBackgroundTask-Aufgabe wird für die App gestartet, wenn eine Hintergrundübertragung autorisierung oder abgeschlossen ist (erfolgreich oder fehlerhaft).

Diese Aufgaben werden in den folgenden Abschnitten ausführlich behandelt.

WKApplicationRefreshBackgroundTask

Dies WKApplicationRefreshBackgroundTask ist eine generische Aufgabe, die geplant werden kann, damit die App zu einem zukünftigen Datum weckt wird:

Ein WKApplicationRefreshBackgroundTask weckte zu einem zukünftigen Datum

Innerhalb der Laufzeit der Aufgabe kann die App jede Art von lokaler Verarbeitung ausführen, z. B. eine Komplikation Zeitleiste aktualisieren oder einige erforderliche Daten mit einem NSUrlSessionabrufen.

WKURLSessionRefreshBackgroundTask

Das System sendet einen WKURLSessionRefreshBackgroundTask Zeitpunkt, an dem die Daten heruntergeladen und bereit sind, von der App verarbeitet zu werden:

WKURLSessionRefreshBackgroundTask, wenn der Download der Daten abgeschlossen ist

Eine App wird nicht ausgeführt, während Daten im Hintergrund heruntergeladen werden. Stattdessen plant die App die Anforderung für Daten, wird sie angehalten, und das System verarbeitet das Herunterladen der Daten, nur wenn der Download abgeschlossen ist.

WKSnapshotRefreshBackgroundTask

In watchOS 3 hat Apple das Dock hinzugefügt, in dem Benutzer ihre bevorzugten Apps anheften und schnell darauf zugreifen können. Wenn der Benutzer die Randschaltfläche auf der Apple Watch drückt, wird ein Katalog mit angehefteten App-Momentaufnahmen angezeigt. Der Benutzer kann nach links oder rechts wischen, um die gewünschte App zu finden, und tippen Sie dann auf die App, um sie zu starten, um die Momentaufnahme durch die Benutzeroberfläche der ausgeführten App zu ersetzen.

Ersetzen der Momentaufnahme durch die ausgeführte App-Schnittstelle

Das System übernimmt regelmäßig Momentaufnahme der Benutzeroberfläche der App (durch Senden eines WKSnapshotRefreshBackgroundTask) und verwendet diese Momentaufnahme, um das Dock aufzufüllen. watchOS bietet der App die Möglichkeit, den Inhalt und die Benutzeroberfläche zu aktualisieren, bevor diese Momentaufnahme erstellt wird.

Momentaufnahmen sind in watchOS 3 sehr wichtig, da sie sowohl als Vorschau- als auch als Startimages für die App funktionieren. Wenn sich der Benutzer in einer App im Dock abgleicht, wird er auf den Vollbildmodus erweitert, in den Vordergrund eingegeben und gestartet. Daher ist es zwingend erforderlich, dass die Momentaufnahme auf dem neuesten Stand ist:

Wenn sich der Benutzer auf einer App im Dock behebt, wird er auf den Vollbildmodus erweitert.

Auch hier stellt das System ein WKSnapshotRefreshBackgroundTask Problem aus, damit die App (durch Aktualisieren der Daten und der Benutzeroberfläche) vorbereiten kann, bevor die Momentaufnahme ausgeführt wird:

Die App kann vorbereitet werden, indem sie die Daten und die Benutzeroberfläche aktualisiert, bevor die Momentaufnahme übernommen wird.

Wenn die App den WKSnapshotRefreshBackgroundTask Abschluss markiert, erstellt das System automatisch eine Momentaufnahme der Benutzeroberfläche der App.

Wichtig

Es ist wichtig, immer einen WKSnapshotRefreshBackgroundTask Termin zu planen, nachdem die App neue Daten empfangen und die Benutzeroberfläche aktualisiert hat, oder der Benutzer sieht die geänderten Informationen nicht.

Wenn der Benutzer eine Benachrichtigung von der App erhält und darauf tippt, um die App in den Vordergrund zu bringen, muss die Momentaufnahme auf dem neuesten Stand sein, da sie auch als Startbildschirm fungiert:

Der Benutzer erhält eine Benachrichtigung aus der App und tippt darauf, um die App in den Vordergrund zu bringen.

Wenn der Benutzer mehr als eine Stunde lang mit einer WatchOS-App interagiert hat, kann er zum Standardstatus zurückkehren. Der Standardstatus kann verschiedene Dinge für unterschiedliche Apps bedeuten, und basierend auf dem Design einer App verfügt er möglicherweise über keinen Standardstatus.

WKWatch Verbinden ivityRefreshBackgroundTask

In watchOS 3 verfügt Apple über die neue WKWatchConnectivityRefreshBackgroundTaskNeue über eine integrierte Watch-Konnektivität mit der Hintergrundaktualisierungs-API. Mit diesem neuen Feature kann eine i Telefon-App neue Daten an ihr Watch App-Gegenstück liefern, während die WatchOS-App im Hintergrund ausgeführt wird:

Eine i Telefon-App kann dem zugehörigen Watch-App-Gegenstück neue Daten liefern, während die WatchOS-App im Hintergrund ausgeführt wird.

Wenn Sie einen Komplikations-Push, App-Kontext initiieren, eine Datei senden oder Benutzerinformationen aus der i Telefon-App aktualisieren, wird die Apple Watch-App im Hintergrund aktiviert.

Wenn die Watch-App über eine WKWatchConnectivityRefreshBackgroundTask App weckt wird, muss sie die Standard-API-Methoden verwenden, um die Daten aus der i Telefon-App zu empfangen.

Der Datenfluss

  1. Stellen Sie sicher, dass die Sitzung aktiviert wurde.
  2. Überwachen Sie die neue HasContentPending Eigenschaft, solange der Wert ist true, hat die App weiterhin Daten, die verarbeitet werden sollen. Wie zuvor sollte die App die Aufgabe beibehalten, bis sie die Verarbeitung aller Daten abgeschlossen hat.
  3. Wenn keine weiteren Daten verarbeitet werden sollen (HasContentPending = false), markieren Sie die Aufgabe als abgeschlossen, um sie an das System zurückzugeben. Wenn Sie dies nicht tun, wird die zugewiesene Hintergrundlaufzeit der App erschöpft, was zu einem Absturzbericht führt.

Der Lebenszyklus der Hintergrund-API

Wenn Sie alle Teile der neuen Hintergrundaufgaben-API zusammen platzieren, würde ein typischer Satz von Interaktionen wie folgt aussehen:

Der Lebenszyklus der Hintergrund-API

  1. Zunächst plant die watchOS-App eine Hintergrundaufgabe so, dass sie in Zukunft wieder eingewoben wird.
  2. Die App wird vom System weckt und eine Aufgabe gesendet.
  3. Die App verarbeitet die Aufgabe, um alle erforderlichen Aufgaben auszuführen.
  4. Als Ergebnis der Verarbeitung der Aufgabe muss die App möglicherweise mehr Hintergrundaufgaben planen, um in Zukunft mehr Arbeit auszuführen, z. B. das Herunterladen weiterer Inhalte mit einem NSUrlSession.
  5. Die App markiert die Aufgabe abgeschlossen und gibt sie an das System zurück.

Verantwortungsvolle Nutzung von Ressourcen

Es ist wichtig, dass sich eine WatchOS-App verantwortungsbewusst innerhalb dieses Ökosystems verhält, indem sie die Belastung der gemeinsam genutzten Ressourcen des Systems einschränkt.

Sehen Sie sich das folgende Szenario an:

Eine WatchOS-App beschränkt den Abfluss auf die gemeinsam genutzten Ressourcen des Systems.

  1. Der Benutzer startet eine watchOS-App um 1:00 Uhr.
  2. Die App plant eine Aufgabe, um neue Inhalte in einer Stunde um 2:00 Uhr aufzuwachen und herunterzuladen.
  3. Um 1:50 Uhr öffnet der Benutzer die App erneut, sodass sie seine Daten und Ui zu diesem Zeitpunkt aktualisieren kann.
  4. Anstatt die App in 10 Minuten erneut zu aktivieren, sollte die App die Aufgabe neu planen, um eine Stunde später um 2:50 Uhr auszuführen.

Während jede App anders ist, schlägt Apple vor, Muster der Nutzung zu finden, wie die oben gezeigten, um Systemressourcen zu sparen.

Implementieren von Hintergrundaufgaben

Aus Gründen des Beispiels verwendet dieses Dokument die gefälschte MonkeySoccer-Sport-App, die dem Benutzer Fußballergebnisse meldet.

Sehen Sie sich das folgende typische Verwendungsszenario an:

Das typische Verwendungsszenario

Die Lieblings-Fußballmannschaft des Benutzers spielt ein großes Spiel von 17:00 bis 19:00 Uhr, sodass die App erwarten sollte, dass der Benutzer die Bewertung regelmäßig überprüft und sich für ein 30-minütiges Updateintervall entscheidet.

  1. Der Benutzer öffnet die App und plant eine Aufgabe für die Hintergrundaktualisierung 30 Minuten später. Die Hintergrund-API ermöglicht nur die Ausführung einer Hintergrundaufgabe zu einem bestimmten Zeitpunkt.
  2. Die App empfängt die Aufgabe und aktualisiert ihre Daten und die Benutzeroberfläche und plant dann 30 Minuten später eine weitere Hintergrundaufgabe. Es ist wichtig, dass der Entwickler daran erinnert, eine andere Hintergrundaufgabe zu planen, oder die App wird nie wieder eingewockt, um weitere Updates zu erhalten.
  3. Auch hier empfängt die App die Aufgabe und aktualisiert ihre Daten, aktualisiert die Benutzeroberfläche und plant eine weitere Hintergrundaufgabe 30 Minuten später.
  4. Derselbe Vorgang wiederholt sich erneut.
  5. Die letzte Hintergrundaufgabe wird empfangen, und die App aktualisiert erneut die Daten und die Benutzeroberfläche. Da dies die endgültige Bewertung ist, ist sie nicht für eine neue Hintergrundaktualisierung geplant.

Planen der Hintergrundaktualisierung

In Anbetracht des obigen Szenarios kann die MonkeySoccer-App den folgenden Code verwenden, um ein Hintergrundupdate zu planen:

private void ScheduleNextBackgroundUpdate ()
{
  // Create a fire date 30 minutes into the future
  var fireDate = NSDate.FromTimeIntervalSinceNow (30 * 60);

  // Create
  var userInfo = new NSMutableDictionary ();
  userInfo.Add (new NSString ("LastActiveDate"), NSDate.FromTimeIntervalSinceNow(0));
  userInfo.Add (new NSString ("Reason"), new NSString ("UpdateScore"));

  // Schedule for update
  WKExtension.SharedExtension.ScheduleBackgroundRefresh (fireDate, userInfo, (error) => {
    // Was the Task successfully scheduled?
    if (error == null) {
      // Yes, handle if needed
    } else {
      // No, report error
    }
  });
}

Sie erstellt eine neue NSDate 30 Minuten in die Zukunft, wenn die App eingewockt werden möchte, und erstellt eine NSMutableDictionary , um die Details der angeforderten Aufgabe zu halten. Die ScheduleBackgroundRefresh Methode der SharedExtension Aufgabe wird verwendet, um die Planung des Vorgangs anzufordern.

Das System gibt einen NSError Wert zurück, wenn er den angeforderten Vorgang nicht planen konnte.

Verarbeiten des Updates

Sehen Sie sich als Nächstes das 5-Minuten-Fenster mit den schritten an, die zum Aktualisieren der Bewertung erforderlich sind:

Das 5-Minuten-Fenster mit den erforderlichen Schritten zum Aktualisieren der Bewertung

  1. Um 17:30:02 Uhr wird die App vom System erwacht und erhält die Update-Hintergrundaufgabe. Die erste Priorität besteht darin, die neuesten Bewertungen vom Server zu erhalten. Siehe Planung einer NSUrlSession unten.
  2. Bei 7:30:05 schließt die App die ursprüngliche Aufgabe ab, das System versetzt die App in den Ruhezustand und lädt die angeforderten Daten im Hintergrund weiter herunter.
  3. Wenn das System den Download abgeschlossen hat, wird eine neue Aufgabe erstellt, um die App zu reaktivieren, damit sie die heruntergeladenen Informationen verarbeiten kann. Weitere Informationen finden Sie unter "Behandeln von Hintergrundaufgaben " und "Behandeln des Downloadabschlusses " weiter unten.
  4. Die App speichert die aktualisierten Informationen und markiert den Abgeschlossenen Vorgang. Der Entwickler kann versucht sein, die Benutzeroberfläche der App zu diesem Zeitpunkt zu aktualisieren, aber Apple schlägt vor, eine Momentaufnahmeaufgabe für die Verarbeitung dieses Prozesses zu planen. Siehe "Planen einer Momentaufnahmeaktualisierung " weiter unten.
  5. Die App empfängt die Momentaufnahmeaufgabe, aktualisiert die Benutzeroberfläche und kennzeichnet die Aufgabe abgeschlossen. Siehe "Behandeln einer Momentaufnahmeaktualisierung " weiter unten.

Planen einer NSUrlSession

Der folgende Code kann verwendet werden, um das Herunterladen der neuesten Bewertungen zu planen:

private void ScheduleURLUpdateSession ()
{
  // Create new configuration
  var configuration = NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration ("com.example.urlsession");

  // Create new session
  var backgroundSession = NSUrlSession.FromConfiguration (configuration);

  // Create and start download task
  var downloadTask = backgroundSession.CreateDownloadTask (new NSUrl ("https://example.com/gamexxx/currentScores.json"));
  downloadTask.Resume ();
}

Sie konfiguriert und erstellt eine neue NSUrlSessionUnd verwendet dann diese Sitzung, um eine neue Downloadaufgabe mithilfe der CreateDownloadTask Methode zu erstellen. Sie ruft die Resume Methode der Downloadaufgabe auf, um die Sitzung zu starten.

Behandeln von Hintergrundaufgaben

Durch Überschreiben der HandleBackgroundTasks Methode der WKExtensionDelegateApp können die eingehenden Hintergrundaufgaben verarbeitet werden:

using System;
using System.Collections.Generic;
using Foundation;
using WatchKit;

namespace MonkeySoccer.MonkeySoccerExtension
{
  public class ExtensionDelegate : WKExtensionDelegate
  {
    #region Computed Properties
    public List<WKRefreshBackgroundTask> PendingTasks { get; set; } = new List<WKRefreshBackgroundTask> ();
    #endregion

    ...

    #region Public Methods
    public void CompleteTask (WKRefreshBackgroundTask task)
    {
      // Mark the task completed and remove from the collection
      task.SetTaskCompleted ();
      PendingTasks.Remove (task);
    }
    #endregion

    #region Override Methods
    public override void HandleBackgroundTasks (NSSet<WKRefreshBackgroundTask> backgroundTasks)
    {
      // Handle background request
      foreach (WKRefreshBackgroundTask task in backgroundTasks) {
        // Is this a background session task?
        var urlTask = task as WKUrlSessionRefreshBackgroundTask;
        if (urlTask != null) {
          // Create new configuration
          var configuration = NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration (urlTask.SessionIdentifier);

          // Create new session
          var backgroundSession = NSUrlSession.FromConfiguration (configuration, new BackgroundSessionDelegate (this, task), null);

          // Keep track of all pending tasks
          PendingTasks.Add (task);
        } else {
          // Ensure that all tasks are completed
          task.SetTaskCompleted ();
        }
      }
    }
    #endregion

    ...
  }
}

Die HandleBackgroundTasks Methode durchsucht alle Aufgaben, die das System gesendet hat, die App (in backgroundTasks) nach einer WKUrlSessionRefreshBackgroundTask. Wenn eine gefunden wird, wird sie erneut an der Sitzung teilnehmen und fügt einen NSUrlSessionDownloadDelegate an, um den Download abzuschließen (siehe Behandeln des Downloadabschlusses unten):

// Create new session
var backgroundSession = NSUrlSession.FromConfiguration (configuration, new BackgroundSessionDelegate (this, task), null);

Sie behält ein Handle für die Aufgabe bei, bis sie abgeschlossen ist, indem sie einer Sammlung hinzugefügt wird:

public List<WKRefreshBackgroundTask> PendingTasks { get; set; } = new List<WKRefreshBackgroundTask> ();
...

// Keep track of all pending tasks
PendingTasks.Add (task);

Alle an die App gesendeten Aufgaben müssen abgeschlossen werden, damit alle Aufgaben, die derzeit nicht verarbeitet werden, als erledigt markieren:

if (urlTask != null) {
  ...
} else {
  // Ensure that all tasks are completed
  task.SetTaskCompleted ();
}

Behandeln des Abschlusses des Downloads

Die MonkeySoccer-App verwendet den folgenden NSUrlSessionDownloadDelegate Delegat, um den Download abzuschließen und die angeforderten Daten zu verarbeiten:

using System;
using Foundation;
using WatchKit;

namespace MonkeySoccer.MonkeySoccerExtension
{
  public class BackgroundSessionDelegate : NSUrlSessionDownloadDelegate
  {
    #region Computed Properties
    public ExtensionDelegate WatchExtensionDelegate { get; set; }

    public WKRefreshBackgroundTask Task { get; set; }
    #endregion

    #region Constructors
    public BackgroundSessionDelegate (ExtensionDelegate extensionDelegate, WKRefreshBackgroundTask task)
    {
      // Initialize
      this.WatchExtensionDelegate = extensionDelegate;
      this.Task = task;
    }
    #endregion

    #region Override Methods
    public override void DidFinishDownloading (NSUrlSession session, NSUrlSessionDownloadTask downloadTask, NSUrl location)
    {
      // Handle the downloaded data
      ...

      // Mark the task completed
      WatchExtensionDelegate.CompleteTask (Task);

    }
    #endregion
  }
}

Bei der Initialisierung behält sie sowohl das ExtensionDelegate Handle als auch das WKRefreshBackgroundTask spawnierte Handle bei. Sie setzt die DidFinishDownloading Methode außer Kraft, um den Download abzuschließen. Anschließend wird die CompleteTask Methode verwendet ExtensionDelegate , um den Vorgang darüber zu informieren, dass er abgeschlossen ist, und es aus der Sammlung ausstehender Vorgänge zu entfernen. Siehe "Behandeln von Hintergrundaufgaben oben".

Planen einer Momentaufnahmeaktualisierung

Der folgende Code kann verwendet werden, um eine Momentaufnahmeaufgabe so zu planen, dass die Benutzeroberfläche mit den neuesten Bewertungen aktualisiert wird:

private void ScheduleSnapshotUpdate ()
{
  // Create a fire date of now
  var fireDate = NSDate.FromTimeIntervalSinceNow (0);

  // Create user info dictionary
  var userInfo = new NSMutableDictionary ();
  userInfo.Add (new NSString ("lastActiveDate"), NSDate.FromTimeIntervalSinceNow (0));
  userInfo.Add (new NSString ("reason"), new NSString ("UpdateScore"));

  // Schedule for update
  WKExtension.SharedExtension.ScheduleSnapshotRefresh (fireDate, userInfo, (error) => {
    // Was the Task successfully scheduled?
    if (error == null) {
      // Yes, handle if needed
    } else {
      // No, report error
    }
  });
}

Genau wie ScheduleURLUpdateSession die oben beschriebene Methode erstellt sie ein neues NSDate Element, wenn die App wieder aufgenommen werden möchte, und erstellt einen, NSMutableDictionary der die Details der angeforderten Aufgabe enthält. Die ScheduleSnapshotRefresh Methode der SharedExtension Aufgabe wird verwendet, um die Planung des Vorgangs anzufordern.

Das System gibt einen NSError Wert zurück, wenn er den angeforderten Vorgang nicht planen konnte.

Behandeln einer Momentaufnahmeaktualisierung

Um die Momentaufnahmeaufgabe zu behandeln, wird die HandleBackgroundTasks Methode (siehe oben beschriebene Behandlung von Hintergrundaufgaben ) so geändert, dass sie wie folgt aussieht:

public override void HandleBackgroundTasks (NSSet<WKRefreshBackgroundTask> backgroundTasks)
{
  // Handle background request
  foreach (WKRefreshBackgroundTask task in backgroundTasks) {
    // Take action based on task type
    if (task is WKUrlSessionRefreshBackgroundTask) {
      var urlTask = task as WKUrlSessionRefreshBackgroundTask;

      // Create new configuration
      var configuration = NSUrlSessionConfiguration.CreateBackgroundSessionConfiguration (urlTask.SessionIdentifier);

      // Create new session
      var backgroundSession = NSUrlSession.FromConfiguration (configuration, new BackgroundSessionDelegate (this, task), null);

      // Keep track of all pending tasks
      PendingTasks.Add (task);
    } else if (task is WKSnapshotRefreshBackgroundTask) {
      var snapshotTask = task as WKSnapshotRefreshBackgroundTask;

      // Update UI
      ...

      // Create a expiration date 30 minutes into the future
      var expirationDate = NSDate.FromTimeIntervalSinceNow (30 * 60);

      // Create user info dictionary
      var userInfo = new NSMutableDictionary ();
      userInfo.Add (new NSString ("lastActiveDate"), NSDate.FromTimeIntervalSinceNow (0));
      userInfo.Add (new NSString ("reason"), new NSString ("UpdateScore"));

      // Mark task complete
      snapshotTask.SetTaskCompleted (false, expirationDate, userInfo);
    } else {
      // Ensure that all tasks are completed
      task.SetTaskCompleted ();
    }
  }
}

Die Methode testet auf den Typ des verarbeiteten Vorgangs. Wenn es sich um einen WKSnapshotRefreshBackgroundTask Zugriff auf die Aufgabe handelt:

var snapshotTask = task as WKSnapshotRefreshBackgroundTask;

Die Methode aktualisiert die Benutzeroberfläche und erstellt dann eine NSDate , um dem System mitzuteilen, wann die Momentaufnahme veraltet ist. Es erstellt eine NSMutableDictionary mit Benutzerinformationen, um die neue Momentaufnahme zu beschreiben und die Momentaufnahmeaufgabe mit diesen Informationen zu kennzeichnen:

// Mark task complete
snapshotTask.SetTaskCompleted (false, expirationDate, userInfo);

Darüber hinaus teilt sie der Momentaufnahmeaufgabe mit, dass die App nicht zum Standardstatus (im ersten Parameter) zurückkehrt. Apps, die kein Konzept eines Standardzustands haben, sollten diese Eigenschaft immer auf truefestlegen.

Effizientes Arbeiten

Wie im obigen Beispiel des fünfminütigen Fensters, das die MonkeySoccer-App zum Aktualisieren seiner Bewertungen benötigt hat, durch effizientes Arbeiten und Verwenden der neuen WatchOS 3-Hintergrundaufgaben war die App nur insgesamt 15 Sekunden aktiv:

Die App war nur für insgesamt 15 Sekunden aktiv.

Dies verringert die Auswirkungen, die die App sowohl auf die verfügbaren Apple Watch-Ressourcen als auch auf die Akkulaufzeit hat, und ermöglicht es der App, besser mit anderen Apps zu arbeiten, die auf der Uhr ausgeführt werden.

Funktionsweise der Terminplanung

Während sich eine WatchOS 3-App im Vordergrund befindet, ist sie immer für die Ausführung geplant und kann jede Art von Verarbeitung ausführen, die erforderlich ist, z. B. Aktualisieren von Daten oder Neuzeichnen der Benutzeroberfläche. Wenn die App in den Hintergrund wechselt, wird sie in der Regel vom System angehalten, und alle Laufzeitvorgänge werden angehalten.

Während sich die App im Hintergrund befindet, kann sie vom System verwendet werden, um schnell eine bestimmte Aufgabe auszuführen. Daher kann das System in WatchOS 2 eine Hintergrund-App vorübergehend reaktivieren, um Dinge wie das Behandeln einer langen Blickbenachrichtigung oder das Aktualisieren der Komplikation der App auszuführen. In watchOS 3 gibt es mehrere neue Möglichkeiten, wie eine App im Hintergrund ausgeführt werden kann.

Während sich eine App im Hintergrund befindet, erzwingt das System mehrere Grenzwerte:

  • Es wird nur ein paar Sekunden gegeben, um einen bestimmten Vorgang abzuschließen. Das System berücksichtigt nicht nur die Zeitspanne, die vergangen ist, sondern auch, wie viel CPU-Leistung die App verbraucht, um diesen Grenzwert abzuleiten.
  • Alle Apps, die ihre Grenzwerte überschreiten, werden mit den folgenden Fehlercodes getötet:
    • CPU - 0xc51bad01
    • Zeit - 0xc51bad02
  • Das System erzwingt unterschiedliche Grenzwerte basierend auf dem Typ der Hintergrundaufgabe, die von der App ausgeführt werden soll. Beispielsweise WKApplicationRefreshBackgroundTaskWKURLSessionRefreshBackgroundTask erhalten Aufgaben etwas längere Laufzeiten für andere Hintergrundaufgabentypen.

Komplikationen und App-Updates

Neben den neuen Hintergrundaufgaben, die Apple watchOS 3 hinzugefügt hat, kann sich die Komplikationen einer WatchOS-App darauf auswirken, wie und wann die App Hintergrundupdates empfängt.

Komplikationen sind kleine visuelle Elemente, die nützliche Informationen auf einen Blick bereitstellen. Je nach ausgewähltem Überwachungsgesicht kann der Benutzer ein Uhrgesicht mit einer oder mehreren Komplikationen anpassen, die von einer Watch-App in watchOS 3 bereitgestellt werden können.

Wenn der Benutzer eine der Komplikationen der App auf seine Uhrsicht einschließt, bietet er der App die folgenden aktualisierten Vorteile:

  • Das System bewirkt, dass die App im Zustand "Ready-to-launch" bleibt, wo sie versucht, die App im Hintergrund zu starten, sie im Arbeitsspeicher zu halten und zusätzliche Zeit zum Aktualisieren zu erhalten.
  • Komplikationen sind mindestens 50 Pushupdates pro Tag garantiert.

Der Entwickler sollte immer bestrebt sein, überzeugende Komplikationen für seine Apps zu erstellen, um den Benutzer dazu zu bringen, sie aus den oben aufgeführten Gründen zu ihrem Watch-Gesicht hinzuzufügen.

In watchOS 2 waren Komplikationen die primäre Methode, wie eine App laufzeit im Hintergrund empfangen hat. In watchOS 3 wird weiterhin sichergestellt, dass eine Komplikations-App mehrere Updates pro Stunde empfängt, sie kann jedoch verwenden WKExtensions , um mehr Laufzeit anzufordern, um ihre Komplikationen zu aktualisieren.

Sehen Sie sich den folgenden Code an, der zum Aktualisieren der Komplikation von der verbundenen i Telefon-App verwendet wird:

using System;
using WatchConnectivity;
using UIKit;
using Foundation;
using System.Collections.Generic;
using System.Linq;
...

private void UpdateComplication ()
{

  // Get session and the number of remaining transfers
  var session = WCSession.DefaultSession;
  var transfers = session.RemainingComplicationUserInfoTransfers;

  // Create user info dictionary
  var iconattrs = new Dictionary<NSString, NSObject>
    {
      {new NSString ("lastActiveDate"), NSDate.FromTimeIntervalSinceNow (0)},
      {new NSString ("reason"), new NSString ("UpdateScore")}
    };

  var userInfo = NSDictionary<NSString, NSObject>.FromObjectsAndKeys (iconattrs.Values.ToArray (), iconattrs.Keys.ToArray ());

  // Take action based on the number of transfers left
  if (transfers < 1) {
    // No transfers left, either attempt to send or inform
    // user of situation.
    ...
  } else if (transfers < 11) {
    // Running low on transfers, only send on important updates
    // else conserve for a significant change.
    ...
  } else {
    // Send data
    session.TransferCurrentComplicationUserInfo (userInfo);
  }
}

Die Eigenschaft der App verwendet die RemainingComplicationUserInfoTransfers Eigenschaft, WCSession um zu sehen, wie viele Übertragungen mit hoher Priorität die App für den Tag verlassen hat, und führt dann basierend auf dieser Zahl Aktionen aus. Wenn die App mit geringen Übertragungen beginnt, kann sie das Senden kleiner Updates anhalten und nur Informationen senden, wenn eine erhebliche Änderung erfolgt.

Planen und Andocken

In watchOS 3 hat Apple das Dock hinzugefügt, in dem Benutzer ihre bevorzugten Apps anheften und schnell darauf zugreifen können. Wenn der Benutzer die Randschaltfläche auf der Apple Watch drückt, wird ein Katalog mit angehefteten App-Momentaufnahme angezeigt. Der Benutzer kann nach links oder rechts wischen, um die gewünschte App zu finden, und tippen Sie dann auf die App, um sie zu starten, um die Momentaufnahme durch die Benutzeroberfläche der ausgeführten App zu ersetzen.

Das Dock

Das System verwendet in regelmäßigen Abständen Momentaufnahme der Benutzeroberfläche der App und verwendet diese Momentaufnahme, um die Dokumente aufzufüllen. watchOS bietet der App die Möglichkeit, den Inhalt und die Benutzeroberfläche zu aktualisieren, bevor diese Momentaufnahme übernommen wird.

Apps, die an das Dock angeheftet wurden, können folgendes erwarten:

  • Sie erhalten mindestens eine Aktualisierung pro Stunde. Dies umfasst sowohl eine App-Aktualisierungsaufgabe als auch eine Momentaufnahmeaufgabe.
  • Das Updatebudget wird zwischen allen Apps im Dock verteilt. Je weniger Apps der Benutzer angeheftet hat, desto mehr potenzielle Updates erhalten jede App.
  • Die App wird im Arbeitsspeicher gespeichert, sodass die App schnell fortgesetzt wird, wenn sie aus dem Dock ausgewählt wird.

Die letzte App, die der Benutzer ausgeführt hat, wird als die zuletzt verwendete App betrachtet und belegt den letzten Platz im Dock. Von dort aus kann der Benutzer auswählen, ob er dauerhaft an das Dock angeheften werden soll. Die zuletzt verwendete App wird wie jede andere bevorzugte App behandelt, die der Benutzer bereits an das Dock angeheftet hat.

Wichtig

Apps, die nur dem Startbildschirm hinzugefügt wurden, erhalten keine regelmäßige Planung. Um regelmäßige Planungs- und Hintergrundaktualisierungen zu erhalten, muss eine App zum Dock hinzugefügt werden.

Wie weiter oben in diesem Dokument erwähnt, sind Momentaufnahmen in watchOS 3 sehr wichtig, da sie sowohl als Vorschau als auch als Startbilder für die App funktionieren. Wenn sich der Benutzer in einer App im Dock absetzt, wird er auf den Vollbildmodus erweitert, in den Vordergrund eingegeben und gestartet, daher ist es zwingend erforderlich, dass die Momentaufnahme auf dem neuesten Stand ist.

Es kann vorkommen, dass das System entscheidet, dass es eine neue Momentaufnahme der Benutzeroberfläche der App benötigt. In diesem Fall zählt die Snapshot-Anforderung nicht mit dem Laufzeitbudget der App. Im Folgenden wird eine Systemmomentaufnahmeanforderung ausgelöst:

  • Eine Komplikation Zeitleiste Aktualisierung.
  • Benutzerinteraktion mit der Benachrichtigung einer App.
  • Wechseln vom Vordergrund zum Hintergrundzustand.
  • Nach einer Stunde im Hintergrundzustand, sodass die App zum Standardstatus zurückkehren kann.
  • Wenn watchOS zum ersten Mal startet.

Bewährte Methoden

Apple schlägt beim Arbeiten mit Hintergrundaufgaben die folgenden bewährten Methoden vor:

  • Planen Sie so oft, wie die App aktualisiert werden muss. Jedes Mal, wenn die App ausgeführt wird, sollte sie ihre zukünftigen Anforderungen neu bewerten und diesen Zeitplan nach Bedarf anpassen.
  • Wenn das System eine Hintergrundaktualisierungsaufgabe sendet und die App keine Aktualisierung erfordert, verzögern Sie die Arbeit, bis eine Aktualisierung tatsächlich erforderlich ist.
  • Berücksichtigen Sie alle Für eine App verfügbaren Laufzeitmöglichkeiten:
    • Dock- und Vordergrundaktivierung.
    • Benachrichtigungen.
    • Komplikationsupdates.
    • Hintergrund wird aktualisiert.
  • Verwendung für die allgemeine Hintergrundlaufzeit, z. B ScheduleBackgroundRefresh .:
    • Abrufen des Systems nach Informationen.
    • Planen Sie die Zukunft NSURLSessions , um Hintergrunddaten anzufordern.
    • Bekannte Zeitübergänge.
    • Auslösen von Komplikationsupdates.

Bewährte Methoden für Snapshot

Bei der Arbeit mit Snapshot-Updates macht Apple die folgenden Vorschläge:

  • Ungültige Momentaufnahmen nur, wenn erforderlich, z. B. wenn eine erhebliche Inhaltsänderung vorhanden ist.
  • Vermeiden Sie die Ungültigigkeit von Momentaufnahmen mit hoher Häufigkeit. Beispielsweise sollte eine Timer-App die Momentaufnahme nicht jede Sekunde aktualisieren, sie sollte nur ausgeführt werden, wenn der Timer beendet wurde.

App-Datenfluss

Apple schlägt Folgendes für die Arbeit mit dem Datenfluss vor:

App-Datenfluss diagramm

Ein externes Ereignis (z. B. Watch Verbinden ivity) aktiviert die App. Dadurch wird die App gezwungen, das Datenmodell (das den aktuellen Zustand der Apps darstellt) zu aktualisieren. Aufgrund der Änderung des Datenmodells muss die App ihre Komplikationen aktualisieren, eine neue Momentaufnahme anfordern, möglicherweise einen Hintergrund NSURLSession starten, um weitere Daten abzurufen und weitere Hintergrundaktualisierungen zu planen.

Der App-Lebenszyklus

Aufgrund des Docks und der Möglichkeit, Lieblings-Apps an sie anzuheften, glaubt Apple, dass Benutzer zwischen weit mehr Apps wechseln werden, viel häufiger, dann haben sie mit watchOS 2. Daher sollte die App bereit sein, diese Änderung zu behandeln und schnell zwischen Vordergrund- und Hintergrundzuständen zu wechseln.

Apple hat die folgenden Vorschläge:

  • Stellen Sie sicher, dass die App alle Hintergrundaufgaben bei der Eingabe der Vordergrundaktivierung so bald wie möglich beendet.
  • Stellen Sie sicher, dass alle Vordergrundarbeiten abgeschlossen werden, bevor Sie den Hintergrund durch Aufrufen NSProcessInfo.PerformExpiringActivitydes Hintergrunds eingeben.
  • Beim Testen einer App im WatchOS-Simulator werden keine Der Aufgabenbudgets erzwungen, sodass eine App so viel aktualisieren kann, wie sie erforderlich ist, um ein Feature ordnungsgemäß zu testen.
  • Testen Sie immer die echte Apple Watch-Hardware, um sicherzustellen, dass die App nicht über ihre Budgets läuft, bevor Sie in iTunes Verbinden veröffentlichen.
  • Apple schlägt vor, die Apple Watch beim Testen und Debuggen auf dem Ladegerät zu halten.
  • Stellen Sie sicher, dass sowohl der Kaltstart als auch die Fortsetzung einer App gründlich getestet werden.
  • Stellen Sie sicher, dass alle App-Aufgaben abgeschlossen werden.
  • Variieren Sie die Anzahl der Apps, die im Dock angeheftet sind, um sowohl die besten als auch die schlimmsten Szenarien zu testen.

Zusammenfassung

In diesem Artikel wurden die Verbesserungen behandelt, die Apple für watchOS gemacht hat und wie sie verwendet werden können, um eine Watch-App auf dem neuesten Stand zu halten. Zunächst wurden alle neuen Hintergrundaufgaben abgedeckt, die Apple in watchOS 3 hinzugefügt hat. Anschließend wurde der Hintergrund-API-Lebenszyklus behandelt und erläutert, wie Hintergrundaufgaben in einer Xamarin watchOS-App implementiert werden. Schließlich wurde erläutert, wie die Planung funktioniert und einige bewährte Methoden gegeben hat.