Condividi tramite


Attività in background watchOS in Xamarin

Con watchOS 3, esistono tre modi principali in cui un'app watch può mantenere aggiornate le informazioni:

  • Uso di una delle diverse nuove attività in background.
  • Avere una delle sue complicazioni sul viso dell'orologio (dandogli più tempo per aggiornare).
  • Avere l'utente aggiunto all'app al nuovo Dock (dove viene mantenuto in memoria e aggiornato spesso).

Mantenere aggiornata un'app

Prima di discutere di tutti i modi in cui uno sviluppatore può mantenere aggiornati e aggiornati i dati di un'app watchOS e dell'interfaccia utente, questa sezione esaminerà un tipico set di modelli di utilizzo e come un utente potrebbe spostarsi tra i propri i Telefono e il proprio Apple Watch durante il giorno in base all'ora del giorno e all'attività attualmente in corso (ad esempio guida).

Ad esempio:

Come un utente potrebbe spostarsi tra i loro i Telefono e il loro Apple Watch durante tutto il giorno

  1. Al mattino, durante l'attesa in linea per un caffè, l'utente sfoglia le notizie correnti sul loro i Telefono per alcuni minuti.
  2. Prima di lasciare la caffetteria, controllano rapidamente il tempo con una complicazione sul viso dell'orologio.
  3. Prima di pranzo, usano l'app Mappe sull'i Telefono per trovare un ristorante nelle vicinanze e prenotare una prenotazione per incontrare un cliente.
  4. Mentre viaggiano al ristorante, ricevono una notifica sul loro Apple Watch e con una rapida occhiata, sanno che il loro appuntamento per il pranzo è in ritardo.
  5. La sera usano l'app Mappe sull'i Telefono per controllare il traffico prima di guidare a casa.
  6. Sulla strada di casa, ricevono una notifica iMessage sul loro Apple Watch chiedendo loro di raccogliere un po 'di latte e usano la funzionalità Risposta rapida per inviare la risposta "OK".

A causa della natura "rapida" (meno di tre secondi) di come un utente vuole usare un'app Apple Watch, in genere non c'è tempo sufficiente per l'app per recuperare le informazioni desiderate e aggiornarne l'interfaccia utente prima di visualizzarla all'utente.

Usando le nuove API apple incluse in watchOS 3, l'app può pianificare un aggiornamento in background e avere le informazioni desiderate pronte prima che l'utente lo richieda. Si prenda l'esempio della complicazione meteo illustrata in precedenza:

Un esempio di complicazione meteo

  1. L'app pianifica di essere svegliata dal sistema in un momento specifico.
  2. L'app recupera le informazioni necessarie per generare l'aggiornamento.
  3. L'app rigenera l'interfaccia utente per riflettere i nuovi dati.
  4. Quando l'utente visualizza la complicazione dell'app, contiene informazioni aggiornate senza che l'utente debba attendere l'aggiornamento.

Come illustrato in precedenza, il sistema watchOS riattiva l'app usando una o più attività, di cui dispone di un pool molto limitato:

Il sistema watchOS riattiva l'app usando una o più attività

Apple suggerisce di sfruttare al meglio questa attività (poiché è una risorsa così limitata per l'app) tenendola premuta fino a quando l'app non ha terminato il processo di aggiornamento stesso.

Il sistema recapita queste attività chiamando il nuovo HandleBackgroundTasks metodo del WKExtensionDelegate delegato. Ad esempio:

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
  }
}

Quando l'app ha completato l'attività specificata, la restituisce al sistema contrassegnandola completata:

L'attività torna al sistema contrassegnandola completata

Nuove attività in background

watchOS 3 introduce diverse attività in background che un'app può usare per aggiornare le informazioni in modo che disponga del contenuto necessario per l'utente prima di aprire l'app, ad esempio:

  • Aggiornamento dell'app in background: l'attività WKApplicationRefreshBackgroundTask consente all'app di aggiornarne lo stato in background. In genere questo includerà un'altra attività, ad esempio il download di nuovi contenuti da Internet tramite una sessione NSUrlSession.
  • Aggiornamento snapshot in background: l'attività WKSnapshotRefreshBackgroundTask consente all'app di aggiornare sia il contenuto che l'interfaccia utente prima che il sistema crei uno snapshot che verrà usato per popolare il Dock.
  • Background Watch Connessione ivity : l'attività WKWatch Connessione ivityRefreshBackgroundTask viene avviata per l'app quando riceve i dati in background dall'i Telefono associato.
  • Sessione URL in background: l'attività WKURLSessionRefreshBackgroundTask viene avviata per l'app quando un trasferimento in background richiede l'autorizzazione o viene completato (correttamente o in errore).

Queste attività verranno illustrate in dettaglio nelle sezioni seguenti.

WKApplicationRefreshBackgroundTask

è un'attività WKApplicationRefreshBackgroundTask generica che può essere pianificata in modo che l'app venga riattivata in una data futura:

Un woken WKApplicationRefreshBackgroundTask in una data futura

All'interno del runtime dell'attività, l'app può eseguire qualsiasi tipo di elaborazione locale, ad esempio aggiornare una sequenza temporale delle complicazioni o recuperare alcuni dati necessari con un oggetto NSUrlSession.

WKURLSessionRefreshBackgroundTask

Il sistema invierà un oggetto WKURLSessionRefreshBackgroundTask al termine del download dei dati e sarà pronto per l'elaborazione da parte dell'app:

WKURLSessionRefreshBackgroundTask al termine del download dei dati

Un'app non viene lasciata in esecuzione durante il download dei dati in background. L'app pianifica invece la richiesta di dati, quindi viene sospesa e il sistema gestisce il download dei dati, riattivando l'app solo al termine del download.

WKSnapshotRefreshBackgroundTask

In watchOS 3 Apple ha aggiunto il Dock in cui gli utenti possono aggiungere le app preferite e accedervi rapidamente. Quando l'utente preme il pulsante laterale in Apple Watch, verrà visualizzata una raccolta di snapshot dell'app aggiunti. L'utente può scorrere rapidamente verso sinistra o destra per trovare l'app desiderata, quindi toccare l'app per avviarla sostituendo snapshot con l'interfaccia dell'app in esecuzione.

Sostituzione dello snapshot con l'interfaccia delle app in esecuzione

Il sistema acquisisce periodicamente snapshot dell'interfaccia utente dell'app (inviando un WKSnapshotRefreshBackgroundTask) e usa tali snapshot per popolare il Dock. watchOS offre all'app la possibilità di aggiornare il contenuto e l'interfaccia utente prima che venga acquisito questo snapshot.

Gli snapshot sono molto importanti in watchOS 3 perché funzionano sia come anteprima che come immagini di avvio per l'app. Se l'utente si stabilirà su un'app nel Dock, si espanderà a schermo intero, immettere il primo piano e avviare l'esecuzione, quindi è imperativo che lo snapshot sia aggiornato:

Se l'utente si stabilisce su un'app nel Dock, si espanderà a schermo intero

Anche in questo caso, il sistema genererà un oggetto WKSnapshotRefreshBackgroundTask in modo che l'app possa prepararsi (aggiornando i dati e l'interfaccia utente) prima che venga acquisito lo snapshot:

L'app può prepararsi aggiornando i dati e l'interfaccia utente prima di creare lo snapshot

Al termine dell'app WKSnapshotRefreshBackgroundTask , il sistema creerà automaticamente uno snapshot dell'interfaccia utente dell'app.

Importante

È importante pianificare sempre un oggetto WKSnapshotRefreshBackgroundTask dopo che l'app ha ricevuto nuovi dati e aggiornato l'interfaccia utente o l'utente non visualizzerà le informazioni modificate.

Inoltre, quando l'utente riceve una notifica dall'app e lo tocca per portare l'app in primo piano, lo snapshot deve essere aggiornato perché funge anche da schermata di avvio:

L'utente riceve una notifica dall'app e lo tocca per portare l'app in primo piano

Se è trascorsa più di un'ora dall'interazione dell'utente con un'app watchOS, sarà possibile tornare allo stato predefinito. Lo stato predefinito può comportare aspetti diversi per app diverse e, in base alla progettazione di un'app, potrebbe non avere affatto uno stato predefinito.

WKWatch Connessione ivityRefreshBackgroundTask

In watchOS 3 Apple ha integrato la connettività watch con l'API di aggiornamento in background tramite il nuovo WKWatchConnectivityRefreshBackgroundTask. Usando questa nuova funzionalità, un'app i Telefono può distribuire dati aggiornati alla controparte dell'app watch, mentre l'app watchOS è in esecuzione in background:

Un'app i Telefono può distribuire dati aggiornati alla controparte dell'app watch, mentre l'app watchOS è in esecuzione in background

L'avvio di un push complicazione, il contesto dell'app, l'invio di un file o l'aggiornamento delle informazioni utente dall'app i Telefono riattiva l'app Apple Watch in background.

Quando l'app watch viene svegliata tramite , WKWatchConnectivityRefreshBackgroundTask sarà necessario usare i metodi API standard per ricevere i dati dall'app i Telefono.

Flusso di dati WKWatch Connessione ivityRefreshBackgroundTask

  1. Verificare che la sessione sia stata attivata.
  2. Monitorare la nuova HasContentPending proprietà purché il valore sia true, l'app dispone ancora di dati da elaborare. Come in precedenza, l'app deve mantenere l'attività fino al termine dell'elaborazione di tutti i dati.
  3. Quando non sono presenti altri dati da elaborare (HasContentPending = false), contrassegnare l'attività completata per restituirla al sistema. Se non si esegue questa operazione, il runtime in background assegnato dell'app comporterà un report di arresto anomalo.

Ciclo di vita dell'API in background

Inserendo insieme tutte le parti della nuova API Attività in background, un set tipico di interazioni sarà simile al seguente:

Ciclo di vita dell'API in background

  1. Prima di tutto, l'app watchOS pianifica un'attività in background da svegliare come un certo punto in futuro.
  2. L'app viene svegliata dal sistema e inviata un'attività.
  3. L'app elabora l'attività per completare qualsiasi operazione necessaria.
  4. In seguito all'elaborazione dell'attività, l'app potrebbe dover pianificare più attività in background per completare altre operazioni in futuro, ad esempio il download di altri contenuti usando un oggetto NSUrlSession.
  5. L'app contrassegna l'attività completata e la restituisce al sistema.

Uso responsabile delle risorse

È fondamentale che un'app watchOS si comporti in modo responsabile all'interno di questo ecosistema limitandone lo svuotamento sulle risorse condivise del sistema.

Esaminare lo scenario seguente:

Un'app watchOS limita il suo svuotamento sulle risorse condivise del sistema

  1. L'utente avvia un'app watchOS alle 13:00.
  2. L'app pianifica un'attività per riattivare e scaricare nuovi contenuti in un'ora alle 2:00.
  3. Alle 13:50 l'utente riapre l'app che consente di aggiornare i dati e l'interfaccia utente in questo momento.
  4. Invece di consentire all'attività di riattivare nuovamente l'app in 10 minuti, l'app deve riprogrammare l'attività per l'esecuzione un'ora dopo alle 2:50.

Anche se ogni app è diversa, Apple suggerisce di trovare modelli di utilizzo, come quelli illustrati in precedenza, per risparmiare risorse di sistema.

Implementazione di attività in background

Per esempio, questo documento userà l'app sportiva MonkeySoccer falsa che segnala i punteggi di calcio all'utente.

Esaminare lo scenario di utilizzo tipico seguente:

Scenario di utilizzo tipico

La squadra di calcio preferita dell'utente sta giocando una grande partita dalle 17:00 alle 9:00, quindi l'app dovrebbe aspettarsi che l'utente controlli regolarmente il punteggio e decida un intervallo di aggiornamento di 30 minuti.

  1. L'utente apre l'app e pianifica un'attività per l'aggiornamento in background 30 minuti dopo. L'API Background consente l'esecuzione di un solo tipo di attività in background in un determinato momento.
  2. L'app riceve l'attività e ne aggiorna i dati e l'interfaccia utente, quindi pianifica per un'altra attività in background 30 minuti dopo. È importante che lo sviluppatore ricordi di pianificare un'altra attività in background o che l'app non verrà mai riattivata per ottenere altri aggiornamenti.
  3. Anche in questo caso, l'app riceve l'attività e ne aggiorna i dati, aggiorna l'interfaccia utente e pianifica un'altra attività in background 30 minuti dopo.
  4. Lo stesso processo viene ripetuto di nuovo.
  5. L'ultima attività in background viene ricevuta e l'app aggiorna nuovamente i dati e l'interfaccia utente. Poiché questo è il punteggio finale non prevede un nuovo aggiornamento in background.

Pianificazione per l'aggiornamento in background

Dato lo scenario precedente, l'app MonkeySoccer può usare il codice seguente per pianificare un aggiornamento in background:

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

Crea nuovi NSDate 30 minuti in futuro quando l'app vuole essere svegliata e crea un oggetto NSMutableDictionary per contenere i dettagli dell'attività richiesta. Il ScheduleBackgroundRefresh metodo di SharedExtension viene utilizzato per richiedere la pianificazione dell'attività.

Il sistema restituirà un oggetto NSError se non è stato in grado di pianificare l'attività richiesta.

Elaborazione dell'aggiornamento

Esaminare quindi più in dettaglio la finestra di 5 minuti che mostra i passaggi necessari per aggiornare il punteggio:

Finestra di 5 minuti che mostra i passaggi necessari per aggiornare il punteggio

  1. Alle 17:30:02 l'app viene risvegliata dal sistema e data l'attività in background dell'aggiornamento. La prima priorità è ottenere i punteggi più recenti dal server. Vedere Pianificazione di una sessione NSUrlSession di seguito.
  2. Alle 7:30:05 l'app completa l'attività originale, il sistema attiva la sospensione dell'app e continua a scaricare i dati richiesti in background.
  3. Al termine del download, il sistema crea una nuova attività per riattivare l'app in modo che possa elaborare le informazioni scaricate. Vedere Gestione delle attività in background e gestione del download completato di seguito.
  4. L'app salva le informazioni aggiornate e contrassegna l'attività completata. Lo sviluppatore potrebbe essere tentato di aggiornare l'interfaccia utente dell'app in questo momento, tuttavia Apple suggerisce di pianificare un'attività snapshot per gestire tale processo. Vedere Pianificazione di un aggiornamento snapshot di seguito.
  5. L'app riceve l'attività Snapshot, ne aggiorna l'interfaccia utente e contrassegna l'attività completata. Vedere Gestione di un aggiornamento snapshot di seguito.

Pianificazione di una sessione NSUrlSession

Il codice seguente può essere usato per pianificare il download dei punteggi più recenti:

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

Configura e crea un nuovo NSUrlSessionoggetto , quindi usa tale sessione per creare una nuova attività di download usando il CreateDownloadTask metodo . Chiama il Resume metodo dell'attività di download per avviare la sessione.

Gestione delle attività in background

Eseguendo l'override del HandleBackgroundTasks metodo di WKExtensionDelegate, l'app può gestire le attività in background in ingresso:

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

    ...
  }
}

Il HandleBackgroundTasks metodo scorre tutte le attività inviate dal sistema (in backgroundTasks) alla ricerca di un oggetto WKUrlSessionRefreshBackgroundTask. Se ne viene trovato uno, si rielabora la sessione e si allega a NSUrlSessionDownloadDelegate per gestire il completamento del download (vedere Gestione del completamento del download di seguito):

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

Mantiene un handle sull'attività finché non viene completato aggiungendolo a una raccolta:

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

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

Tutte le attività inviate all'app devono essere completate, per qualsiasi attività non gestita, contrassegnarla come completata:

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

Gestione del completamento del download

L'app MonkeySoccer usa il delegato seguente NSUrlSessionDownloadDelegate per gestire il completamento del download ed elaborare i dati richiesti:

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
  }
}

Quando viene inizializzato, mantiene un handle per e ExtensionDelegate per l'oggetto WKRefreshBackgroundTask che lo ha generato. Esegue l'override del DidFinishDownloading metodo per gestire il completamento del download. Usa quindi il CompleteTask metodo di ExtensionDelegate per informare l'oggetto Task che è stato completato e rimuoverlo dalla raccolta di attività in sospeso. Vedere Gestione delle attività in background sopra.

Pianificazione di un aggiornamento snapshot

Il codice seguente può essere usato per pianificare un'attività snapshot per aggiornare l'interfaccia utente con i punteggi più recenti:

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

Proprio come ScheduleURLUpdateSession nel metodo precedente, crea un nuovo NSDate oggetto per quando l'app vuole essere svegliata e crea un oggetto NSMutableDictionary per contenere i dettagli dell'attività richiesta. Il ScheduleSnapshotRefresh metodo di SharedExtension viene utilizzato per richiedere la pianificazione dell'attività.

Il sistema restituirà un oggetto NSError se non è stato in grado di pianificare l'attività richiesta.

Gestione di un aggiornamento snapshot

Per gestire l'attività Snapshot, il HandleBackgroundTasks metodo (vedere Gestione delle attività in background precedente) viene modificato in modo che sia simile al seguente:

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

Il metodo verifica il tipo di attività da elaborare. Se si tratta di un WKSnapshotRefreshBackgroundTask oggetto, ottiene l'accesso all'attività:

var snapshotTask = task as WKSnapshotRefreshBackgroundTask;

Il metodo aggiorna l'interfaccia utente e quindi crea un oggetto NSDate per indicare al sistema quando lo snapshot non sarà aggiornato. Crea un NSMutableDictionary oggetto con informazioni utente per descrivere il nuovo snapshot e contrassegna l'attività snapshot completata con queste informazioni:

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

Inoltre, indica all'attività snapshot che l'app non torna allo stato predefinito (nel primo parametro). Le app che non hanno alcun concetto di stato predefinito devono sempre impostare questa proprietà su true.

Lavorare in modo efficiente

Come illustrato nell'esempio precedente della finestra di cinque minuti che l'app MonkeySoccer ha impiegato per aggiornare i punteggi, lavorando in modo efficiente e usando la nuova attività in background watchOS 3, l'app era attiva solo per un totale di 15 secondi:

L'app era attiva solo per un totale di 15 secondi

In questo modo si riduce l'impatto che l'app avrà sulle risorse di Apple Watch disponibili e sulla durata della batteria e consente anche all'app di funzionare meglio con altre app in esecuzione sull'orologio.

Funzionamento della pianificazione

Mentre un'app watchOS 3 è in primo piano, è sempre pianificata per l'esecuzione e può eseguire qualsiasi tipo di elaborazione necessaria, ad esempio aggiornare i dati o ridisegnare l'interfaccia utente. Quando l'app si sposta in background, viene in genere sospesa dal sistema e tutte le operazioni di runtime vengono interrotte.

Anche se l'app è in background, può essere destinata al sistema per eseguire rapidamente un'attività specifica. Quindi, in watchOS 2, il sistema potrebbe riattivare temporaneamente un'app in background per eseguire operazioni come la gestione di una notifica di aspetto lungo o l'aggiornamento della complicazione dell'app. In watchOS 3 esistono diversi nuovi modi in cui un'app può essere eseguita in background.

Mentre un'app è in background, il sistema impone diversi limiti:

  • Per completare un'attività specifica, vengono forniti solo alcuni secondi. Il sistema prende in considerazione non solo la quantità di tempo trascorso, ma anche la quantità di potenza della CPU che l'app sta consumando per derivare questo limite.
  • Qualsiasi app che supera i limiti verrà terminata con i codici di errore seguenti:
    • CPU - 0xc51bad01
    • Ora - 0xc51bad02
  • Il sistema impone limiti diversi in base al tipo di attività in background che ha chiesto all'app di eseguire. Ad esempio, WKApplicationRefreshBackgroundTask e WKURLSessionRefreshBackgroundTask Alle attività vengono assegnati runtime leggermente più lunghi rispetto ad altri tipi di attività in background.

Complicazioni e Aggiornamenti delle app

Oltre alle nuove attività in background aggiunte da Apple per watchOS 3, le complicazioni di un'app watchOS possono influire su come e quando l'app riceve gli aggiornamenti in background.

Le complicazioni sono piccoli elementi visivi che forniscono informazioni utili a colpo d'occhio. A seconda del viso dell'orologio selezionato, l'utente ha la possibilità di personalizzare un viso dell'orologio con una o più complicazioni che possono essere fornite da un'app watchOS 3.

Se l'utente include una delle complicazioni dell'app sul viso dell'orologio, offre all'app i vantaggi aggiornati seguenti:

  • Fa in modo che il sistema mantenga l'app in uno stato pronto per l'avvio, in cui tenta di avviare l'app in background, lo mantiene in memoria e dà tempo aggiuntivo per l'aggiornamento.
  • Le complicazioni sono garantite almeno 50 aggiornamenti push al giorno.

Lo sviluppatore deve sempre cercare di creare complicazioni accattivanti per le proprie app per invogliare l'utente ad aggiungerli al viso dell'orologio per i motivi elencati in precedenza.

In watchOS 2, le complicazioni erano il modo principale in cui un'app ha ricevuto il runtime mentre è in background. In watchOS 3, tuttavia, un'app Complicazione verrà comunque assicurata di ricevere più aggiornamenti all'ora, ma può usare WKExtensions per richiedere più runtime per aggiornare le complicazioni.

Esaminare il codice seguente usato per aggiornare La complicazione dall'app i Telefono connessa:

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

Usa la RemainingComplicationUserInfoTransfers proprietà di WCSession per vedere il numero di trasferimenti con priorità alta che l'app ha lasciato per il giorno e quindi esegue un'azione in base a tale numero. Se l'app inizia a essere ridotta sui trasferimenti, può tenere premuto l'invio di aggiornamenti secondari e inviare informazioni solo quando si verifica una modifica significativa.

Pianificazione e dock

In watchOS 3 Apple ha aggiunto il Dock in cui gli utenti possono aggiungere le app preferite e accedervi rapidamente. Quando l'utente preme il pulsante laterale in Apple Watch, verrà visualizzata una raccolta di snapshot dell'app aggiunti. L'utente può scorrere rapidamente verso sinistra o destra per trovare l'app desiderata, quindi toccare l'app per avviarla sostituendo lo snapshot con l'interfaccia dell'app in esecuzione.

The Dock

Il sistema acquisisce periodicamente snapshot dell'interfaccia utente dell'app e usa tali snapshot per popolare la documentazione. watchOS offre all'app la possibilità di aggiornare il contenuto e l'interfaccia utente prima di creare questo snapshot.

Le app aggiunte al dock possono prevedere quanto segue:

  • Riceveranno almeno un aggiornamento all'ora. Sono incluse sia un'attività di aggiornamento app che un'attività snapshot.
  • Il budget di aggiornamento viene distribuito tra tutte le app nel Dock. Quindi il minor numero di app aggiunte dall'utente, maggiore sarà il numero di aggiornamenti potenziali che ogni app riceverà.
  • L'app verrà mantenuta in memoria in modo che l'app riprenderà rapidamente quando selezionata dal Dock.

L'ultima app eseguita dall'utente verrà considerata l'app usata più di recente e occupa l'ultimo slot nel Dock. Da qui, l'utente può scegliere di aggiungerlo in modo permanente al Dock. L'oggetto Usato più di recente verrà considerato come qualsiasi altra app preferita che l'utente ha già aggiunto al Dock.

Importante

Le app aggiunte solo alla schermata iniziale non riceveranno alcuna pianificazione regolare. Per ricevere aggiornamenti regolari di pianificazione e in background, è necessario aggiungere un'app al Dock.

Come indicato in precedenza in questo documento, gli snapshot sono molto importanti in watchOS 3 perché funzionano sia come immagini di anteprima che di avvio per l'app. Se l'utente si stabilirà su un'app nel Dock, si espanderà a schermo intero, immettere il primo piano e avviare l'esecuzione, quindi è imperativo che lo snapshot sia aggiornato.

In alcuni casi il sistema decide che è necessario un nuovo snapshot dell'interfaccia utente dell'app. In queste situazioni, la richiesta snapshot non verrà conteggiato rispetto al budget di runtime dell'app. Di seguito verrà attivata una richiesta snapshot di sistema:

  • Aggiornamento della sequenza temporale delle complicazioni.
  • Interazione dell'utente con la notifica di un'app.
  • Passaggio dallo stato Primo piano allo stato Sfondo.
  • Dopo un'ora di stato In background, l'app può tornare allo stato predefinito.
  • Quando watchOS viene avviato per la prima volta.

Consigli per iniziare

Apple suggerisce le procedure consigliate seguenti quando si lavora con le attività in background:

  • Pianificare la frequenza con cui l'app deve essere aggiornata. Ogni volta che l'app viene eseguita, deve rivalutare le proprie esigenze future e regolare questa pianificazione in base alle esigenze.
  • Se il sistema invia un'attività di aggiornamento in background e l'app non richiede un aggiornamento, rinviare il lavoro fino a quando non è effettivamente necessario un aggiornamento.
  • Prendere in considerazione tutte le opportunità di runtime disponibili per un'app:
    • Ancorare e attivazione in primo piano.
    • Notifiche.
    • Aggiornamenti delle complicazioni.
    • Aggiornamenti in background.
  • Usare ScheduleBackgroundRefresh per il runtime in background per utilizzo generico, ad esempio:
    • Polling del sistema per informazioni.
    • Pianificare in futuro NSURLSessions la richiesta di dati in background.
    • Transizioni temporali note.
    • Attivazione degli aggiornamenti delle complicazioni.

Procedure consigliate per gli snapshot

Quando si utilizzano gli aggiornamenti snapshot, Apple invia i suggerimenti seguenti:

  • Invalidare gli snapshot solo quando necessario, ad esempio, quando si verifica una modifica significativa del contenuto.
  • Evitare l'invalidazione snapshot ad alta frequenza. Ad esempio, un'app timer non deve aggiornare lo snapshot ogni secondo, deve essere eseguita solo al termine del timer.

App Flusso di dati

Apple suggerisce quanto segue per l'uso del flusso di dati:

Diagramma Flusso di dati app

Un evento esterno(ad esempio Watch Connessione ivity) riattiva l'app. In questo modo l'app deve aggiornare il modello di dati (che rappresenta lo stato corrente delle app). In seguito alla modifica del modello di dati, l'app dovrà aggiornare le complicazioni, richiedere un nuovo snapshot, possibilmente avviare uno sfondo NSURLSession per eseguire il pull di più dati e pianificare ulteriori aggiornamenti in background.

Ciclo di vita dell'app

A causa del Dock e della possibilità di aggiungere app preferite, Apple pensa che gli utenti si spostino tra molte più app, molto più spesso, poi hanno fatto con watchOS 2. Di conseguenza, l'app deve essere pronta per gestire questa modifica e spostarsi rapidamente tra gli stati in primo piano e in background.

Apple offre i suggerimenti seguenti:

  • Assicurarsi che l'app finisca tutte le attività in background il prima possibile quando si immette l'attivazione in primo piano.
  • Assicurarsi di completare tutte le operazioni in primo piano prima di entrare in background chiamando NSProcessInfo.PerformExpiringActivity.
  • Quando si testa un'app nel simulatore watchOS, nessuno dei budget delle attività verrà applicato in modo che un'app possa aggiornare quanto necessario per testare correttamente una funzionalità.
  • Testare sempre l'hardware di Apple Watch reale per assicurarsi che l'app non sia in esecuzione oltre i budget prima della pubblicazione in iTunes Connessione.
  • Apple suggerisce di mantenere Apple Watch sul caricabatterie durante i test e il debug.
  • Assicurarsi che sia l'avvio a freddo che la ripresa di un'app siano testati accuratamente.
  • Verificare che tutte le attività dell'app siano state completate.
  • Variare il numero di app aggiunte nel Dock per testare sia gli scenari migliori che peggiori.

Riepilogo

Questo articolo ha illustrato i miglioramenti apportati da Apple per watchOS e come possono essere usati per mantenere aggiornata un'app watch. In primo luogo, ha trattato tutto il nuovo Background Task Apple aggiunto in watchOS 3. Ha quindi illustrato il ciclo di vita dell'API in background e come implementare le attività in background in un'app Xamarin watchOS. Infine, ha illustrato il funzionamento della pianificazione e ha fornito alcune procedure consigliate.