Come salvare un oggetto per poi rileggerlo in seguito
Objective-C
Una funzionalità molto utile è quella di poter creare degli oggetti e poterli salvare su disco.
Ad esempio potremmo avere bisogno di salvare una cache o delle impostazioni molto complesse e poterle riutilizzare in seguito.
Objective-C ci aiuta anche in questo con delle classi molto utili e semplici da utilizzare.
Il concetto di base è semplice, dobbiamo trasformare il nostro oggetto in Dati (NSData) e poi salvarlo. Ma se proviamo a farlo ad un nostro oggetto probabilmente riceveremo qualche errore.
La cosa necessaria infatti è che l’oggetto che vogliamo salvare sia conforme al protocollo NSCoding.
Vediamo come utilizzarlo e come poter permettere il salvataggio e il recupero di questi dati.
Creiamo una classe di esempio, sottoclasse di NSObject e con il nome “SampleObject”. Rendiamola conforme al protocollo NSCoding e dichiariamo tre proprietà :
@interface SampleObject : NSObject @property (nonatomic, strong) NSString* name; @property (nonatomic, strong) NSDate* birthDate; @property (nonatomic, readwrite) NSInteger age; @end
A questo punto però dobbiamo implementare i due metodi necessari affinché il protocollo permetta di fare il lavoro in modo corretto.
- (id)initWithCoder:(NSCoder *)aDecoder { if ((self = [super init])) { _name = [aDecoder decodeObjectForKey:@"name"]; _birthDate = [aDecoder decodeObjectForKey:@"birthDate"]; _age = [aDecoder decodeIntegerForKey:@"age"]; } return self; } - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:_name forKey:@"name"]; [aCoder encodeObject:_birthDate forKey:@"birthDate"]; [aCoder encodeInteger:_age forKey:@"age"]; }
Quello che avviene è la codificazione e la decodificazione delle variabili all’interno dell’oggetto quando NSCoding lo richiede.
In particolare c’è metodo di inizializzazione e uno che viene richiamato nel momento in cui cercheremo di codificare l’oggetto.
Adesso torniamo al nostro ViewController ed andiamo ad inizializzare il nostro oggetto. Assegnamo le proprietà :
SampleObject* object = [SampleObject new]; object.name = @"Andrea"; object.birthDate = [NSDate date]; object.age = 28;
A questo punto l’oggetto è completamente funzionante infatti possiamo farci stampare dal debugger i suoi dati:
Object name Andrea, birthDate 2014-10-29 16:43:26 +0000, age 28
Ora proviamo a salvarlo in NSUserDefaults.
Ciò che dobbiamo fare quindi è trasformarlo in NSData e per fare questi ci viene in aiuto la classe NSKeyedArchiver:
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults]; NSData* dataObject = [NSKeyedArchiver archivedDataWithRootObject:object]; [userDefaults setObject:dataObject forKey:@"object"]; [userDefaults synchronize];
Adesso è quindi salvato all’interno di NSUserDefault dell’utente.
Possiamo ricrearlo quando vogliamo ed anche qui ci facciamo aiutare da un altra classe di Objective-C chiamata NSKeyedUnarchiver:
NSData* restoredDataObject = [userDefaults objectForKey:@"object"]; SampleObject* restoredObject = [NSKeyedUnarchiver unarchiveObjectWithData:restoredDataObject];
Et-Voilà , ecco il nostro oggetto esattamente come prima e il debugger sarà felice di dirci quali sono i suoi dati:
restoredObject name Andrea, birthDate 2014-10-29 16:43:26 +0000, age 28
La procedura è un po’ macchinosa e non rimane facilmente in mente, per non parlare di quando l’oggetto è complesso.. risulterà sicuramente noiosa ma le potenzialità sono infinite.