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:
- Am Morgen, während er auf einen Kaffee wartet, durchsucht der Benutzer die aktuellen Nachrichten auf dem i Telefon mehrere Minuten.
- Bevor sie den Café verlassen, überprüfen sie schnell das Wetter mit einer Komplikation auf ihrem Watch-Gesicht.
- 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.
- 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.
- Am Abend verwenden sie die Karten-App auf dem i Telefon, um den Verkehr vor dem Heimfahren zu überprüfen.
- 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:
- Die App plant, das System zu einem bestimmten Zeitpunkt aufzuwachen.
- Die App ruft die Informationen ab, die zum Generieren des Updates erforderlich sind.
- Die App generiert die Benutzeroberfläche neu, um die neuen Daten widerzuspiegeln.
- 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:
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:
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:
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 NSUrlSession
abrufen.
WKURLSessionRefreshBackgroundTask
Das System sendet einen WKURLSessionRefreshBackgroundTask
Zeitpunkt, an dem die Daten heruntergeladen und bereit sind, von der App verarbeitet zu werden:
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.
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:
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:
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:
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 WKWatchConnectivityRefreshBackgroundTask
Neue ü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:
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.
- Stellen Sie sicher, dass die Sitzung aktiviert wurde.
- Überwachen Sie die neue
HasContentPending
Eigenschaft, solange der Wert isttrue
, 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. - 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:
- Zunächst plant die watchOS-App eine Hintergrundaufgabe so, dass sie in Zukunft wieder eingewoben wird.
- Die App wird vom System weckt und eine Aufgabe gesendet.
- Die App verarbeitet die Aufgabe, um alle erforderlichen Aufgaben auszuführen.
- 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
. - 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:
- Der Benutzer startet eine watchOS-App um 1:00 Uhr.
- Die App plant eine Aufgabe, um neue Inhalte in einer Stunde um 2:00 Uhr aufzuwachen und herunterzuladen.
- Um 1:50 Uhr öffnet der Benutzer die App erneut, sodass sie seine Daten und Ui zu diesem Zeitpunkt aktualisieren kann.
- 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:
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.
- 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.
- 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.
- 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.
- Derselbe Vorgang wiederholt sich erneut.
- 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:
- 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.
- 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.
- 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.
- 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.
- 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 NSUrlSession
Und 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 WKExtensionDelegate
App 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 true
festlegen.
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:
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
WKApplicationRefreshBackgroundTask
WKURLSessionRefreshBackgroundTask
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 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:
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.PerformExpiringActivity
des 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.