Compatibile con Xcode 8

Come creare una applicazione per Apple Watch con il linguaggio Swift

ENTRA NEL NOSTRO GRUPPO FACEBOOK

I numeri dicono sempre la verità. Apple ha venduto più di 12 milioni di Apple Watch in tutto il 2015 conquistandosi la nomina a leader del mercato globale dei wearable device.

E se sono poche le cose dovrebbero interessare uno sviluppatore, se escludiamo donne o uomini, quello che rimane in cima alla nostra lista è solamente una cosa: guadagnare con un’applicazione.

Non fraintendermi, se stai tramutando lo sviluppo di un’applicazione, in un mero interesse economico stai andando completamente fuori strada. Creare un’applicazione è un’arte che difficilmente può essere appagata dal guadagno. Ma, ovviamente, di sole idee e arte, non si vive.

Ciò non toglie il fatto che, con l’ormai affermarsi di nuove tecnologie in casa Apple, come watchOS e tvOS, ti si parano di fronte due nuove strade da percorrere:

  1. Lasciarti sfuggire quest’opportunità.
  2. Oppure iniziare a sviluppare applicazioni per Apple Watch.

Per lo sviluppo posso darti una mano io, mentre per la prima, rifletteteci bene perché nel giro di qualche anno, lo store sarà già troppo maturo e la competizione, per essere annoverati tra i big, maggiore.

Quindi, non perdiamoci in chiacchere, con questa guida voglio insegnarti come creare una applicazione per Apple Watch con il linguaggio Swift. Ti trasmetterò tutti i concetti di base e fondamentali che ti permetteranno di sviluppare app per watchOS in piena autonomia.

Imparerai a creare app per Apple Watch sviluppando una semplice applicazione per la gestione di una lista della spesa. Progetto già affrontato in altri tutorial e che ti permetterà di studiare i primi componenti di un progetto watchOS.

Dato che difficilmente un nuovo sviluppatore comincia con la creazione di un’app per watchOS, il tutorial è pensato per chi già sa creare applicazioni per iOS e per chi già conosce il linguaggio Swift. Se non sei tra questi, comincia adesso seguendo i miei corsi!

Pronto per imparare a creare app per Apple Watch? Allora cominciamo!

Applicazioni Native e WatchKit

Una delle prime caratteristica da tenere presente è che è possibile creare 2 generazioni di applicazioni per Apple Watch:

  1. Le applicazioni native per Apple Watch. Queste sono l’equivalente delle app che sviluppi per iPhone e iPad. In un progetto di questo tipo, l’applicazione risiede fisicamente nel tuo dispositivo da polso.
  2. La WatchKit app. Le app sviluppate con WatchKit nascono come estensione di un’applicazione per iPhone. In questo caso avrai un progetto di un’app classica per iOS diviso in due. Una parte è l’app classica per iOS ed un’altra quella per watchOS. Il WatchKit è un framework, come potrebbe essere l’UIKit o il CoreData per iOS, ti mette a disposizione delle classi per la progettazione dell’app per watchOS.

In realtà entrambe le versioni nascono come progetto iOS in simbiosi con un progetto WatchKit. La natività di un’applicazione watchOS è data dall’utilizzo del sistema operativo watchOS 2.0, infatti, grazie a questo le tue applicazioni risiederanno interamente sul dispositivo da polso anche se create utilizzando il sistema WatchKit.

Fatta questa piccola premessa, è logico pensare come l’applicazione che svilupperai, dato che sarà un gestore di una lista della spesa di una probabile app creata per iPhone, sarà sviluppata di pari passo all’app iOS quindi nella modalità WatchKit app.

Per capire il funzionamento di un’app WatchKit, immagina d’aver già sviluppato l’applicazione per iPhone per la gestione della tua lista e quindi di aver già creato la struttura dati per la conservazione di tutte le informazioni. Avrebbe senso ricreare una nuova struttura, da infilare nel watch, con gli stessi dati presenti su iPhone? La risposta è ovviamente no.

Un’app WatchKit puoi immaginarla, nella realtà è effettivamente così, come composta da 2 parti:

  1. Il primo pezzo, risiede sull’iPhone (o sul watch se la versione del sistema è la 2.0) ed è dove inserirai la logica dell’app WatchKit. Per logica intendo, il codice relativo all’aggiornamento della user interface del watch e la gestione degli eventi generati dalle interazione tra utente e orologio. Nel caso dell’app che creerai, la logica sarà composta dalla lista e dal codice per la gestione delle InterfaceController.
  2. L’altra parte è l’interfaccia utente. Lo storyboard, ad esempio, lo troverai all’interno di quest’area.

Le informazioni e la gestione degli eventi, dato che i due dispositivi non sono fisicamente collegati tra loro, passano attraverso wifi/bluetooth. Soprattutto quest’ultimo punto non deve assolutamente passare inosservato perché un sovraccarico d’informazioni causerà il rallentamento del watch e quindi una visualizzazione differita tra ciò che vorresti fosse visualizzato e ciò che realmente verrà osservato dall’utente.

In pratica, quando l’utilizzatore clicca su un bottone dell’applicazione, per esempio per l’aggiornamento della tabella, quello che succede è che l’evento generato dalla WatchKit app viene spedito, tramite wifi/bluetooth, all’iPhone. Una volta che il segnale arriva alla WatchKit Extension, quest’ultimo ne elabora il contenuto e lo rimanda indietro alla watch app, aggiornando così l’interfaccia con i nuovi dati acquisiti.

Setup del progetto

Apri Xcode e create un nuovo progetto da File\New\Project…, seleziona il template iOS App with WatchKit dalla lista watchOS\Application e premi su Next.

Setting progetto WatchKit app

Dai un nome all’applicazione, ad esempio: ListaSpesa, assicurati di aver selezionato il linguaggio Swift, deseleziona tutti i checkbox che trovi in fondo e clicca su Next. Scegli il Path in cui salvare il progetto e premi su Create.

Dai un’occhiata al Project Navigator sulla tua destra.

Anatomia di un progetto WatchKit con linguaggio swift

L’architettura di un’applicazione WatchKit è più evidente considerando cosa c’è effettivamente dentro ogni gruppo (sarebbe meglio dire Target). Lista Spesa WatchKit App, ad esempio, non contiene nessun tipo di source file ma solamente lo storyboard e gli assets per la creazione dell’interfaccia utente. Dall’altra parte, Lista Spesa WatchKit Extension contiene due file, InterfaceController.swift e ExtensionDelegate.swift, ma non lo storyboard.

Ora tutto ha più senso? alla WatchKit Extension è affidato il compito di gestire il comportamento della WatchKit App mentre quest’ultima deve amministrarne solamente l’interfaccia.

Build & Run

Accanto al bottone di Run del programma, nel riquadro dove visualizzi gli schemi, seleziona lo schema NomeProgetto WatchKit App.

Run di una watchOS app

Premendo il bottone Run (il triangolo in alto a sinistra), o Command-R, Xcode inizia il building della iOS App, dell’Extension, della WatchKit app. Successivamente installa tutte e 3 le parti all’interno dell’iOS Simulator e infine lo apre.

Se per caso il tuo iOS Simulator non dovesse mostrare l’Apple Watch, non ti allarmare, devi semplicemente attivarne la visualizzazione. Vai sul simulator e nella barra degli strumenti in alto, selezionate Hardware\External Displays\Apple Watch- 38 mm. Adesso dovresti vedere uno schermo nero raffigurante l’Apple Watch.

Costruire l’interfaccia di un watchOS app

Dallo sviluppo di applicazione iOS sai che le interfacce si costruiscono utilizzando lo storyboard, l’Auto Layout, Le Size Class e, da iOS 9, anche le Stack View.

Questo è parzialmente vero anche per la realizzazione di app per watchOS dove, nello specifico, le interfacce vengono realizzate utilizzando solamente lo storyboard ma non le tecniche di auto layout. Quest’ultime infatti risultano assenti per via delle dimensioni ridotte dello schermo, 38 mm e 42 mm, che essendo così piccole non godrebbero delle stesse proprietà dei dispositivi iOS.

Torna su Xcode. Dal project navigator apri il file Interface.storyboard che si trova nella cartella NomeProgetto WatchKit App.

Divisione Interface View watchOS app

Nell’interfaccia di un’applicazione per watchOS, differentemente da quanto avviene per un’applicazione iOS, non puoi dislocare gli elementi grafici a tuo piacimento.

La View di un’Interface Controller, è diviso in 3 aree verticali: TOP, CENTER e BOTTOM. Ogni nuovo elemento verrà sempre inserito a partire dalla top area tranne quando già saranno presenti elementi grafici, infatti in quest’ultimo caso, il nuovo oggetto, verrà impilato sotto quelli già esistenti.

Oltre al posizionamento verticale esiste l’equivalente orizzontale. In orizzontale, un oggetto, può essere schierato in altrettante 3 aree: LEFT, CENTER e RIGHT.

In concreto, puoi considerare la View come ad una scacchiera di dimensioni 3×3, ogni casella rappresenta un’area identificata dalle combinazioni possibili tra la componente verticale con quella orizzontale (left-top, center-top, right-top ecc).

Aggiungere un elemento

Lavoriamo per esempi pratici.

Dall’Object Library, cerca l’oggetto Label e trascinalo all’interno dell’Interface Controller. Adesso selezionalo, spostati nell’Attributes Inspector (il 3 bottone a partire da sinistra nel menu sopra l’Object Library) e, scorrendo un po’ il menu verso il basso, dovresti vedere la sezione Position composta da 2 attributi: Horizontal e Vertical. Modificando questi valori puoi riposizionare l’oggetto a tuo piacimento in una delle 9 caselle della scacchiera.

Ad esempio, mettendo horizontal: center e vertical: center, la label, verrà spostata immediatamente al centro del dispositivo:

Aggiungere un elemento all'interfaccia di un'app watchOS
Cosa succede quando aggiungete una nuova label?

Come previsto la nuova label viene inserita nell’angolo superiore sinistro perché di default, la componente orizzontale e verticale, è definita con quei parametri di default.

Adesso prova a posizionare la nuov label in posizione centrale, sia in orizzontale che verticale. Hai notato cos’è successo? entrambe le label sono entrate in conflitto per occupare la posizione centrale del dispositivo e, a discapito di quanto si potrebbe pensare, non vengono posizionate una accanto all’altra bensì, l’ultima label inserita, viene accatastata sotto la prima label.

Neanche provando a cambiare il parametro orizzontale di entrambe le label, mettendo la prima spostata verso left e la seconda verso right, i due oggetti si troveranno a condividere lo stesso spazio orizzontale. Come risolvere questo problema lo vedrete tra un po’.

Size di un elemento

Elimina le label che hai inserito e aggiungi un Button.

Button per watchOS app

Ti siete accorti che, anche se l’oggetto ha posizione left-top, occupa tutto lo spazio superiore dell’interfaccia?

Oltre ai vincoli di posizione, un altro fattore che influisce sull’interfaccia di un’applicazione è la dimensione o Size dell’oggetto.

Sotto al campo Position, nell’Attributes Inspector, c’è il campo Size che permette la modifica dell’estensione dell’oggetto in questione. I valori di larghezza (Width) e altezza (Height) vengono influenzati da 3 possibili proprietà:

  1. Relative to Container: imposta le dimensioni uguali a quelle del Container (per container si intende l’intera finestra dell’interfaccia).
  2. Size To Fit Content: ridimensiona l’oggetto in modo da racchiudere solamente ciò che contiene. Ad esempio il bottone, come qualsiasi altro elemento, sarà uguale alle dimensioni del testo contenuto al suo interno.
  3. Fixed: setta le dimensioni dell’oggetto in maniera statica, ovvero in base ad un valore numerico. Può essere modificato anche selezionando e trascinando uno degli angoli o bordi dell’oggetto selezionato.

Le prime due opzioni, relative e size to fit, sono proprietà dinamiche, infatti sono in grado di adattarsi in base al cambiamento delle dimensioni sia del dispositivo. Ti ricordo che esistono due versione di Apple Watch con dimensioni dello schermo differenti. Il mio consiglio è quello di utilizzare sempre una di queste due opzioni onde evitar di dover riadattare la grafica dell’applicazione a runtime.

Il parametro larghezza, nel bottone che hai inserito, è settato uguale a quella del container, mentre la dimensione in verticale è relativa all’altezza del testo contenuto. Se provi a modificare la larghezza in: Size To Fit Content il bottone si ridimensionerà occupando solo lo spazio occupato dalla parola “button”. Adesso con un doppio click sul bottone rinominalo utilizzando una parola più lunga e, con le impostazioni che gli hai assegnato, dovrebbe allargarsi in base alla larghezza del testo contenuto.

Proprietà Size di un elemento grafico di app watchOS WatchKit swift

Mettere insieme più elementi con i Group

L’ultima nozione basilare che ti serve per comporre un’interfaccia è quella della dislocazione di più oggetti sullo stesso livello. Da quanto fin ora spiegato sai che un oggetto, qualsiasi sia il suo tipo di collocazione, non può essere posizionato accanto ad un altro. Il motivo risiede nella quantità di informazioni che effettivamente possono stare su una riga.

L’Apple Watch ha uno schermo di dimensioni veramente ridicole se paragonate a quelle di un’iPhone e, per questo motivo, Apple da per scontato che non verranno inserite grandi quantità di informazioni visive che indurrebbero l’utente a dover avvicinare il viso all’orologio.

Però c’è un modo per poter ovviare al presunto problema e la risposta è nell’oggetto Group. Elimina tutto ciò che hai all’interno dell’Interface Controller e trascina, sempre dall’Object Library, un oggetto Group all’interno dell’interfaccia.

L’oggetto Group crea un container posizionabile in una delle 9 caselle dell’Interface Controller. Un Group crea una nuova sotto griglia 3×3 dove posizionare gli oggetti grafici.

Group e dislocazione di più elementi nello stesso quadrante watchOS

Dato che di default un group è trasparente, per capire cosa voglio dire, selezionate il group e dall’Attributes Inspector cambia il colore di background (l’attributo Color per l’esattezza) in uno a tua scelta. Adesso se provi ad inserire due label, una accanto all’altra, all’interno del group noterai come esse vengano visualizzate effettivamente una accanto all’altra.

Cambiando la position di una delle due label in horizontal: right e vertical: top, dovresti vederle sempre sulla stessa linea ma diametralmente opposte rispetto all’asse centrale.

Sei riuscito a mettere una label sotto una presente nel group? don’t worry! oltre alla dislocazione orizzontale, esiste quella verticale e per attivarla vi basta cambiare, sempre dall’Attributes Inspector e dopo aver selezionato il group, la voce Layout da Horizontal a Vertical.

Interfaccia del progetto

Una regola generale per la costruzione di una qualsiasi applicazione è quella di partire dalla realizzazione dell’interfaccia utente.

L’interfaccia dell’applicazione che state realizzando è composta da 3 Interface Controller, la prima sarà una schermata di benvenuto con il numero di oggett da compare, la seconda mostrerà la lista della spesa e l’ultima verrà utilizzata per visualizzare i dettagli dell’appuntamento selezionato dalla seconda interfaccia.

Il primo passaggio da fare è quello di eliminare qualsiasi cosa tu abbia inserito nel primo Interface Controller. Successivamente aggiungi una Label e posizionatela in top-center, fai doppio click su di essa e cambia il testo in “Ciao”. Aggiungi un Group e ubicalo in center-center. All’interno del gruppo inserisci 2 Label. Colloca la prima label in left-center e, facendo doppio click su di essa, cambiate il testo in “0”. Questa label la utilizzerai per mostrare il numero di appuntamenti in programma.

La seconda label posizionatela, sempre all’interno del group, in right-center e cambiale il testo in “da comprare”. Inserisci un Button e posizionalo in center-bottom, rinominalo in “Vedi Lista” e se preferisci cambia il Color di background.

Interfaccia app WatchKit 1 Dall’Object Library prendi un oggetto Interface Controller e riponilo accanto a quello appena creato. Al suo interno trascina un oggetto Table.

Selezionate la Cell, cambia il Color di sfondo in uno a tua scelta e, se vuoi maggiormente stilizzarla, modificate la voce Radius per arrotondare i bordi del rettangolo che la descrive. All’interno della cella trascinate una Label e sistematela in center-center. In questa label verrà mostrato il nome della persona da incontrare.

Interfaccia app WatchKit 2

Non c’è bisogno di aggiungere nient’altro perché la tabella funziona alla stessa maniera, o quasi, di quelle utilizzate per iOS. Il funzionamento verrà ripreso durante l’implementazione del codice.

Se stai cercando un tutorial in cui ampliare le tue conoscenze sulle tabelle del WatchKit, questo è il tutorial che fa per te.

Allo stesso modo aggiungi, accanto all’ultimo inserito, un nuovo Interface Controller. Inserite una Label in top-center e rinominatela in “nome”. Sotto la seguente label, posizionane una nuova in center-top, cambia l’attributo Lines in 3 (in modo da far entrare tutto il testo) e modifica la Size larghezza in Relative to Container.

Infine dovresti avere il seguente layout:

Schermata 2016-05-02 alle 12.31.11

I 3 avvisi mostrati da Xcode verranno corretti successivamente.

InterfaceController e Life Cycle

Un oggetto di tipo InterfaceController è un’istanza della classe WKInterfaceController o più precisamente di una sua subclass. La WKInterfaceController è contenuta all’interno del framework WatchKit.

Da watchOS 2.0 in sù questa classe gira localmente sul dispositivo da polso. Mentre, nella versione watchOS 1.0 la classe risiede sull’iPhone e, di conseguenza, l’app doveva essere obbligatoriamente utilizzata in connessione con l’app iOS.

Nel Project Navigator di Xcode, vai alla cartella NomeProgetto WatchKit Extension e apri il file InterfaceController.swift. La classe che troverai all’interno è il controller, creato di default da Xcode, per la gestione della prima interfaccia presente nello storyboard.

 

  • awakeWithContext(context:), chiamato dopo il costruttore init, inizializza l’InterfaceController con i dati passati dal context. Il context può essere opzionale in quanto rappresenta le informazione passata da un controller precedente. Dato che è il primo metodo ad essere invocato, l’awakeWithContext(context:) viene utilizzato per tutte quelle operazioni preparatorie alla visualizzazione dell’interfaccia all’utente. Ad esempio, l’inizializzazione delle informazioni contenute nelle label, tabelle, immagini ecc viene eseguita all’interno del seguente metodo. Nel caso dell’ultima InterfaceController, modificherete l’awakeWithContext(context:) per cambiare il testo contenuto dalle label con le informazioni passate dal context.
  • willActivate() viene chiamato non appena l’awake ha finito il suo ciclo d’esecuzione e quindi qualche istante prima che l’interfaccia verrà presentata all’utente. Dato che l’esecuzione avviene nel lasso di tempo in cui l’interfaccia viene renderizzata, è sconsigliato eseguire, all’interno di questo metodo, operazioni di inizializzazione dispendiose le quali potrebbero bloccare il watch. Questo non vuol dire: “non dovete mettere metodi di aggiornamento dell’interfaccia”, bensì vanno inserite esclusivamente le operazioni di brevissima durata, come ad esempio il cambio del testo in una label o l’aggiornamento di una tabella con pochi dati.
  • didDeactivate(), viene chiamato quando l’interface controller di riferimento non è più visualizzato o quando l’iPhone passa allo stato di Lock. Un controller in questo stato può essere deallocato in qualsiasi momento e per questo motivo, all’interno del metodo didDeactivate(), potete inserire delle operazioni di cleanup del progetto come lo stop di timer o il salvataggio di alcune informazioni. Non utilizzate questo metodo per la modifica dell’interfaccia, infatti quando esso viene chiamato l’interfaccia non è più visualizzata dal watch e quindi ogni modifica inserita ne risulterebbe superflua.

Quando l’applicazione WatchKit viene lanciata in esecuzione, il primo metodo che viene chiamato dal sistema, dopo il caricamento della struttura dell’interfaccia dallo storyboard, è il metodo init e successivamente l’awakeWithContext(context:). Quest’ultimo provvede ad inizializzare la user interface dandogli i valori e le informazioni principali (in questo momento l’interfaccia è in caricamento e non è ancora visualizzata sul watch).

Una volta eseguiti i metodi di inizializzazione viene immediatamente visualizzata l’interfaccia dell’applicazione con precedente chiamata al metodo willActivate().

A questo punto l’applicazione è pronta per essere utilizzata: ad esempio, un click su un bottone invierà un segnala alla rispettiva action la quale rimanderà indietro all’Apple Watch il segnale elaborato o l’operazione da eseguire; mentre nell’ipotesi in cui venisse eseguito un push verso un altro controller, il nuovo controller verrebbe istanziato eseguendo un nuovo ciclo di vita indipendente dal controller precedente (ripartendo dall’awakeWithContext(context:)).

Qualora l’utente ritornasse indietro, dato che il controller di partenza era stato già istanziato, verrebbe eseguita solo la willActivate() sempre qualche istante prima della visualizzazione dell’interfaccia. Quando l’utente interromperà l’applicazione o l’iPhone passerà in lock, verrà lanciata la didDeactivate() che provvederà, se il programmatore l’ha previsto, ad interrompere alcuni task o a salvare i dati modificati.

condividi xcoding

Ho impiegato un po’ di tempo a scrivere questo tutorial. Sarei davvero felice se contribuissi al mio progetto semplicemente mettendo un mi piace o follow alle mie pagine.

[addtoany]

Grazie davvero :-)

Controller, Outlet e Segue

Dopo aver creato l’interfaccia, il secondo passaggio da fare è quello relativo al collegamento degli oggetti interattivi dell’applicazione, o soggetti a cambiamento, con il rispettivo codice di controllo.

Il primo passaggio da fare è creare 2 classi di riferimento per le interface controller dell’applicazione non ancora associate ad una custom class.

All’interno del group, NomeProgetto WatchKit Extesion, devi aggiungere 2 nuovi file, quindi clicca con il tasto destro sul nome del gruppo e seleziona New File. Dal menu WatchOS\Source scegli WatchKit Class e premi Next. Cambiate la subclass of in WKInterfaceController, rinomina la classe in TableInterfaceController e seleziona Swift come linguaggio. Nella finestra di selezione della cartella in cui salvare il file, assicurati che, nel riquadro in basso, sia selezionato il target: NomeProgetto WatchKit Extension.

Esegui le stesse operazioni per creare un nuovo file di tipo WKInterfaceController. A quest’ultimo dai il nome di DetailInterfaceController.

new source file watchkit Adesso torna allo storyboard e seleziona l’interface controller composto dalla tabella. Dal menu Utilities passa alla voce Identity Inspector e nel campo Class inserisci il nome della classe creata in precedenza: TableInterfaceController. Premi invio.

La stessa identica operazione eseguila per l’ultima interfaccia assicurandoti di inserire, nel campo Class, la DetailInterfaceController:

Associare una classe ad Interface Controller

Sempre dallo storyboard, seleziona il primo interface controller e apri l’Assistant Editor. Seleziona la label con il testo “0”, premi CTRL+Click Sinistro, o solamente Click Destro e trascina, tenendo premuto i tasti, la freccia verso l’interno della classe InterfaceController.

Nel box per la creazione della IBOutlet, inserisci come Name: label_numeroElementi. Alla label_numeroElementi verrà cambiato il testo in base al numero di oggetti ancora da comprare.

Dato che gli altri elementi dell’interfaccia sono statici, a parte il bottone che ora visualizzi, non c’è bisogno di creare una outlet per la loro gestione. Il bottone serve esclusivamente per passare dalla InterfaceController alla TableInterfaceController.

Il sistema di passaggio tra controller è simile a quello utilizzo su iOS e anche qui prende il nome di segue. Selezionate il bottone, tenendo premuti gli stessi comandi utilizzati per le outlet, trascina, all’interno dello storyboard, la freccia verso la TableInterfaceController. Scegli come Action Segue: Push. Se tutto è andato per il verso giusto, dovresti vedere una freccia che collega l’InterfaceController alla TableInterfaceController.

Outlet e Segue WatchKit

Cell Identifier tabella

La TableInterfaceController ha al suo interno una tabella che essendo composta da custom cell, perché hai inserito una label all’interno della cella, deve essere gestita da una classe apposita. All’interno del file TableInterfaceController.swift, sotto l’intero corpo della classe TableInterfaceController, create una nuova classe chiamata TableRowController come subclass della NSObject:

 

 

Torna allo storyboard e clicca sulla TableInterfaceController. Onde evitare errori, dal Document Outline, selezionate la Table e premendo sempre i bottoni per i collegamenti, trascinate la freccia verso l’interno della classe TableInterfaceController e rinomina l’outlet in table_listaSpesa.

Sempre dall’outline selezionate la Table Row Controller e dal menu Identity Inspector cambia la classe di riferimento in TableRowController.

Ancora per la Table Row Controller, passa al menu Attributes Inspector e cambiate l’Identifier in TableRowController. In questo modo il controller che gestisce le row della tabella è impostato per funzionare secondo le specifiche che inserirai nella classe TableRowController.

TableRowController e identifier cell

Seleziona la label che hai inserito all’interno della cella della tabella e trascinate la freccia verso l’interno della classe TableRowController. Rinomina l’outlet in label_nomeAlimento.

L’ultimo passaggio, per questo controller, è quello relativo al segue che collega il tocco su una row della tabella, al controller dei dettagli dell’appuntamento. Dallo storyboard seleziona la tabella e crea un segue di tipo push con la DetailInterfaceController.

Per il DetailInterfaceController, create le outlet delle due label presenti. La prima chiamatela label_nomeAlimento, servirà per mostrare il nome dell’alimento da acquistare, e la seconda label_dettagliAlimento, mostrerà dei dettagli dell’alimento.

label cella e altri identifier

L’implementazione del codice

Per prima cosa, all’interno del NomeProgetto WatchKit Extension, create un nuovo file di tipo Swift File chiamato Alimento. Al suo interno inserisci il seguente codice:

 

La classe Alimento è composta, come si evince dall’interfaccia, da soli due attributi: nome e dettagli. L’attributo “nome” verrà utilizzato per identificare l’alimento da acquistare mentre l’attributo “dettagli” indicherà qualche sorta di promemoria. Il costruttore init inizializza l’oggetto con le stringhe passate come parametro.

Apri il file InterfaceController.swift e all’interno della classe, crea una lista, chiamata listaSpesa, contenente alcune istanze della classe Alimento:

 

Ora che hai la struttura dati, puoi aggiornare il testo della label_numeroElementi. Dove aggiorniamo il valore della label? Nell’awakeWithContext(context:) o nel willActivate()?

Se il valore che state per aggiornare è di tipo statico e non è soggetto a cambiamenti nel tempo, la risposta è il metodo awakeWithContext(context:). Se invece l’informazione è soggetta a mutamenti, come nel caso del numero di alimenti, allora è lecito utilizzare la willActivate().

Per modificare il testo della label, all’interno del metodo willActivate(), aggiungi il seguente codice:

Il metodo che la classe WKInterfaceLabel ti mette a disposizione, per la manipolazione del testo della label, si chiama setText.

Avviando l’applicazione, la label_numeroElementi, dovrebbe mostrare il numero 3.

L’ultimo passaggio da fare, per completare la InterfaceController, è quello di modificare il segue in modo da passare la lista alla TableInterfaceController che ne provvederà a visualizzarne il contenuto nella tabella. Sotto uno dei metodi della classe InterfaceController, aggiungi il seguente codice:

Il segue, come per la programmazione iOS, ha un Identifier che lo marca nel caso in cui fossero presenti più segue che partano dalla stessa interfaccia. Nel nostro caso il segue che esce dall’InterfaceController è solo uno e per tanto non ha motivo di essere targato tramite Identifier.

Se ti ricordi, nell’awakeWithContext(context:), il context è l’oggetto che viene passato durante gli spostamenti tra le interfacce e che quindi identifica l’informazione che un controller passa all’altro.

La contextForSegueWithIdentifier(segueIdentifier:) crea l’oggetto context dal quale, il controller destinatario, leggerà i dati. In questo modo, quando verrà premuto il bottone per spostarsi alla TableInterfaceController, il context, letto dal metodo awakeWithContext(context:), sarà un array di oggetti Alimento. Il fatto che la funzione contextForSegueWithIdentifier(segueIdentifier:) ritorna un AnyObject opzionale ti da la possibilità di spedire qualsiasi tipo d’informazione.

La tabella

Spostati nel TableInterfaceController.swift e sotto l’IBOutlet crea una lista di oggetti Alimento dove poter inserire le informazioni che il context passerà:

Nel metodo awakeWithContext(context:) eseguite un casting del context al tipo Appuntamento e infine passatelo alla variabile appuntamenti:

Una volta che la lista appuntamenti è stata riempita, con i valori passati dal context, devi provvedere a mostrarla nella tabella. Per inserire i dati all’interno della tabella è necessario:

  1. creare una funzione che setti il numero di righe della tabella uguale a quello del numero di elementi della lista.
  2. istanziare le varie custom cell con il contenuto dell’array.

All’interno della classe TableInterfaceController, aggiungi il codice:

 

La setNumberOfRow(withRowType:) imposta sia il numero di righe, che il tipo di controller che utilizzerà la riga per mostrare il suo contenuto. Il withRowType fa riferimento all’Identifier impostato alla TableRowController. Una volta stabilito il numero di righe, il ciclo, dopo aver recuperato la row all’indice index (uguale al numero identificativo generato dall’enumerazione dell’array – self.listaSpesa!.enumerate()), cambia il testo della labe_cell mettendolo uguale al nome dell’appuntamento iterato. La funzione adesso è pronta per essere chiamata all’interno della willActivate():

Prova per credere! Avvia l’applicazione e spostati, premendo il bottone, alla TableInterfaceController.

run app watchOS

Per concludere con la TableInterfaceController devi preparare il context per l’invio dell’informazione alla DetailInterfaceController. Il metodo in questione è leggermente diverso rispetto a quello visto in precedenza, infatti è creato appositamente per generare un context al tocco di un elemento in una riga della tabella. Il codice è il seguente:

Anche in questo caso non eseguiamo nessun controllo sull’Identifier del segue e semplicemente prendendo la rowIndex, passata come parametro al tocco della riga, recuperiamo l’appuntamento relativo a quell’indice e lo ritorniamo al context.

Nella DetailInterfaceController, all’interno dell’awakeWithContext(context:), esegui il casting in Alimento e, dato che le informazioni sono statiche, cambia direttamente il testo delle due label:

Conclusione

A questo punto l’applicazione di base è conclusa! adesso nella vostra cassetta degli attrezzi avete i primi strumenti per la realizzazione delle applicazioni per Apple Watch utilizzando il framework WatchKit.

Da questo tutorial, puoi passare ai seguenti:

Buona Programmazione!

Start typing and press Enter to search

Il database Realtime di Firebase con il linguaggio Swift