Archive NSKeyedArchiver and iosnskeyedarchiver for iOS persistent data storage

Source: Internet
Author: User

Archive NSKeyedArchiver and iosnskeyedarchiver for iOS persistent data storage

Archive is a common method for storing files. Almost all types of objects can be archived and stored (in fact, it is a form of file storage ), I collected some information on the Internet and summarized it as follows based on my experience.

1. Use archiveRootObject for simple Archiving

 

NSKeyedArichiver is used for archiving and NSKeyedUnarchiver for archiving. This method serializes and deserializes data before writing or reading data.

Archive:

// 1. Obtain the file path

NSString * docPath = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex: 0];

// 2. Add the stored file name

NSString * path = [docPath stringByAppendingPathComponent: @ "data. archiver"];

// 3. save an object to a file

BOOL flag = [NSKeyedArchiver archiveRootObject: @ "" toFile: path];

This method can archive strings, numbers, and so on. Of course, it can also archive NSArray and NSDictionary. The returned Flag indicates whether the archive is successful. YES indicates that the archive is successful, and NO indicates that the archive is failed.

File Transfer:

  

// 1. Obtain the file path

NSString * docPath = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex: 0];

NSString * path = [docPath stringByAppendingPathComponent: @ "person. yangyang"]; NSLog (@ "path = % @", path );

// 2. Read objects from files

[NSKeyedUnarchiver unarchiveObjectWithFile: path]

 

Use NSKeyedUnarchiver for file (deserialization ).

This archive method has one disadvantage: Only one object can be archived into one file. How can we archive multiple objects?

 

2. Archiving multiple objects

The same uses NSKeyedArchiver for archiving. The difference is that multiple objects are archived at the same time. Here we put a CGPoint, string, and INTEGER (of course, many types are acceptable, for example, UIImage, float, etc.), use the encodeXXX Method for archiving, and write the file through the writeToFile method.

Archive: Write Data

// Prepare the data CGPoint point = CGPointMake (1.0, 2.0); NSString * info = @ "coordinate origin"; NSInteger value = 10; NSString * docPath = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex: 0]; NSString * multiHomePath = [docPath stringByAppendingPathComponent: @ "multi. archiver "]; NSMutableData * data = [[NSMutableData alloc] init]; NSKeyedArchiver * archvier = [[NSKeyedArchiver alloc] initForWritingWithMutableData: data]; // archive multiple objects [archvier encodeCGPoint: point forKey: @ "kPoint"]; [archvier encodeObject: info forKey: @ "kInfo"]; [archvier encodeInteger: value forKey: @ "kValue"]; [archvier finishEncoding]; [data writeToFile: multiHomePath atomically: YES];

 

 

File Link: obtain data from the path to construct an NSKeyedUnarchiver instance, and use the decodeXXXForKey method to obtain objects in the file.

  NSMutableData *dataR = [[NSMutableData alloc] initWithContentsOfFile:multiHomePath];    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:dateR];    CGPoint pointR = [unarchiver decodeCGPointForKey:@"kPoint"];    NSString *infoR = [unarchiver decodeObjectForKey:@"kInfo"];    NSInteger valueR = [unarchiver decodeIntegerForKey:@"kValue"];    [unarchiver finishDecoding];    NSLog(@"%f,%f,%@,%d",pointR.x,pointR.y,infoR,valueR);  

 

It can be seen that it is quite convenient to archive multiple objects. Another problem occurs here. The objects here are all basic data types, how can I archive the instance objects generated by my own defined classes?

3. Archiving custom objects

A custom object has a wide range of applications, because it corresponds to the Model layer in MVC, that is, the entity class. In the program, we will define a lot of entity in the Model layer, such as User and Teacher ..

Therefore, archiving custom objects is much more important, because in many cases, we need to save the data after the Home key and reload the data when the program recovers. archive is a good choice.

First, we need to customize an object class.

// YYViewController. m # import "YYViewController. h "# import" YYPerson. h "@ interface YYViewController ()-(IBAction) saveBtnOnclick :( id) sender;-(IBAction) readBtnOnclick :( id) sender; @ end @ implementation YYViewController-(void) viewDidLoad {[super viewDidLoad];}-(IBAction) saveBtnOnclick :( id) sender {// 1. create object YYPerson * p = [[YYPerson alloc] init]; p. name = @ "circle"; p. age = 23; p. height = 1.7; // 2. obtain the file path NSString * docPath = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString * path = [docPath stringByAppendingPathComponent: @ "person. yangyang "]; NSLog (@" path = % @ ", path); // 3. save the custom object to the file [NSKeyedArchiver archiveRootObject: p toFile: path];}-(IBAction) readBtnOnclick :( id) sender {// 1. obtain the file path NSString * docPath = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString * path = [docPath stringByAppendingPathComponent: @ "person. yangyang "]; NSLog (@" path = % @ ", path); // 2. read the object YYPerson * p = [NSKeyedUnarchiver unarchiveObjectWithFile: path]; NSLog (@ "% @, % d, %. 1f ", p. name, p. age, p. height);} @ end

 

 

// YYPerson. h # import <Foundation/Foundation. h> // if you want to save a custom object to a file, you must implement the NSCoding Protocol @ interface YYPerson: NSObject <NSCoding> // name @ property (nonatomic, copy) NSString * name; // age @ property (nonatomic, assign) int age; // height @ property (nonatomic, assign) double height; @ end

 

// YYPerson. m # import "YYPerson. h "@ implementation YYPerson // this method is called when a custom object is saved to a file. // This method describes how to store the attributes of a custom object. // in this method, it is clear which attributes of the custom object are stored-(void) encodeWithCoder :( NSCoder *) ACO {NSLog (@ "called encodeWithCoder: Method"); [ACO encodeObject: self. name forKey: @ "name"]; [ecoder encodeInteger: self. age forKey: @ "age"]; [ecoder encodeDouble: self. height forKey: @ "height"];} // this method is called when an object is read from a file. // This method describes how to read the object stored in the file. // that is to say how to read the object in this method. read object-(id) initWithCoder :( NSCoder *) aDecoder {NSLog (@ "initWithCoder called: Method"); // note: in the constructor, you must first initialize the method of the parent class if (self = [super init]) {self. name = [aDecoder decodeObjectForKey: @ "name"]; self. age = [aDecoder decodeIntegerForKey: @ "age"]; self. height = [aDecoder decodeDoubleForKey: @ "height"];} return self;} @ end

 

Create a class for Local Data Storage Based on Archive as follows:

 

# Import <Foundation/Foundation. h> @ interface LocalArchiverManager: NSObject/** Singleton mode. Obtain the request management class * \ param: none * \ returns return: none */+ (LocalArchiverManager *) shareManagement; /** clear the local serialized file * \ param: none * \ returns return: none */-(void) clearArchiverData;/** save cache data * \ param obj: data Source * \ param key: interface name * \ returns none */-(void) saveDataArchiver :( id) obj andAPIKey :( NSString *) key; /** return to cache data * \ param obj: api key * \ returns id: returned data source */-(id) archiverQueryAPIKey :( NSString *) key; @ end

 

LocalArchiverManager. m file
# Import "LocalArchiverManager. h "static LocalArchiverManager * m_localArchiverMana; # define Document [attributes (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex: 0] # define ArchiverFile [Document attributes: @" Archiver "] @ interface LocalArchiverManager () @ property (nonatomic, retain) NSFileManager * fileManager; @ end @ implementation LocalArchiverManager + (Lo CalArchiverManager *) shareManagement {static dispatch_once_t onceTocken; dispatch_once (& onceTocken, ^ {m_localArchiverMana = [[LocalArchiverManager alloc] init] ;}); return response;}-(id) init {self = [super init]; if (self) {self. fileManager = [NSFileManager defaultManager];} return self ;}# pragma mark private methods-(BOOL) checkPathIsExist :( NSString *) path {return [_ fileManager fil EExistsAtPath: path isDirectory: nil];}-(void) createArchiverFile {if (! [Self checkPathIsExist: ArchiverFile]) {[self addNewFolder: ArchiverFile] ;}// create a directory. path is the directory path (including the directory name)-(void) addNewFolder :( NSString *) path {[_ fileManager createDirectoryAtPath: path withIntermediateDirectories: YES attributes: nil error: nil] ;}# pragma mark-# pragma mark public methods-(void) clearArchiverData {NSError * error; if ([m_fileManager removeItemAtPath: ArchiverFile error: & error]) {} else {DLOG (@" An error occurred while clearing the locally serialized file ....: % @ ", error) ;}}-(void) saveDataArchiver :( id) obj andAPIKey :( NSString *) key {NSMutableData * data = [[NSMutableData alloc] init]; NSKeyedArchiver * archiver = [[NSKeyedArchiver alloc] failed: data]; [archiver encodeObject: obj forKey: key]; [archiver finishEncoding]; [self createArchiverFile]; key = [key secret: @ "/" withString: @ "_"]; NS String * path = [ArchiverFile stringByAppendingPathComponent: [NSString stringWithFormat: @ "% @. text", key]; BOOL isSuc = [data writeToFile: path atomically: YES]; if (! IsSuc) {DLOG (@ "failed local serialization key ....: % @ ", key) ;}}-(id) archiverQueryAPIKey :( NSString *) key {NSString * str = [key stringByReplacingOccurrencesOfString: @"/"withString: @ "_"]; NSString * path = [ArchiverFile stringByAppendingPathComponent: [NSString stringWithFormat: @ "% @. text ", str]; NSMutableData * data = [[NSMutableData alloc] paths: path]; NSKeyedUnarchiver * unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData: data]; id content = [unarchiver decodeObjectForKey: key]; [unarchiver finishDecoding]; DLOG (@ "content .....: % @ ", content); return content ;}

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.