Salvare le preferenze utente in iOS e macOS con Swift

Quando creiamo un’applicazione, spesso desideriamo salvare le preferenze dell’utente per riutilizzarle in esecuzioni successive. Ad esempio, possiamo voler salvare quali notifiche l’utente desidera ricevere, lo schema di colori e altre personalizzazioni. Alcune volte, può essere necessario salvare delle preferenze nascoste (o implicite).

Il framework Foundation rende disponibile la classe UserDefaults. Questa classe permette di accedere ad un “database” nel quale è possibile salvare delle coppie chiave-valore  che vengono persistite nelle diverse esecuzioni dell’app.

La classe permette un accesso semplice e di alto livello a queste preferenze. I valori vengono anche memorizzati un cache applicativa, per evitare di leggere continuamente dal database.

È possibile memorizzare e leggere tipi di date base come booleani, numerici, stringhe e url, ma anche array, dictionary e dati complessi.

Attenzione: i dati scritti con UserDefaults vengono automaticamente caricati all’avvio dell’app. Questo significa che in UserDefaults vanno salvati solo pochi dati strettamente necessari, per evitare di rallentare il caricamento dell’app.

Per iniziare è necessario richiedere una istanza della classe:

let uesrPrefs = UserDefaults.standard

Se vogliamo scrivere dei dati, possiamo usare il metodo set():

userPrefs.set(25, forKey: "Age")
userPrefs.set(true, forKey: "UseTouchID")
userPrefs.set(Double.pi, forKey: "Pi")

Per ogni dato, definiamo una chiave univoca attraverso la quale possiamo referenziarlo in seguito.

Il metodo set() può essere usato anche per salvare stringhe, array, date, … Ricordiamoci che in Swift le stringhe, gli array, i dictionary e le date sono delle strutture, non delle classi.

userPrefs.set("Senior Software Specialist", forKey: "Title")
userPrefs.set(Date(), forKey: "LastRun")
//lo stesso per array e dictionary
userPrefs.set(["Hello", "World"], forKey: "AnArray")
userPrefs.set(["Name": "Mircha Emanuel", "Country": "IT"], forKey: "ADict")

Ok, abbiamo salvato i dati. Adesso come li leggiamo?

UserDefaults offre un metodo di lettura per ogni tipo di dato. Il metodo ritorna o il valore corrispondente alla chiave, o un valore che indica che la lettura non è andata a buon fine. La documentazione indica il valore di ritorno per i vari metodi di lettura messi a disposizione:

userPrefs.integer(forKey: "Age") //ritorna un intero se la chiave esiste, 0 altrimenti. È lo stesso per qualsiasi altro valore numerico.
userPrefs.bool(forKey: "UseTouchID") //ritorna un boolean se il valore esiste, false altrimenti (?!?)
userPrefs.object(forKey: "anObject") //ritorna Any? e consente poi un cast condizionale al tipo di dato che ci si aspetta
userPrefs.string(forKey: "aString") //ritorna la stringa o nil se il valore non esiste o non si tratta di un tipo string
//...

Quando utilizziamo il metodo object() e ci viene restituito Any? possiamo utilizzare l’operatore ?? per ottenere il valore che cerchiamo. L’operatore ?? fa due cose contemporaneamente: se l’oggetto a sinistra è Optional e esiste, lo “unwrappa” (permettetemi questa parola :D) in un non-optional; se non esiste, usa il valore a destra.

Questo significa che possiamo utilizzare l’operatore as??? per ritornare l’oggetto che ci aspettiamo o un valore di default se l’oggetto letto è null.

Ad esempio:

userPrefs.object("ForegroundColor") as? UIColor ?? UIColor.black

In questo caso andiamo a leggere la chiave ForegroundColor cercando di ottenere un UIColor, se la lettura dovesse tornare nil utilizziamo il valore di default UIColor.black.

Spero di avervi fornito una utile introduzione a come salvare le preferenze utente della vostra app. C’è ancora molto da dire su UserDefaults. Ad esempio la sincronizzazione, persistentDomain, volatileDomain, … Se avete fretta e non potete aspettare il prossimo articolo, potete leggere la documentazione ufficiale:

https://developer.apple.com/documentation/foundation/userdefaults

 

Lascia un commento

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