Hur du sparar data i din application med NSKeyedArchiver

Andreas Claesson

När du utvecklar en applikation, för vilken plattform som helst, så är det väldigt vanligt att du behöver spara data på ett eller annat sätt. Antingen lokalt eller på en server. Den här artikeln berskriver hur du ska gå tillväga för att spara din data lokalt, i iOS, med hjälp utav NSKeyedArchiver.

När man jobbar med datatyper som NSData, NSString, integer etc. så kan man enkelt spara den datan i en property list eller i NSUserDefaults. Men ganska ofta så har man en mer kompliserad datastruktur som består av egenskapade objekt som inte går att spara ner i en property list eller i NSUserDefaults. Då kan man ta hjälp av NSKeyedArchiver.

I det här exemplet har vi en klass som heter TextAreas som innehåller tre NSString objekt, Text_ID, Text_Version och Text_Value.

import "TextArea.h" 

@implementation TextArea

@synthesize Text_ID;
@synthesize Text_Version;
@synthesize Text_Value;

Vår applikations delegate äger en NSMutableArray som innehåller x antal TextAreas och nu vill vi spara den här arrayen med data.  Här är koden för hur vi lyckas med det:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self.textAreas];
[defaults setObject:data forKey:@"TextAreas"];
[defaults synchronize];

Koden ovan gör följande:

  • Hämtar en referens till ”User Defaults” för den här applikationen.
  • *Kodar NSMutableArrayen  som innehåller TextAreas objekten.
  • Lagrar det som en viktig värde-par med en nyckel ”TextAreas”
  • Anropar syncroniserings metoden som tvingar datan att skrivas till disk, annars skulle operationen hamna i kö och inte köras förens operativet tyckte att det passade.

Du kanske märkte * på punkten om kodning av våra TextAreas. För att kunna ”koda” vår data så måste vi implementera två metoder för att vara kompatibelt med NSCoding protokollet så att vår data KAN bli arkiverat.

- (id)initWithCoder:(NSCoder *)coder
{
    if ((self = [super init]) == nil) {
        return self;
    }

    [coder decodeValueOfObjCType:@encode(NSString *) at:&Text_ID];
    [coder decodeValueOfObjCType:@encode(NSString *) at:&Text_Version];
    [coder decodeValueOfObjCType:@encode(NSString *) at:&Text_Value];

    return self;
}

- (void)encodeWithCoder:(NSCoder *)coder
{
    [coder encodeValueOfObjCType:@encode(NSString *) at:&Text_ID];
    [coder encodeValueOfObjCType:@encode(NSString *) at:&Text_Version];
    [coder encodeValueOfObjCType:@encode(NSString *) at:&Text_Value];
}

encodeWithCoder funktionen kommer att anropas när den här funktionen körs:

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self.textAreas];

Som du kan se så är dessa funktionerna ganska grundläggande – eftersom vår klass bara har tre variabler, Text_ID, Text_Version och Text_Value, så kodar och avkodar vi bara tre saker. Det finns funktioner för nästan alla variabeltyper,  encode och decode används för datatyper som  float, int, double och bool och encodeObject, decodeObject för allt annat (NSString, NSNumber, eller någon av dina egna klasser).

Hittills har vi sparat vår data, men var och hur ska vi ladda den? Enkelt – i funktionen applicationDidFinishLaunching i din applikations delegat, lägger du till den här koden:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [defaults objectForKey:@"TextAreas"];
self.textAreas = (NSMutableArray *)[NSKeyedUnarchiver unarchiveObjectWithData:data];

Den här koden är snarlik koden vi implementerade för att spara vår data, den ända skillnaden är att vi hämtar ett NSData objekt istället för att spara det och använder NSKeyedUnarchiver istället för NSKeyedArchiver. När unarchiveObjectWithData anropas så anropas funktionen initWithCoder i TextArea klassen som vi skapade och vips så har du laddat din sparade data.

Lycka Till!

Taggar: , , , , , ,

Skriv en kommentar