Compatibile con Xcode 8

Tutorial NSTimer in Swift, creare applicazione cronometro

ENTRA NEL NOSTRO GRUPPO FACEBOOK

Ogni giorno sei costretto a confrontarti con il nemico dei nemici, colui che ti ama e ti abbandona, ti culla, ti allatta e poi finisce perTutorial NSTimer in Swift, creare applicazione cronometro buttarti in mezzo ad una strada! no! non è la scuola o il lavoro ma è…

Il tempo!

Quante volte ti è capitato di volere giorni da 72 ore solo perché non riesci a completare tutti i tuoi impegni in sole 24?

Il dramma di tutti, sviluppatori e non, è non riuscire a completare qualcosa in tempo. Ma, fortunatamente c’è sempre un ma, il tempo da nemico può diventare amico con le giuste cure e prese di coscienza.

Un po’ mi sembra inutile ripetertelo (ci avranno già pensato amici e parenti) ma voglio dirtelo lo stesso -> nella stragrande maggioranza delle volte, non è il tempo ad essere il tuo problema, ma è il modo in cui viene gestito.

No! non parlerò della gestione personale del tempo bensì della gestione dei tempi della tua applicazione e come generare un evento ad un determinato istante di tempo. Dato che molte persone mi contattano, chiedendomi se c’è un modo per poter far partire una funzione, una notifica o un timer ad un determinato istante di tempo, ho deciso di creare un tutorial tutto centrato sull’utilizzo del NSTimer in Swift.

Cosa tratta questo tutorial

In questa guida voglio mostrarti come creare una applicazione, in Swift per iOS 8, con le stesse funzioni di un cronometro. Nel particolare l’applicazione che creerai sarà composta dalle seguenti caratteristiche:

  1. Gestione di un Timer tramite l’oggetto NSTimer.
  2. Possibilità di avviare e stoppare lo scorrere del tempo.
  3. Visualizzare lo scorrere del tempo in una UILabel.
  4. Salvare i tempi dell’utente nel CoreData (nel prossimo tutorial).
  5. Visualizzare i tempi in una TableView (nel prossimo tutorial).

Il tutorial, come tutti gli altri, è sempre rivolto a chi già conosce le basi della programmazione e la programmazione ad oggetti.

Quindi se sei un nuovo programmatore, o vuoi imparare il nuovo linguaggio Swift vai qui -> INIZIA DA QUA!

Let’s start! Creare progetto e interfaccia in Xcode

Apri Xcode, crea un nuovo progetto da File\New\Project…, seleziona iOS e Single View Application, premi Next. Alla schermata successiva dai un nome al tuo progetto, assicurati di aver selezionato Swift come linguaggio di programmazione, seleziona iPhone come Devicesabilita il Core Data (non serve per la gestione del timer ma te lo faccio attivare solo perché molto probabilmente il prossimo tutorial è il continuo di questo). Premi Next e infine Create.

Come ho già accennato qua, il primo passo da fare nella realizzazione di un’applicazione è quello di creare l’interfaccia utente.

Apri il Main.storyboard.

Trascina all’interno dell’interfaccia:

  1. Una UILabel. Posizionala al centro della View, allarga le dimensioni in modo da far entrare correttamente il testo e successivamente dall’Attributes Inspector cambia l’alignment in centrale e se vuoi il font e font size.
    Cambia il text da “Label” in “00:00”.
  2. Una ToolBar. Posizionala in fondo alla View, poi seleziona il bottone di default e sempre dall’Attributes Inspector cambia l’identifier in Play.
    Adesso aggiungi un nuovo Bar button item alla tool bar e cambia l’identifier in Pause.
    Per spostare il nuovo bottone dall’altro lato devi aggiungere, tra i due bottoni, una Flexible space bar buttom item.

La tua applicazione dovrebbe avere una interfaccia simile a questa:

interfaccia Tutorial NSTimer in Swift, creare applicazione cronometro

Risolvere velocemente i problemi di auto layout

Se provi ad avviare l’app, la prima cosa che noterai sarà sicuramente il layout della grafica sfalsato. Bottoni che non si vedono e Label decisamente non centrale.

Quando hai creato il progetto hai impostato iPhone come Devices e ciò sta a significare che il layout della tua app non è configurato per un tipo specifico, ad esempio iphone 5, ma è pensato per funzionare su tutti i modelli disponibili.

Ora, per risolvere questi problemi bisogna implementare l’auto layout e aggiungere dei vincoli che permettano al layout della tua applicazioni di adattarsi a tutti i tipi di dispositivi Apple.

Dato che ho già parlato di Auto Layout in questi 2 tutorial -> Introduzione all’Auto Layout in Xcode 6 e Impostare un auto layout in Xcode 6, base, ti voglio far vedere come risolverli in maniera veloce senza dover pensare a quali vincoli aggiungere.

Seleziona la label, poi scendi in basso dove ci sono i bottoni dell’Auto Layout e apri il menu Resolve Auto Layout Issues e infine clicca su Add Missing Constraints:

resolve auto layout issues

In questo modo Xcode pensa a creare dei vincoli che seguano la dislocazione che gli hai dato nello storyboard. Stessa identica operazione, adesso, devi farla per la tool bar.

Avvia l’app! dovresti vedere il layout come lo hai correttamente creato nello storyboard.

NSTimer in Swift, la creazione di un cronometro

Adesso devi interfacciare i bottoni con la grafica. Se non ti ricordi come si fa, l’ho spiegato qui.

Apri l’Assistant Editor e crea 1 IBOutlet per la Label e 2 IBAction, una per il primo bottone e una per l’altro. Il risultato dovrebbe essere questo:

Sempre dal file ViewController.swift, aggiungi sotto la definizione di classe il seguente codice:

In questo modo la variabile “timer” sarà quella delegata alla gestione del cronometro o meglio timer della tua applicazione.

Ma cos’è un NSTimer? 

Un NSTimer è un oggetto dell’omonima classe che serve a gestire “timer objects” o più semplicemente timers. Un timer ha la capacità di seguire l’andamento temporale della tua applicazione scandendo il tempo reale a cui sei normalmente abituato. In pratica, quando viene istanziato, si comporta come le lancette di un orologio: parte da un certo istante X (che per convenzione è il tempo 0) e inizia a “muoversi” (ovvero compiere operazioni) ad ogni tic del timer.

Grazie a questa capacità che ha l’NSTimer, puoi, oltre al semplice cronometro, creare degli eventi che partono o muoiono ad un determinato istante di tempo. Mi spiego meglio!

Se vuoi che un alert view o notifica push venga visualizzato dopo 10 minuti, oppure vuoi controllare periodicamente i dati inseriti o se ti sono arrivate nuove email, non hai altro modo per farlo se non quello di avere un oggetto che esegua delle operazioni sono ad un determinato X temporale.

Un timer, inoltre, ha la capacità di ripetere una determinata azione ad un intervallo regolare definito dall’utente. Ad esempio, se vuoi verificare la presenza di un nuovo messaggio nella casella di posta ogni 10 minuti, non ti basta altro che creare un timer, associargli una funzione (vedrai come si fa) che possa avviarsi allo scoccare del decimo minuto, mettersi in pausa e poi riavviarsi nuovamente allo scoccare del 10 minuto successivo.

Un po’ come se avessi una clessidra che esegue delle operazioni solo quando tutta la sabbia è scesa giù (cioè dopo un X di tempo) e con la possibilità di ribaltarsi per riattivare lo scorrere della sabbia.

gestione del tempoAvviare un Timer e gestire lo scorrere del tempo

Per avviare un timer bisogna istanziarlo utilizzando un particolare metodo chiamato scheduledTimerWithTimeInterval. Dentro il metodo startTimer_Clicked (che sarebbe la mia IBAction per il bottone Play) inserisci il seguente codice:

Quello che fa la funzione non è altro che assegnare alla variabile, definita poco fa, un timer con delle particolari caratteristiche. Il metodo con cui viene creato il timer si chiama scheduledTimerWithTimeInterval e vuole settati 5 parametri:

  1. Il primo è l’intervallo di tempo con cui il timer deve scandire il tempo (ogni quanto tempo la clessidra deve girarsi). Se il valore è:
    <= 0 scegli il più piccolo degli intervalli permessi impostando 0.1 secondi come default value.
     = 1, equivale a un timer che scandisce il tempo secondo per secondo.
    un valore a piacere sempre maggiore di 0.
  2. Il secondo è il target. Ovvero colui a cui si vuole mandare un messaggio per avvisare che il timer è partito. Se non c’è un target in particolare è l’oggetto stesso ad essere il target.
  3. Il selector è la funzione da schedulare, ovvero la funzione che viene startata allo scoccare dell’intervallo.
  4. Le informazioni dell’utente per il timer (non si usa spesso ed è sempre nil).
  5. repeats, è un boolean che indica se deve o non deve ripetere il ciclo di vita dopo che è finito l’intervallo di tempo (devo o non devo girare la clessidra quando la sabbia ha finito di scorrere?).

In pratica l’NSTimer non fa altro che invocare una funzione, definita nel selector, ad intervalli regolari e il tutto ovviamente se è impostato su true il parametro repeats.

La funzione per la gestione del cronometro

Sotto la definizione del timer, aggiungi due variabili che serviranno a gestire i secondi e i millisecondi del cronometro:

Il passo successivo è quello che riguarda la creazione della funzione per l’aggiornamento dei valori della label. Infatti la label deve mostrare i secondi e i millisecondi come se fosse un vero e proprio cronometro.

Aggiungi la seguente funzione sotto il metodo viewDidLoad:

La funzioneTimer, che deve avere lo stesso nome del selector dell’NSTimer, non fa altro che mostrare nella timeLabel.text il valore dei secondi e dei centesimi di secondo.

Dato che la funzione viene richiamata con un intervallo di 0.1 secondi, ho dovuto escogitare un trucchetto per poter mostrare correttamente i valori nella label. Se ci fai la caso, la variabile centesimiDiSecondo, è un Intero perché non voglio che venga mostrato a schermo come Double e quindi nella forma 0.x.

Per questo motivo ho dovuto convertirla a Int e prima moltiplicare il suo valore per 10, in questo modo 0.1 * 10  = 1 e i centesimi di secondo vengono aggiornati di 1 invece che di 0.1. In questo modo, dato che la funzione viene richiamata ogni 0.1 secondi, i centesimiDiSecondo verranno sempre aggiornati ogni 0.1 ma verranno visualizzati come numeri interi.

Poi, ogni volta che la somma dei centesimi di secondo raggiunge 10, incrementa i secondi e resetta a 0 i centesimi.

Mettere in pausa/fermare l’esecuzione di un timer

Lo stop di un timer è semplicissimo! basta invocare la funzione invalidate() che ne arresta l’esecuzione. Quindi, all’interno dell’IBAction pauseTimer_Clicked (quella relativa al bottone di pausa) inserisci il seguente codice:

Il principio è abbastanza semplice, devi ricordarti che il timer far partire una funzione, la ripete costantemente a intervalli regolari e che l’invalidate non distrugge i dati creati dalla funzione, bensì toglie dalla lista “delle cose in esecuzione dell’applicazione” il timer.

test Tutorial NSTimer in Swift, creare applicazione cronometro

Conclusione e Download del progetto

Nel prossimo tutorial inserirò le funzionalità del core data per gestire una classifica dei tempi di un utente e la trasposizione di questi dati in una tabella.

Se hai avuto dei problemi con il tuo progetto, oppure vuoi vedere il bottone per il reset del timer, scarica quello fatto da me:

[sociallocker][wpdm_package id=’2306′][/sociallocker]

Buona Programmazione!

Start typing and press Enter to search

Tutorial Alert View e Action Sheets con il linguaggio SwiftIntroduzione al CloudKit in iOS e Swift