Durante il\u00a0WWDC del 2019 <\/a>Apple<\/strong> ha presentato la sua versione di un linguaggio di sviluppo app<\/a> dichiarativo sulla falsa riga di React. Ovviamente basato su Swift<\/a> e con la principale caratteristica di essere veloce, fluido e sopratutto utilizzabile su tutte le sue piattaforme. Lo stesso codice scritto in SwiftUI<\/strong><\/a>\u00a0pu\u00f2 essere utilizzato quindi su iOS, iPadOS, WatchOS e MacOS.<\/p>\n SwiftUI<\/strong> nasce per la costruzione di interfacce utente in maniera semplice, veloce e soprattuto uniforme tra tutte le diverse piattaforme Apple. Lo stesso componente infatti verr\u00e0 renderizzato e si comporter\u00e0 automaticamente nella maniera pi\u00f9 appropriata a seconda del dispositivo dove viene utilizzato. Questo permetter\u00e0 a chi lavora nello sviluppo app di preoccuparsi meno dei diversi aspetti di ciascuna piattaforma (ovviamente alcune distinzioni andranno sempre fatte, ci sono cose che si possono fare su MacOS mentre su WatchOS no ad esempio) e focalizzarsi maggiormente sulle funzionalit\u00e0 delle proprie applicazioni.<\/p>\n SwiftUI<\/strong>\u00a0si basa su due principi fondamentali: una sintassi dichiarativa e un nuovo sistema per l\u2019aggiornamento delle informazioni che dovranno aggiornare l\u2019interfaccia.\u00a0<\/span><\/p>\n Differentemente da quanto accade normalmente in UIKit<\/a>, invece di raccogliere gli eventi e decidere come modificare l\u2019interfaccia utente con una sintassi dichiarativa, \u00e8 necessario descrivere a priori che cosa dovr\u00e0 fare l\u2019interfaccia e come dovr\u00e0 comportarsi. Al variare dei dati l\u2019interfaccia semplicemente si aggiorner\u00e0 per riflettere tali cambiamenti. Come scritto in uno dei primi esempi forniti da Apple, sar\u00e0 possibile scrivere che volete visualizzare una lista di elementi formata da una label per il titolo e una per il sottotitolo, descrivere la font, l\u2019allineamento e il colore per ciascun componente.\u00a0<\/span><\/p>\n Queste informazioni rappresentano la descrizione di ciascuna View, che verr\u00e0 renderizzata e rinfrescata automaticamente da\u00a0SwiftUI<\/strong>\u00a0al variare delle condizioni di stato definite. Lo stato infatti \u00e8 il cuore centrale di una View, quello che Apple definisce Source of Truth (fonte della verit\u00e0), ciascuna View deve avere almeno un oggetto che funga da Source of Truth e che ne scateni gli aggiornamenti automatici (a meno di non voler disegnare una view completamente statica che \u00e8 una casistica plausibile). Ad esempio uno Switch (chiamato Toggle in\u00a0SwitftUI<\/strong>) varier\u00e0 automaticamente il suo stato \u201cgrafico\u201d da On a Off al variare di una variabile booleana a cui \u00e8 agganciato e viceversa, quindi modificare a codice la stato della variabile porter\u00e0 SwiftUI a ridisegnare la view per aggiornare lo switch mentre l\u2019utente che manualmente effettua un tap sul componente aggiorner\u00e0 il valore della variabile a cui \u00e8 agganciato.<\/p>\n Questo ci porta al secondo principio su cui si basa\u00a0SwiftUI<\/strong>, Combine un nuovo framework, introdotto sempre durante il WWDC del 2019, che come\u00a0SwiftUI<\/strong> si prefigge di descrivere in modo dichiarativo come i valori vengano modificati nel corso del tempo. Scopo di questo articolo non \u00e8 approfondire i concetti dietro Combine, che pu\u00f2 essere usato anche con il buon vecchio UIKit, anche perch\u00e9 fortunatamente Apple ha gi\u00e0 reso compatibile con Combine numerosi framework di base.<\/p>\n Dopo questa lunga introduzione credo che\u00a0il modo migliore per capire come funzioni SwiftUI<\/strong> sia lavorare insieme allo sviluppo app di\u00a0una semplice applicazione e provare a capire come si costruiscono e si possa interagire con le view<\/strong>. Ed essendo programmatori ho pensato di lavorare sullo sviluppo app che ci permetta di visualizzare e scegliere il nostro carburante preferito, il caff\u00e8. Essendo io un amante del caff\u00e8 di Starbucks ho pensato di raccogliere le informazioni presenti su alcuni dei loro prodotti, presenti sul sito ufficiale, e creare una piccola App che mi permetta di visualizzare i caff\u00e8 e scegliere i miei preferiti. Per l\u2019occasione ho preparato una lista in json di alcuni esempi di caff\u00e8 e le relative immagini da associare.<\/p>\n Scaricate il file zip con gli asset e siamo pronti a partire:\u00a0DevelopersFuel Materiale\u00a0<\/a><\/strong><\/p>\n Iniziate aprendo Xcode, create un nuovo progetto e selezionate Single View App.\u00a0<\/span><\/p>\n Nella schermata successiva come product name scrivete DeveloperFuel facendo attenzione a scegliere SwiftUI<\/strong> come User Interface. Rimuovete dalle spunte Use core data, Include Unit Tests e Include UI Tests.<\/p>\n Se \u00e8 la prima volta che provate ad usare un template per SwiftUI<\/strong> noterete che l\u2019interfaccia \u00e8 notevolmente diversa dai progetti UIKit a cui siete abituati. Infatti la parte sinistra di Xcode \u00e8 riempita da una vasta porzione che mostra in tempo reale un preview della vostra applicazione, e quando dico in tempo reale intendo che man mano che scriverete il codice l\u2019interfaccia del preview si aggiorner\u00e0 e, viceversa, aggiungendo componenti al preview il codice viene aggiornato di conseguenza.\u00a0<\/span><\/p>\n A questo punto aprite lo zip con il materiale che avete precedentemente scaricato<\/strong>, troverete una cartella Images che contiene le immagini da visualizzare dei nostri preziosi caff\u00e8. Trascinate tutte le immagini all\u2019interno dell\u2019Asset Catalog di default.\u00a0<\/span><\/p>\n All\u2019interno della cartella Model troverete 3 files: BundleJsonHelper.swift, Coffee.swift e coffees.json, aggiungete anche questi tre files al progetto Xcode e siamo pronti per iniziare. Si tratta di un file json che contiene il nostro modello dati iniziale, la definizione della classe Coffee e un helper per semplificare il caricamento del file json all\u2019interno del modello dati.\u00a0<\/span><\/p>\n Aprite il file Coffee.swift e date un occhiata a come sar\u00e0 strutturato il nostro modello: ci sono 2 oggetti CoffeeType e Coffee, il primo raggrupper\u00e0 un certo numero di caff\u00e8. Per ogni caff\u00e8 sono definite alcune propriet\u00e0 come nome, descrizione, foto e ingredienti. Prestate particolarmente attenzione alle ultime righe del file, viene creata un istanza statica chiamata CoffeeExample di un oggetto Coffee, questo risulter\u00e0 fondamentale durante la costruzione delle nostre view.<\/p>\n SwiftUI<\/strong> nasce intorno all\u2019idea della composizione e riusabilit\u00e0 delle singole View, invece di descrivere un\u2019interfaccia complessa nella sua interezza \u00e8 preferibile (e sopratutto molto pi\u00f9 leggibile) scomporla in tanti piccoli blocchi atomici da comporre a nostro piacimento ed eventualmente riutilizzare in altre parti dell\u2019App. La nostra App dovr\u00e0 per prima cosa presentare una lista di diversi tipi di caff\u00e8 (altrimenti cosa mi sono messo a copiare in file json tutte quelle informazioni dal sito di Starbucks?!?), e per fare questo per prima cosa abbiamo bisogno di rappresentare un singolo elemento di questa lista, che per semplicit\u00e0 chiameremo CoffeeRow.<\/p>\n Create un nuovo file da aggiungere al progetto, e dalla sezione User Interface selezionate SwiftUI<\/strong> View. Chiamate il file CoffeeRow e proseguite:<\/p>\n La prima di cui abbiamo bisogno \u00e8 una propriet\u00e0 che contenga i dati da visualizzare, aggiungete quindi subito dopo la definizione della struct:<\/p>\n Immediatamente il compilatore si arrabbier\u00e0 indicando che manca il parametro coffee all\u2019interno del preview. Del preview? Si esatto, perch\u00e8 i preview in tempo reale che vedete sulla sx non sono altro che strutture particolari di SwiftUI<\/strong> che vengono compilate e renderizzate mentre modificate il codice. In alcuni casi, quando le modifiche sono troppo sostanziose per essere calcolate durante la scrittura del codice, il preview viene messo in pausa automaticamente, una volta terminate le modifiche \u00e8 possibile farlo ripartire premendo il pulsante resume in alto a sinistra oppure option+command+p sulla tastiera.<\/p>\n Risolviamo subito il problema modificando la riga di errore da CoffeeRow() in CoffeeRow(coffee: Coffee.coffeExample). Questa \u00e8 l\u2019istanza statica che avete notato nel modello dati precedentemente. Non appena modificata la dichiarazione l\u2019errore scomparir\u00e0 e il preview si aggiorner\u00e0 mostrando il confortante Hello World!, se questo non dovesse succedere avviate a mano il resume del preview.<\/p>\n Una view con il testo hello world per\u00f2 non \u00e8 la pi\u00f9 utile delle view, iniziamo quindi a mostrare alcuni dettagli che possono essere utili ai nostri utenti (o noi stessi) quando visualizziamo una lista di caff\u00e8 tra cui scegliere.<\/p>\n Il componente principale di ciascuna View in SwiftUI<\/strong> \u00e8 la variabile body, che deve necessariamente ritornare un oggetto di tipo View. Questa \u00e8 quella che rappresenter\u00e0 la nostra interfaccia utente a runtime. \u00c9 importante notare che deve ritornare un singolo oggetto View, quindi non \u00e8 possibile ad esempio inserire un secondo oggetto Text() sotto a quello presente, perch\u00e8 appunto sarebbero 2 view.\u00a0<\/span><\/p>\n Ricordate il concetto di composizione di cui abbiamo parlato prima? Gli oggetti possono essere per\u00f2 contenuti in altri oggetti, e per questo abbiamo dei contenitori che ci permettono di raggruppare i nostri elementi di interfaccia\u2026 gli Stack!<\/p>\n Iniziamo creando uno stack verticale, racchiudendo il nostro testo in esso:<\/p>\n Non un grande cambiamento per adesso ma questo \u00e8 solo il primo passo. Adesso \u00e8 giunto il momento di visualizzare qualcosa di vero, sostituiamo quindi il contenuto di Text con Text(coffee.name). Immediatamente nel preview la scritta Hello World! verr\u00e0 sostituita con Caff\u00e8 Mocha, proprio il nome del caffe che abbiamo inizializzato durante la creazione del nostro preview.<\/p>\n Si inizia gi\u00e0 ad intravedere le potenzialit\u00e0 di SwiftUI<\/strong> ma ancora la nostra interfaccia non \u00e8 ne carina ne esaustiva. Proviamo ad aggiungere la descrizione sotto il nome, aggiungiamo quindi un\u2019altra Text sotto quella gi\u00e0 presente e stavolta mostriamo la descrizione.\u00a0<\/span><\/p>\n A questo punto la nostra preview dovrebbe essersi aggiornata con il titolo e la descrizione del caffe, perfettamente centrate una sotto l\u2019altra\u2026 centrate? Avete mai visto una lista con titolo e sotto titolo centrate? Questo perch\u00e8 di default un VStack ha un allineamento centrato, ma ovviamente \u00e8 possibile modificare questa impostazione molto semplicemente.<\/p>\n Per farlo vi mostrer\u00f2 un\u2019altro modo di interazione con l\u2019interfaccia di Xcode, tenendo premuto option cliccate su VStack nell\u2019editor e dal menu contestuale selezionate Show SwiftUI Inspector:<\/p>\nSviluppo app in SwiftUI: iniziamo!<\/h2>\n
<\/a><\/p>\n
<\/a><\/p>\n
<\/a><\/p>\n
<\/a><\/p>\nvar coffee: Coffee<\/pre>\n
VStack {\n Text(\u201cHello World\u201d)\n}<\/pre>\nvar<\/b> body: some<\/b> View {\n VStack {\n Text(coffee.name)\n Text(coffee.description)\n \u00a0 <\/span>}\n }<\/pre>\n