Creazione della prima app con fusibile

Ora che hai imparato i concetti di base di Fuse, è il momento di mettere le cose in pratica e costruire un'app. In questo tutorial, imparerai come sviluppare un'app utilizzando il framework Fuse. In particolare, imparerai quanto segue:

  • Come codificare usando UX Markup.
  • Come utilizzare le API Observable, Timer e Geolocation.
  • Come visualizzare un'anteprima di un'app utilizzando l'anteprima del desktop e l'anteprima personalizzata.

Se hai bisogno di un aggiornamento su Fuse, controlla il mio post precedente in questa serie: Introduzione a Fuse per lo sviluppo di app multipiattaforma.

Prerequisiti

Per iniziare a lavorare con Fuse, vai alla pagina dei download e registrati per un account. Puoi anche accedere a un account esistente se ne hai uno. 

Il fusibile è disponibile sia per Windows che per macOS. Scarica e installa il programma di installazione corretto per la tua piattaforma. Nella pagina dei download, indicano anche i plugin Fuse disponibili per vari editor di testo. Installa quello per il tuo editor di testo. I plugin Fuse includono il completamento del codice, la definizione goto e la visualizzazione dei log generati dall'app, il che rende tutte le app in sviluppo più convenienti.

Vedremo anche come visualizzare un'anteprima dell'app utilizzando l'anteprima personalizzata. Ciò richiede l'installazione di Android Studio o Xcode sul tuo computer.  

Una conoscenza di base delle tecnologie web come HTML, CSS e JavaScript è utile ma non necessaria.

Cosa starai creando

Creerai un'app di cronometro che misura anche la distanza percorsa. La distanza viene misurata usando la geolocalizzazione. L'utente può anche creare giri, e la distanza individuale e il tempo per ogni giro saranno visualizzati sullo schermo.

Ecco come apparirà l'app:

È possibile visualizzare il codice sorgente completo nel tutorial repo GitHub.

Creazione di un nuovo progetto di fusibile

Una volta installato Fuse Studio, ora dovresti essere in grado di creare un nuovo progetto Fuse. Basta aprire Fuse Studio e fare clic su Nuovo progetto Fuse pulsante. Inserire il nome del progetto e fare clic Creare:

Questo creerà una nuova cartella nella directory selezionata. Apri quella cartella e apri il MainView.ux file. Di default, avrà solo il  markup. Aggiornare per includere a , e quindi salvare il file:

 Ciao mondo! 

L'anteprima dovrebbe ora essere aggiornata con il testo specificato:

Questo è il principale flusso di lavoro di sviluppo in Fuse. Basta salvare le modifiche a qualsiasi file nella directory del progetto e queste verranno automaticamente riflesse nell'anteprima del desktop. 

Puoi anche vedere i log nel pannello in basso. Puoi attivare il tuo usando console.log (), come nel browser. L'unica differenza è che devi JSON.stringify () oggetti per vedere il loro valore, dal momento che console.log () l'implementazione in Fuse può produrre solo stringhe. 

Markup UX

Ora siamo pronti per creare l'app. Apri il MainView.UX file e rimuovere il elemento di prima. In questo modo, possiamo iniziare con una lavagna vuota:

 

Compresi i caratteri

Proprio come in un documento HTML, lo standard è quello di includere le risorse (cose come font, fogli di stile e script) prima del markup effettivo della pagina. Quindi aggiungi il seguente all'interno del  elemento:

Questo importa il carattere specificato in File attributo e dà il nome Magro. Si noti che questo non lo rende il carattere predefinito per l'intera pagina. Se si desidera utilizzare questo tipo di carattere, è necessario utilizzare il suo nome (Magro) sul testo specifico a cui vuoi applicarlo. 

Puoi scaricare il font dal repository di GitHub. Successivamente, crea un beni / fonts / robot cartella all'interno della directory del progetto root e inserire il .ttf file in esso.

Se si desidera utilizzare un altro font, è possibile scaricarlo da dafont.com. Ecco dove ho scaricato il font per questa app.

Successivamente, vogliamo utilizzare le icone all'interno dell'app. Il fusibile in realtà non ha elementi integrati e set di icone che ti permettono di farlo. Ciò che offre è un modo per includere i font di icone esistenti nella tua app. Poiché i font delle icone sono essenzialmente dei caratteri, possiamo utilizzare lo stesso metodo per includere i caratteri:

Puoi scaricare il font dell'icona dal repository GitHub o scaricarlo direttamente da fontawesome.com. Nota che non tutte le icone su fontawesome sono gratuite, quindi è meglio controllare la pagina dell'icona reale prima di usarla. Se vedi un'etichetta "pro" accanto all'icona, non puoi semplicemente usarla nel tuo progetto senza pagare. 

Compreso JavaScript

Successivamente, dobbiamo includere il file JavaScript per questa pagina. Possiamo farlo usando il  elemento:

Non dimenticare di creare il scripts /MainView.js file nella root della directory del progetto. 

Creazione di nuovi componenti

Per massimizzare il riutilizzo del codice, Fuse ci consente di creare componenti personalizzati da quelli esistenti. Nel codice qui sotto, stiamo usando un per creare un pulsante personalizzato. Pensalo come un div che funge da contenitore per altri elementi. In questo caso, lo stiamo usando come componente riutilizzabile per la creazione di un pulsante. 

Il fusibile ha molti elementi. Ci sono elementi per la disposizione di contenuti come il , elementi per mostrare controlli utente, pagine e navigazione, scripting e dati e primitive per la costruzione dell'interfaccia utente. Ognuno ha il proprio set di proprietà, che consente di modificare i dati, la presentazione e il comportamento.

Per creare un componente riutilizzabile, aggiungi a UX: Class proprietà a un elemento di presentazione che desideri utilizzare come base. In questo caso, stiamo usando un come base. È quindi possibile aggiungere alcuni stili di default. Questo è simile a come lo styling è fatto in CSS. Margine aggiunge spazio al di fuori del contenitore. Qui abbiamo specificato solo un singolo valore, quindi questo margine viene applicato su tutti i lati del pannello. Colore aggiunge un colore di sfondo all'elemento:

 

Dentro il , vogliamo mostrare il testo del pulsante. Vogliamo trasformarlo in un componente riutilizzabile, quindi abbiamo bisogno di un modo per passare in proprietà per quando utilizzeremo questo componente in seguito. Questo ci consente di ottenere risultati diversi cambiando solo le proprietà. 

Dentro il , utilizzare il tipo di dati del valore che si desidera passare come nome dell'elemento e quindi aggiungere il nome della proprietà utilizzando UX: Proprietà. È quindi possibile mostrare il valore fornito alla proprietà utilizzando ReadProperty PropertyName, dove Nome della proprietà è il valore che hai fornito UX: Proprietà. Questo ti permetterà di fornire un Testo proprietà ogni volta che si utilizza il  componente.

 

Successivamente, vogliamo offrire all'utente una sorta di feedback mentre si preme il pulsante. Possiamo farlo tramite trigger e animatori. I trigger sono fondamentalmente gli ascoltatori di eventi, in questo caso, . E gli animatori sono le animazioni o gli effetti che si desidera eseguire mentre il trigger è attivo. Il codice qui sotto farà il pulsante 10% più grande della sua dimensione originale e cambiare il suo colore. Durata e DurationBack ti consente di specificare quanto tempo impiega l'animazione per raggiungere il suo picco e raggiungere la sua fine.

   

Successivamente, creiamo il componente. Come suggerisce il nome, questo è un pulsante che mostra solo un'icona come suo contenuto. Funziona allo stesso modo del componente precedente, anche se ci sono alcune nuove cose che abbiamo fatto qui. 

Il primo è il UX: Nome proprietà. Questo ci permette di dare un nome a un elemento specifico in modo che possiamo fare riferimento ad esso in seguito. In questo caso, lo stiamo usando per cambiarlo Colore proprietà mentre si preme il pulsante. 

Abbiamo anche usato un elemento condizionale chiamato . Questo ci permette di disabilitare il  trigger quando il valore per is_running è falsa. Forniremo il valore per questa variabile una volta raggiunta la parte JavaScript. Per ora, sappi che questa variabile indica se il timer è attualmente in esecuzione o meno.

  ReadProperty Text         

Contenuto principale

Ora possiamo procedere con il contenuto principale. Per prima cosa, avvolgiamo tutto in un . Come suggerisce il nome, questo ci permette di "impilare" i suoi figli sia verticalmente che orizzontalmente. Per impostazione predefinita, utilizza l'orientamento verticale, quindi non è necessario specificarlo esplicitamente: 

 

Nel codice sopra, abbiamo usato quattro valori per il Margine. A differenza dei CSS, la distribuzione dei valori è sinistra, in alto, a destra, in basso. Se sono specificati solo due valori, è left-right, top-bottom. Puoi utilizzare lo strumento di selezione in Fuse Studio per visualizzare i margini applicati.

Successivamente, aggiungiamo un'immagine di sfondo per la pagina. Questo accetta il percorso del file per l'immagine di sfondo che si desidera utilizzare. UN StretchMode di Riempire rende lo sfondo si allunga per riempire l'intero schermo:

Puoi scaricare l'immagine di sfondo che ho usato dal tutorial repo GitHub. Oppure puoi trovare modelli simili sul sito di Toptal. 

Successivamente, mostra il nome dell'app. Sotto è il campo di testo trascorso nel tempo. Questo testo deve essere aggiornato frequentemente, quindi dobbiamo trasformarlo in una variabile che può essere aggiornata tramite JavaScript. Per generare del testo inizializzato nel file JavaScript di questa pagina, è necessario racchiudere il nome della variabile tra parentesi graffe. Successivamente, vedrai come il valore di questa variabile viene fornito dal file JavaScript:

 tempo trascorso

Successivamente, usiamo il componente che abbiamo creato in precedenza, non diversamente da un ambiente web in cui utilizziamo l'ID del carattere. In Fuse, è necessario utilizzare l'Unicode assegnato al carattere dell'icona che si desidera utilizzare. Devi anche usare &#X come prefisso. Quando viene premuto questo pulsante (chiamato cliccato), il addLap () la funzione dichiarata nel file JavaScript viene eseguita:

In Font Awesome, puoi trovare l'unicode del carattere dell'icona sulla sua pagina.

Subito sotto il pulsante per aggiungere un nuovo giro c'è del testo che indica che il pulsante sopra è per aggiungere nuovi giri:

Quindi, mostra il pulsante per l'avvio e l'arresto del timer. Questo esegue anche una funzione che dichiareremo in seguito:

Successivamente, dobbiamo generare i giri aggiunti dall'utente. Questo include il numero di giro, la distanza coperta e il tempo trascorso. Il elemento ci permette di scorrere attraverso una collezione di oggetti e visualizzare le singole proprietà per ogni oggetto:

        

Nel codice sopra, stiamo usando il per avvolgere il contenuto per ogni oggetto. Questo tipo di pannello ci consente di "agganciare" i suoi figli su lati diversi (in alto, a sinistra, a destra e in basso) dello spazio disponibile. Di default, questo posiziona i suoi figli direttamente l'uno sopra l'altro. Per distribuirli uniformemente, è necessario aggiungere il Allineamento proprietà. 

Codice JavaScript

Ora siamo pronti per aggiungere il codice JavaScript. In Fuse, JavaScript viene principalmente utilizzato per la business logic e funziona con le funzionalità native del dispositivo. Effetti, transizioni e animazioni per interagire con l'interfaccia utente sono già gestiti da UX Markup.

Inizia importando tutte le API di cui abbiamo bisogno. Ciò comprende Osservabile, che viene utilizzato principalmente per l'assegnazione di variabili nell'interfaccia utente. Queste variabili possono quindi essere aggiornate utilizzando JavaScript. Timer è l'equivalente del setTimeout e setInterval funzioni nella versione web di JavaScript. GeoLocation ci consente di ottenere la posizione attuale dell'utente:

var Observable = require ("FuseJS / Observable"); var Timer = require ("FuseJS / Timer"); var GeoLocation = require ("FuseJS / GeoLocation");

Successivamente, inizializziamo tutti i valori osservabili che useremo. Queste sono le variabili che hai visto prima nel markup UX. I valori di queste variabili vengono aggiornati per tutta la durata dell'app, quindi li rendiamo una variabile osservabile. Questo ci consente in effetti di aggiornare i contenuti dell'interfaccia utente ogni volta che uno di questi valori cambia:

var time_elapsed = Observable (); // il testo del timer var toggle_btn_text = Observable (); // il testo per il pulsante per l'avvio e l'arresto del timer var is_running = Observable (); // se il timer è attualmente in esecuzione o no var laps = Observable (); // i giri aggiunti dall'utente

Dopodiché, possiamo ora impostare i valori iniziali per il pulsante di attivazione e il testo del timer:

toggle_btn_text.value = 'Start'; // attiva / disattiva il testo predefinito del pulsante time_elapsed.value = "00:00:00"; // testo predefinito del timer

Ecco come si modifica il valore di una variabile osservabile. Poiché questi non sono all'interno di alcuna funzione, questo dovrebbe aggiornare l'interfaccia utente immediatamente all'avvio dell'app.

Imposta i valori iniziali per il timer, il tempo sul giro e la posizione per ogni giro:

var time = 0; // timer var lap_time = 0; // tempo per ogni giro var locations = []; // posizione dell'utente per ciascun giro

Il ginocchiera () la funzione è utilizzata per avviare e arrestare il timer. Quando il timer è attualmente fermo e l'utente tocca il pulsante di attivazione, è l'unica volta che ripristiniamo i valori per il timer e i giri. Questo perché vogliamo che l'utente veda questi valori anche dopo aver fermato il timer. 

Successivamente, ottieni la posizione corrente dell'utente e inseriscila posizioni array. Questo ci permette di confrontarlo con la prossima posizione dopo, una volta che l'utente aggiunge un giro. Quindi, crea un timer che viene eseguito ogni 10 millisecondi. Aumentiamo sia il totale tempo e il tempo del giro per ogni esecuzione. Quindi aggiorna l'interfaccia utente con il valore formattato usando formatTimer () funzione:

function toggle () if (toggle_btn_text.value == 'Start') // il timer è attualmente fermo (in alternativa, usa is_running) laps.clear (); // i valori osservabili hanno un metodo clear () per resettare il suo valore time_elapsed.value = formatTimer (time); is_running.value = true; locations.push (GeoLocation.location); // get location iniziale timer_id = Timer.create (function () time + = 1; // incrementato ogni 10 millisecondi lap_time + = 1; // current lap time time_elapsed.value = formatTimer (time); // aggiorna l'interfaccia utente con il tempo trascorso formattato stringa, 10, vero);  else // next: aggiungi il codice per quando l'utente arresta il timer toggle_btn_text.value = (toggle_btn_text.value == 'Start')? 'Stop': 'Start'; 

Quando l'utente arresta il timer, lo cancelliamo usando il Elimina() metodo nel timer. Ciò richiede il timer_id che è stato restituito al momento della creazione del timer:

Timer.delete (timer_id); // cancella il timer corrente // ripristina il resto dei valori time = 0; lap_time = 0; is_running.value = false; 

La prossima è la funzione per la formattazione del timer. Funziona convertendo i millisecondi in secondi e in minuti. Sappiamo già che questa funzione viene eseguita ogni 10 millisecondi. E il tempo è incrementato di 1 ogni volta che esegue. Quindi per ottenere i millisecondi, semplicemente moltiplichiamo il tempo di 10. Da lì, calcoliamo solo i secondi ei minuti in base al valore equivalente per ciascuna unità di misura:

function formatTimer (time) function pad (d) return (d < 10) ? '0' + d.toString() : d.toString();  var millis = time * 10; var seconds = millis / 1000; mins = Math.floor(seconds / 60); secs = Math.floor(seconds) % 60, hundredths = Math.floor((millis % 1000) / 10); return pad(mins) + ":" + pad(secs) + ":" + pad(hundredths); 

Ogni volta che l'utente tocca il pulsante di aggiornamento, il addLap () la funzione è eseguita. Questo aggiunge una nuova voce in cima al giri osservabile: 

function addLap () if (time> 0) // esegue solo quando il timer è in esecuzione lap_time_value = formatTimer (lap_time); // formatta il tempo sul giro corrente lap_time = 0; // resetta il tempo sul giro var start_loc = posizioni [laps.length]; // ottiene la posizione precedente var end_loc = GeoLocation.location; // ottiene la posizione corrente locations.push (end_loc); // aggiungi la posizione corrente var distance = getDistanceFromLatLonInMeters (start_loc.latitude, start_loc.longitude, end_loc.latitude, end_loc.longitude); // aggiungi il nuovo elemento in cima laps.insertAt (0, title: ("Lap" + (laps.length + 1)), time: lap_time_value, distance: distance.toString () + "m."); 

Ecco la funzione per ottenere la distanza coperta in metri. Questo usa la formula di Haversine:

function getDistanceFromLatLonInMeters (lat1, lon1, lat2, lon2) function deg2rad (deg) return deg * (Math.PI / 180) var R = 6371; // raggio della terra in km var dLat = deg2rad (lat2 - lat1); var dLon = deg2rad (lon2 - lon1); var a = Math.sin (dLat / 2) * Math.sin (dLat / 2) + Math.cos (deg2rad (lat1)) * Math.cos (deg2rad (lat2)) * Math.sin (dLon / 2) * Math.sin (dLon / 2); var c = 2 * Math.atan2 (Math.sqrt (a), Math.sqrt (1 - a)); var d = (R * c) * 1000; // Distanza in m ritorno d; 

Non dimenticare di esportare tutti i valori osservabili:

module.exports = toggle: toggle, toggle_btn_text: toggle_btn_text, is_running: is_running, time_elapsed: time_elapsed, giri: laps, addLap: addLap

Pacchetto di geolocalizzazione

Per mantenere le cose leggere, Fuse in realtà non include tutti i pacchetti che supporta di default. Per cose come la geolocalizzazione e le notifiche locali, devi dire a Fuse di includerle quando costruisci l'app. Aperto StopWatch.unoproj alla radice della directory del progetto e includi Fuse.GeoLocation sotto il Pacchi array:

"Pacchetti": ["Fuse", "FuseJS", "Fuse.GeoLocation" // aggiungi questo],

Questo dovrebbe indicare a Fuse di includere il pacchetto Geolocation ogni volta che si crea l'app per l'anteprima personalizzata o per generare un programma di installazione. 

Impostazione per l'anteprima personalizzata 

Prima di poter eseguire l'app sul tuo dispositivo iOS, devi prima aggiungere un identificatore del bundle all'app. Apri il Cronometro.unoproj file e aggiungere il seguente sotto iOS. Questo sarà l'identificazione univoca per l'app quando viene inviata all'app store:

"Pacchetti": [// ...], "iOS": "BundleIdentifier": "com.yourname.stopwatch", "PreviewBundleIdentifier": "com.yourname.stopwatch.preview"

Successivamente, su Xcode, accedi con il tuo account sviluppatore Apple. Se non ne hai già uno, puoi visitare il sito Web degli sviluppatori Apple e crearne uno. In realtà è libero di sviluppare e testare le app sul tuo dispositivo iOS. Tuttavia, ci sono alcune limitazioni se non fai parte del programma per sviluppatori.

Una volta creato il tuo account, vai alle preferenze di Xcode e aggiungi il tuo account Apple. Quindi fare clic su Gestisci certificati e aggiungi un nuovo certificato per lo sviluppo iOS. Questo certificato viene utilizzato per garantire che l'app provenga da un'origine conosciuta.

Una volta fatto, ora dovresti essere in grado di eseguire l'app sul tuo dispositivo. Clicca su Anteprima > Anteprima su iOS in Fuse Studio e attendi che venga lanciato Xcode. Una volta che Xcode è aperto, seleziona il tuo dispositivo e fai clic sul pulsante di riproduzione. Questo costruirà l'app e la installerà sul tuo dispositivo. Se si verifica un errore di generazione, è molto probabile che l'identificatore del gruppo di anteprima non sia univoco:

Cambiare il Identificativo del pacchetto a qualcosa di unico dovrebbe risolvere il problema. Una volta scomparso l'errore nella sezione della firma, fai nuovamente clic sul pulsante di riproduzione per ricostruire l'app. Questo dovrebbe installare l'app sul tuo dispositivo. 

Tuttavia, non potrai aprire l'app finché non la approvi. Puoi farlo sul tuo dispositivo iOS andando a impostazioni Generale Gestione dei dispositivi e selezionando l'email associata al tuo account sviluppatore Apple. Approvalo e dovrebbe sbloccare l'app.

Per Android, dovresti essere in grado di visualizzare l'anteprima dell'app senza ulteriori passaggi.

Conclusione

Questo è tutto! In questo tutorial, hai imparato le basi della creazione di un'app utilizzando il framework Fuse. In particolare, hai creato un'app cronometro. Creando questa app, hai imparato a lavorare con UX Markup di Fuse e alcune API JavaScript di Fuse. Hai anche imparato a usare Fuse Studio per visualizzare in anteprima l'app sul tuo computer e sul tuo telefono durante lo sviluppo.