Skip to main content

Creare un Dao per i dati utente con Swift

In un articolo precedente abbiamo visto che NSUserDefaults è la soluzione perfetta per il salvataggio dei dati dell’utente della vostra app. Tuttavia accedere a NSUserDefaults direttamente da vari punti della vostra app vi carica della responsabilità che le letture e le scritture siano effettivamente consistenti. Ad esempio basta scrivere erroneamente il nome della key associata al valore che state gestendo per produrre degli scenari non coerenti.

Può sembrare un errore facile da evitare ma quando l’app diventa complessa con varie coppie chiave valore che vengono salvate in diversi punti del codice, è facile commettere un errore. E purtroppo si tratta di un’ inconsistenza che il compilatore non può controllare essendo le chiavi delle stringhe.

Una prima soluzione potrebbe sembrare quella di creare delle costanti  (di tipo String) per accedere ai metodi di NSUserDefaults passando sempre una costante invece di digitare liberamente la chiave. Tuttavia stiamo esponendo al codice dell’intera app dei dettagli che sarebbe meglio racchiudere in un oggetto unico.

Un Dao per NSUserDefaults

Un Dao (Data Access Object) è un oggetto che definisce un’astrazione per l’accesso ad alcuni tipi di database o altri meccanismi di persistenza. E’ generalmente associato al mondo Java EE ma si adatta perfettamente alla situazione descritta nel paragrafo precedente. Infatti fornisce uno strumento per l’accesso (lettura e scrittura) dei dati dell’app ad alto livello.

Col tempo ho imparato che costruire un mio Dao (le cui funzionalità sono specifiche per l’app) intorno ad alcuni oggetti di iOS che forniscono accesso ai dati (per GameCenter, la localizzazione, etc…) rende lo sviluppo molto più robusto.

Vediamo come realizzarlo.

Vogliamo che questa classe sia un Singleton, cioè vogliamo che durante l’esecuzione dell’app esista al massimo un’istanza di questa classe in memoria. Questo ci permette di risparmiare qualcosa sul footprint (quantità di risorse richieste) dell’app.

Per farlo nascondiamo l’initializer di default rendendolo privato (riga #2) e creiamo una costante statica sharedInstance che useremo per ottenere l’unica istanza esistente della nostra classe.

La riga #4 crea una propery privata costante contenente l’istanza di NSUserDefaults che useremo internamente per accedere ai dati.

A questo punto iniziamo ad aggiungere una funzionalità al nostro Dao, vogliamo gestire il numero di punti che l’utente ha realizzato. Questa situazione è perfetta per utilizzare un concetto di Swift chiamato Computed Property.

Computed Property

Una Computed Property, a differenza di una classica Stored Property, fornisce un getter e un setter opzionale per recuperare e scrivere il valore. Implementando questo getter e setter potete definire una logica per leggere e salvare il valore.

Abbiamo appena creato la Computed Propery points di tipo Int. Come vedete si appoggia a storage (cioè a NSUserDefaults) per recuperare e salvare il valore.

La prima versione del Dao è completa, eccome come si usa.

L’istruzione alla riga #1 chiama indirettamente il setter di points mentre quella alla riga #3 chiama indirettamente il getter.

Gestione di oggetti non primitivi

Un altro compito svolto da un Dao è quello di fornire all’esterno un’interfaccia per la gestione di oggetti di alto livello, nascondendo i dettagli implementativi relativi a come questi oggetti vengono poi effettivamente letti e scritti.

Riprendiamo l’oggetto Game creato in un post precedente.

Si tratta di un oggetto conforme al protocollo NSCoding quindi in grado di trasformarsi in NSData e viceversa.

Aggiungiamo la Computed Property myOwnGame a UserDataDao.

In questo modo abbiamo nascosto all’interno del Dao la logica per trasformare l’oggetto di tipo Game in NSData durante il salvataggio e viceversa durante la lettura.

Adesso salvare e recuperare un oggetto Game è diventato molto più veloce.

Conclusione

Il Dao per la gestione di NSUserDefaults, secondo il mio punto di vista, dovrebbe diventare l’unico mezzo di accesso a NSUserDefaults. Resistete alla tentazione di accedere direttamente in altri punti del codice e otterrete una struttura molto più robusta e di facile manutenzione.

Trainer • Developer • Writer

Luca Angeletti

Trainer • Developer • Writer

Lascia un commento

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