La mia esperienza con NativeScript e Angular (Ionic vs NativeScript)

Aggiornamento maggio 2020: Nativescript rimuoverà il supporto la funzionalità di “Cloud Build” fornite con SideKick (che era una delle poche cose positive che avevo riscontrato), con una nuovo sistema Circle Ci come annunciato qui, dismettendo il precedente dal 31.05.2020, in pratica senza preannuncio e possibilità di scelta.
A questo punto confermo la mia opinione: un pessimo sistema e privo di supporto long-term, che per un progetto professionale – per proteggere l’investimento – deve essere la prima cosa da valutare. Inoltre solo 2 settimane per fare la migrazione/upgrade, con tutti i problemi relativi, potrebbe portare a notevoli problemi (come leggo dai vari commenti). Personalmente devo ancora effettuare la migrazione.
Sconsiglio quindi altamente Nativescipt per qualsiasi progetto professionale.

Ho avuto l’idea di sviluppare una applicazione nativa per smartphone, al fine di permettere alla mia compagna di agevolarle la scrittura di Pattern di Crochet per Amigurumi, per poi poterli stampare e venderli su Etsy.
Questo è il risultato finale:


Tra l’altro sono in vendita anche le bambole finite, pronte per la spedizione, un bellissimo e originale regalo per tute le età!

Ma ora torniamo alla nostra App!

Requisiti

Il lavoro è molto lungo e richiede continue correzioni, e allegare ai vari passaggi foto che aiutino a capire esattamente come procedere. E non è una cosa semplice!
Ora si prendeva le note su un foglio di carta, ma poi diventava difficile ricordarsi di fare le foto, associarle al passaggio del pattern, e poi ri-scrivere tutto su Word per generare un Pdf distribuibile. Se anche un passaggia non è perfetto, il pattern non si può vendere.
Allora ecco l’idea di creare un App, in modo tale da editare i Pattern direttamente sul cellulare e prendere direttamente le foto. Poi esportare il tutto in Pdf. Et voilà, il Pattern è pronto.

Premetto che la mia esperienza di applicazioni native su cellulare era quasi nulla, a parte un breve corso di base su React Native. Per partecipare al corso ho avuto la necessità di fare il setup dell’emulatore con Android Studio, quindi un po’ di esperienza su questo punto ce l’avevo per fortuna, e anche un emulatore funzionante.

I miei requisiti ideali erano:
gratuito: è un progetto amatoriale, poi se dovesse andare bene il business in futuro potrei sicuramente investire in qualcosa di più professionale,
TypeScript: nel 2020 scrivere codice in JavaScript per me non è una opzione,
Angular: così riutilizzo gli stessi pattern, Rx, rxjs/redux e librerie,
Visual Studio Code / Visual Studio: ri-utilizzo delle conoscenze dell’IDE,
– Ambiente di sviuppo Windows,
veloce setup dell’emulatore: per esperienza può essere molto frustrante avere un emulatore up-and-running con la possibità di fare debug del codice,
Android: magari anche iOs se senza sforzo,
– supportato da tecnologie solide: in modo tale da garantire di evitare di riscrivere tutto in un paio di anni,
nessuna Api: tutti i dati devono essere residenti sul dispositivo,
– salvataggio dei dati in file formato testo: semplici da editare, quindi ho scelto Json, piuttosto che l’ottimo SQLite. Ogni progetto sarà composto da una cartella con un file json di progetto e tutte le foto necessarie allegate,
– salvataggio dei file su cartella pubblica: in modo che in nessun modo sia possibile “perdere” tutto il lavoro fatto (es. disinstallando l’app) e che fosse semplici aggiungere e rimuovere progetti. NB. lo storage interno della App non è accessibile via USB! Sospetto poi che un aggiornamento della App potreste perderne il contenuto, ma non l’ho verificato.
semplice UX: utilizzabile semplicemente da chiunque, il target degli utilizzatori sono persone non tecniche.

Scelta e setup di NativeScript

Ho iniziato scegliendo la piattaforma di sviluppo da utilizzare, e le opzioni erano tra Ionic e NativeScript (Ionic vs NativeScript). Ho scelto NativeScript in quanto l’integrazione con TypeScript e Angular sembravano native, e quindi avrei riutilizzato due conoscenze che già avevo. La scelta è stata semplice.
NativeScript permette di creare UI Native (quindi compilate in codice binario) ma scrivendo codice in JavaScript + HTML, e puo’ essere utilizzato con framework come Angular, Vue, e NativeScript Xml.

Ho quindi seguito la loro guida su come fare il setup e mi è sembrata abbastanza semplice e ben fatta, per poi scoprire che aveva ignorato le mie precedenti impostazioni e aggiunti emulatori, applicazioni, tools, in altri posti, creando una confuzione incredibile. Dopo ore di ricerche e tentativi, sono riuscito ad avere un ambiente funzionante, ma sto ben attento a installare aggiornamenti di Android Studio, devo dire che sono ancora traumatizzato.

Venendo dal mondo Microsoft, sono stupito dalla povertà di questi ambienti di sviluppo, che sembrano sviluppati da pochi giorni e da ragazzini, quando in realtà è lo standard de-facto da molti anni. Se siete abituati agli IDE e avete esperienza di sviluppo di Microsoft, munitevi di tanta tanta pazienza.

Per vostra comodità alla fine dell’articolo ho riportato dei link utili, che fanno riferimento alla documentazione che ho trovato utile e ai plugin che ho utilizzato.

La prima impressione

In realtà la piattaforma è molto debole, la documentazione scarsa, e molto lavoro da fare per capire come risolvere i “problemi”. Forse sarebbe stato lo stesso con Ionic, ma ad oggi sconsiglierei NatveScript e direi di provare Ionic. Mal che vada avrete la stessa (pessima) esperienza.
Purtroppo lo sviluppo Native è ancora molto indietro su quello che sono le aspettative di base per una App appena decente, e questo penso dipenda dal supporto del sistema operativo, che sia Android o iOs. Evidentemente la possibilità di libertà si paga con un sacco di lavoro per avere qualcosa di decente. E non parlo di effetti speciali, ma di semplici pulsanti per navigare attraverso la App, o di layout per distribuire i contenuti.

Diciamo che se devi fare la classica App che visualizza foto, o che ha una struttura semplice, allora non dovresti avere problemi.
Nel mio caso invece era una App “di lavoro” in cui dovevo ottimizzare l’inserimento dei contenuti, e dover fare 3000 click per abilitare un pulsante, dover aprire form, o passare a altre pagine non era assolutamente contemplato.

Integrazione con IDE

L’integrazione con Visual Studio Code devo dire che è molto buona e permette di fare il debug direttamente nell’IDE, richiede solo la loro estensione.
Si lancia l’emulatore, si lancia il debug nativo, e dopo che l’immagine è stata trasferita nel device, si può debuggare il codice step-by-step. Ottimo!
Alternativa è anche utilizzare il debug con Chrome, ma secondo me è meno pratico.
Non ho scoperto però come fare il debug (intendo “inspect”) degli elementi nella UI, se qualcuno sa come fare fatemi sapere!

Integrazione con Angular

Inoltre l’integrazione con Angular non è assolutamente semplice, proprio per come le app Angular sono progettate dentro NativeScript. Ovvero se hai un Observable in un component, dimenticati che puoi “completarlo” all’uscita della pagina, perchè così non funziona! Come si risolve il problema? Beh è semplice: intanto di devi accorgere di avere il problema (e qui auguri, perchè si manifesterà con out-of-memory o rallentamenti) poi ti devi cercare il problema e forse troverai la soluzione che non è chiara.

Ma io dico: se sviluppi un framework simile, è ovvio che questa cosa deve essere scritta in prima pagina della documentazione, altrimenti come pensi che la gente possa essere felice di usare il tuo framework?

SASS

Poi abbiamo SASS che è supportato ma, ovviamente, il progetto template di base parte senza. Certo perchè chi a sviluppa App con Angular non serve SASS, ma scrive CSS direttamente e non ha necessita ‘ di customizzare il Template di base. Ovviamente è una follia!

Poi abilitare SASS è un incubo, ho perso tanto di quel tempo dietro pessima e vecchia documentazione che non lo rifarei mai un’altra volta.

Elementi UI e layout

Poi devi iniziare a mettere dei componenti sulla tua UI, e scopri che la fantastica documentazione per ogni elemento, in realtà è inutile, in quanto è una raccolta di cose ovvie. Se vuoi poi provare le varie opzioni, ovviamente gli screenshot sono mancanti, e secondo loro dovresti spendere il 90% del tempo che hai a disposizione a provare le vari opzioni per vedere quella che ti va bene.
Poi devi mettere i vari elementi su un layout, e qui ti metti a piangere, una cosa impossibile da fare in poco tempo. Io vi consiglio fortemente di spendere la maggior parte del tempo a disposizione nel comprendere i vari tipi di elementi per il Layout, comprendere che tipologie di problemi risolvono, e fare delle prove reali. Personalmante ho sottovalutato questo punto e ho dovuto riscrivere molte parti molte volte, e ancora ad oggi il risultato è molto scarso a livello estetico di UI e UX, e di sicuro non segue le best-practice per UI Native.

Una cosa che funziona bene senza sorprese sono i form modali, tipo MessageBox e InputBox per capirsi.

Icone

Tiri un sospiro di sollievo quando vuoi aggiungere delle icone ai tuoi pulsanti, e l’integrazione con FontAwesome è molto semplice e funzionale. In pratica puoi utilizzare le icone come testo normale nei vari elementi. Ad esempio

<Button (tap)="onClick()">
	<FormattedString>
		<Span text="&#xf03a;" class="fas"></Span>
	</FormattedString>
</Button>

genera un pulsante con icona simile a questo:

Android e iOs

Beh se pensate che sviluppando in NativeScript potete cogliere entrambe le piattaforme non è proprio “gratis”. Vi servirà un modo per eseguire l’emulatore e nel codice scrivere customizzazioni specifiche per il target. Per capirsi: if-android then… if-ios then… ah ovviamente non è incluso nel framework, ma quando te ne accorgi, è troppo tardi, e ti serve un plugin esterno.

Storage

A questo punto devo salvare i dati sul dispositivo, in modo tale siano accessibili dall’esterno (via USB per capirsi) e scopri che non è così semplice. Ma la domanda sorge spontanea: a cosa dovrebbe servire una App? Ancora non capisco per quale motivo sviluppino un framework come NativeScript.

Ricordo che dietro c’è il gigante Progress (forse più conosciuto per Telerik), che avevo rivalutato positivamente con l’utilizzo dei loro componenti Kendo per Angular.
Beh mi sono ricordato perchè ne avevo caldamente sconsigliato l’utilizzo, memore della mia esperienza precedente in un grosso progetto in Italia, dove avevamo dovuto rimuovere ovunque i plugin Telerik che erano stati utilizzati (mesi di lavoro).

Foto e plugin

Dope aver perso anni di vita, diventi un po’ più abile e cerchi di utilizzare funzionalità un po’ più evolute, tipo la possibilità di scattare una foto e poterla di conseguenza editare (funzione di base in ogni cellulare).
Per farlo non esiste niente di nativo, ma devi utilizzare una libreria in Javascript creata mille anni fa e che per fortuna funziona.
Se poi vuoi selezionare una immagine dal tuo dispositivo per linkarla, ti serve un altro plugin, “NativeScript mediafilepicker”. Sul serio! Il bello è che funziona ma segue pattern javascript-style “antichi”, no promises o observable, e tra l’altro non è integrata con il lifecycle di Zone, e quindi la UI non veniva aggiornata a causa che il “change detection” non funzionava.
Dopo avere provato tutte le possibili combinazioni per risolvere il problema e aver capito come integrarla, ho contattato l’autore per chiedergli di approvare una mia Pull Request su github per aggiungere la nota alla documentazione.
Peccato che “secondo lui” è una cosa ovvia e tutti quelli che usano Angular sanno di questa cosa! Ma gli ho spiegato che non è la prassi e che in 4 anni di utilizzo con applicazioni enterprise, non mi era mai capitato. Ora per fortuna è documentato!

Come regola diciamo che le librerie esterne/plugin devono essere compatibili con NativeScript, altrimenti non è possibile utilizzarle. Questo in quanto NativeScript non ha – ovviamente – il supporto a elementi del browser, quindi le chiamate a determinate funzioni devono essere ri-mappate in codice nativo. Quindi se un plugin richiede una chiamata che NativeScript non ha mappato, non può funzionare. Questo riduce di molto le librerie che purtroppo potete utilizzare.
Inoltre la maggior parte delle funzionalità sono implementate con Promise, e che con il mondo Angular non si integrano proprio benissimo.

Funzioni… avanzate?

E che dire di un drop-down da cui sia semplice scegliere un elemento da una lista? non esiste, devi fartelo. Per fortuna ho trovato un post a riguardo, dell’ottimo Dave Coffin, che ha implementato un filterable list picker.

Ti serve abilitare dei permessi per la tua App, tipo storage o camera? ovviamente è una cosa di base ed è già integrata… ah no, ops, ti serve un plugin esterno…
Color picker? semplicissimo: cerca su google per un paio di ore, prova un paio di plugin, ed è fatta (forse) in un paio di giorni.

Vuoi salvare una immagine e regolare la compressione? Devi usare un trucchetto che ho scoperto dopo molte ricerche, grazie a Tim Leland:

	var saved = imageSource.saveToFile(path, "jpg", compressionValue);

Discorso diverso invece se vuoi generare un documento in pdf, lì è più semplice: non puoi farlo e basta. Ho quindi optato per generare un documento in html e css, per poi stampare il tutto sul pc. Avrei potuto utilizzare una Api, ma non volevo avere quella dipendenza.

Ho quindi scoperto che nel 2020 html e css non supportano ancora la stampa su carta/pdf. Alla fine però ce l’ho fatta e sono soddisfatto del risultato, oltre ad avere imparato un sacco di trucchi per applicare watermark, layout multi-colonna, e le comodissime (e devo ammettere per me nuove) css-grid.

Per poter stampare il file in pdf, o per applicare una post-elaborazione del template (in quanto il css è customizzabile), serve inviare tutti i file e e foto su un computer. Quindi ho pensato di creare uno Zip (anche qui, con un plugin esterno) e inviarlo via email, ma il limite sui client/app di posta (es Gmail) è di circa 10 Mb di allegati. Per fortuna le cartelle del “progetto” sono memorizzate sullo storage pubblico, e quindi basta collegare il cavo USB per poterle copiare sul pc.

Sidekick

Aggiornamento di maggio 2020: SideKick praticamente non è più disponibile!

Un punto a favore di NativeScript è l’applicazione “Sidekick” che semplifica enormemente la compilazione e distribuzione della App. Pochi click e ottieni un Apk da installare sul cellulare con un QR-code. Il tutto con le giuste icone, splash screen, il tutto settato per Android a iOs. Un ottimo lavoro.
Sidekick è gratuito fino a 100 build al mese, direi perfetto per un piccolo gruppo di sviluppatori.

Vi lascio alcuni link utili al risorse per NativeScript e Angular:

One Comment

  1. benz 22 Luglio 2020 Reply

Add a Comment

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *