Widgets: come crearli per mostrare informazioni dalla nostra app

App Extensions sono state introdotte, durante il WWDC 2014 Keynote come un modo per estendere la portata della vostra applicazione ad alcune parti di iOS8, ad esempio con la creazione di un widget che verranno mostrati nel Centro notifiche, o di una azione di condivisione personalizzata. È senza dubbio una grande opportunità per gli sviluppatori iOS / Mac, quindi se avete un’idea per un widget / estensione, vi suggerisco di iniziare a lavorarci.

0_Extension_screenshot_w_280

Stiamo per costruire una semplice estensione “Oggi” (questo è il nome per il Centro notifiche) che mostra un numero che può essere impostato da app e le modifiche apportate in app si rifletteranno nel widget in tempo reale. Useremo NSUserDefaults condivise per raggiungere questo obiettivo.

0_App_screenshot_w_280

 

Prerequisiti

Avrete bisogno di Xcode 6 e, idealmente, un vero e proprio dispositivo iOS con iOS8.

Iniziamo

In Xcode 6, selezionare File> Nuovo> Progetto. Selezionare il modello Single View, e chiamiamolo TodayExtensionSharingDefaults. È possibile utilizzare Swift se ne hai voglia, ma andremo diretti con Objective-C per ora.

In Xcode, selezionare File> Nuovo> Target …. Poi, nel riquadro di sinistra, selezionare Application Extension dopodiché scegliere “Today Extension”. Poichè sarà un widget che comparirà unicamente nel centro notifiche, diamogli il nome NumberWidget.

Vi verrà chiesto se si desidera attivare lo schema “NumberWidget”. Fare clic su Annulla, dal momento che stiamo per eseguire il debug utilizzando lo schema di applicazione normale.

Adesso selezioniamo Main.storyboard. Aggiungere un campo di testo e un pulsante.

Effettuare le seguenti regolazioni del campo di testo:

  • Impostare la larghezza su 100
  • Impostare la sua origin.x a 110
  • Impostare il tipo di tastiera a Number Pad

Effettuare queste regolazioni per il pulsante:

  • Impostare l’etichetta in “Set number” o se preferite in italiano, Imposta Numero.
  • Posizionarlo sotto il campo di testo.

Alla fine dovrebbe essere simile a questo:

2_Application_UI

Quindi, passare alla Assistant Editor e creare le connessioni del controllo UITextField trascinando dal campo di testo per l’interfaccia. Chiamare l’outlet “textField”.

3_textField_connection

Ripetere lo stesso per il pulsante, ma questa volta creiamo l’azione Touch UP inside, e chiamiamola “setButtonPressed”.

4_Button_action

Impostare interfaccia utente del widget

La cosa grandiosa di Today Extensions è che sono costruiti utilizzando UIViewControllers, il che significa che è possibile utilizzare storyboard per costruire la sua interfaccia utente. Nel project navigation espandere il gruppo NumberWidget e fare clic su MainInterface.storyboard. Quindi eseguire le seguenti modifiche:

  • Selezionare lil file inspector e deselezionare ‘Usa Layout automatico’ (per semplicità di questo tutorial, non lo useremo).
  • Altezza a 50
  • Selezionare l’etichetta segnaposto con testo bianco nel mezzo della vista e modificare il testo in “number:” o “numero”; il suo colore al grigio chiaro in modo che possiamo vederlo e posizionarlo a sinistra
  • Aggiungere nuova label, modificare il suo testo e il suo colore in verde. Posizionare accanto alla label “Number:”.
  • Allo stesso modo del passaggio precedente, collegare la label al suo file di implementazione passando a Assistant Editor trascinando dalla label all’interfaccia. Chiamare l’outlet “numberLabel”
  • Rendere le etichette un po’ più grandi, o nel modo in cui ci piace

L’interfaccia dovrebbe essere simile a questa:

5_Widget_interface

Ora, è possibile eseguire il progetto per testare l’estensione. Quando l’applicazione viene avviata (sia sul dispositivo o nel simulatore), è sufficiente trascinare da sopra a mostrare il centro di notifica. In fondo, toccare e modificare il vostro NumberWidget dovrebbero essere elencati nella sezione “Non includere”. Se non lo è, prova a fare nuovamente un clean, e poi Build e run, dovrebbe esserci di sicuro.

6_NotificationCenter_Editing

 

È possibile toccare il pulsante più verde accanto ad esso per aggiungere e poi su Fine per tornare alla visualizzazione Today. Ma un attimo, la view dell’estensione ora ha un’altezza pari a zero! Non ti preoccupare, è perché abbiamo rimosso il layout automatico e non abbiamo ancora fissato la preferredContentSize. Lo faremo tra un minuto.

 

Attivare App groups per entrambi i target

Hai bisogno di farlo per essere in grado di condividere NSUserDefaults tra l’interno e l’esterno dell’applicazione. Il processo è molto semplice.

In Project Navigator, fare clic sull’icona del progetto TodayExtensionSharingDefaults, poi in alto a sinistra fare clic sulla freccia piccola per mostrare la lista di target, quindi fare clic su TodayExtensionSharingDefaultsTarget, passare alle Capabilities nel menu in alto, e scorrere verso il basso per i App groups. Questo potrebbe sembrare un po’ complicato, ma la schermata seguente dovrebbe chiarire:

7_App_groups_position_anotated

Ora, accendere l’interruttore App groups. Seleziona il team di sviluppo da utilizzare per il provisioning e fare clic su Scegli. Ciò aggiungerà il diritto “App Groups” per l’ID applicazione.A seconda che avete fatto queste cose prima o non, ci potrebbero essere alcuni altri gruppi elencati nei gruppi App. In entrambi i casi, fare clic su + per aggiungere nuova App di gruppo il nome App gruppo deve essere univoco quindi utilizzare group.yourcompany.TodayExtensionSharingDefaults nel resto di questo tutorial.

Se tutto è andato come dovrebbe, il nuovo gruppo applicazione dovrebbe essere lì, potete controllare.

Grande, ora siamo solo ad un passo dal traguardo! Scriviamo un po’ di codice.

Selezionare ViewController.m e aggiungere il seguente codice nel metodo -setButtonPressed:

[code lang=”obj-c”]
NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.yourcompany.TodayExtensionSharingDefaults"];

[sharedDefaults setInteger:[self.textField.text integerValue] forKey:@"MyNumberKey"];
[sharedDefaults synchronize]; // (!!) Questo è fondamentale
[/code]

Qui, abbiamo appena allocato / inizializzato nuovi NSUserDefaults con il nostro App Groups, e memorizzato il numero inserito all’interno del textField sotto la chiave MyNumberKey. Normalmente, si vorrebbe definire tali stringhe come costanti da qualche parte, ma per semplicità di questo tutorial le lascierò in questo modo. La chiamata di al metodo syncronize è fondamentale perché abbiamo bisogno di scrivere sul disco immediatamente, dal momento che la lettura avverrà velocemente.

Aprire TodayViewController.m e fare le seguenti modifiche:

Sostituire -initWithNibName con il seguente inizializzatore.

[code lang=”obj-c”]
– (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(userDefaultsDidChange:)
name:NSUserDefaultsDidChangeNotification
object:nil];
}
return self;
}
[/code]

Qui, stiamo aggiungendo un osservatore al NSUserDefaultsDidChangeNotification. Il NSNotificationCenter il metodo userDefaultsDidChange di default ogni volta che viene modificato.

In viewDidLoad, aggiungere queste due righe:

[code lang=”obj-c”]
self.preferredContentSize = CGSizeMake(320, 50);
[self updateNumberLabelText];
[/code]

I primi “segnali” verso il Centro notifiche: la dimensione desiderata per il widget, e il secondo aggiorna il numberLabel in base al valore corrente di @ “MyNumberKey” di default.

Successivamente, aggiungere questi due metodi alla fine del file (al di sopra della direttiva @end)

[code lang=”obj-c”]
– (void)userDefaultsDidChange:(NSNotification *)notification {
[self updateNumberLabelText];
}

– (void)updateNumberLabelText {
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.yourcompany.TodayExtensionSharingDefaults"];
NSInteger number = [defaults integerForKey:@"MyNumberKey"];
self.numberLabel.text = [NSString stringWithFormat:@"%d", number];
}[/code]

Qui, abbiamo semplicemente aggiornato il testo del numberLabel ogni volta che vengono modificate le impostazioni predefinite. Si noti che sarà pubblicato la notifica di modifica di default ogni volta che si cambia, quindi se avrete più aggiornamenti in contemporanea, potrebbe essere necessario trovare un modo più intelligente di come/quando effettuare l’aggiornamento dei valori.

Fatto!

Ora sei in grado di costruire e gestire il widget in modo da impostare un numero qualsiasi all’interno della app e poi vedere il cambiamento che si riflette nel tuo centro notifiche immediatamente dopo l’apertura.