In iOS learning process, sometimes need to maintain user data, such as login information, user settings, etc., this time need to learn data persistence, this section of the main learning iOS data persistence related knowledge.
There are four ways to persist data:
1). Write P List file ( attribute list )
2). Preference Settings
3). Archive (Nskeyedarchiver)
4). NSData
The following examples illustrate four ways of application and usage.
1. Writing the plist file (attribute list)
1.1 plist What data can be stored
The attribute list is an XML-formatted file that expands to the name plist
If the object is NSString, Nsdictionary, Nsarray, NSData, NSNumber, and so on, you can use the writetofile:atomically: method to write the object directly to the property list file.
Since the root of the plist file is only two types of array and dictionary, it is best to keep only the data of their corresponding data type.
For example, when you store a string type of data, the type is empty.
1.2 How to store
#pragma mark-store data-(ibaction) Btnsavedata_click: (UIButton *) sender{nsstring *str = @ "Hello"; NSString *filepath = [Nssearchpathfordirectoriesindomains (nsdocumentdirectory, Nsuserdomainmask, YES) [0] stringbyappendingpathcomponent:@ "Test_str.plist"]; BOOL result = [str writetofile:filepath atomically:yes encoding:nsutf8stringencoding Error:nil]; if (result) {NSLog (@ "store data successfully"); } else {NSLog (@) failed to store data! "); }}
The results of the program run as follows:
Auto-generated files:
Note: plist cannot store custom object types!
<span style= "color: #000000;" > #pragma mark-store data-(ibaction) Btnsavedata_click: (UIButton *) sender{//file's Shahe path nsstring *filepath = [NSSEARCHPA Thfordirectoriesindomains (NSDocumentDirectory, Nsuserdomainmask, YES) [0] stringbyappendingpathcomponent:@ "test_ Obj.plist "]; Create student Object Cystudent *stu = [[Cystudent alloc]init]; Stu.name = @ "Zhangsan"; Stu.age = 18; Nsarray *arrtmp = @[stu]; BOOL result = [arrtmp writetofile:filepath atomically:yes]; if (result) {NSLog (@ "store data successfully"); } else {NSLog (@) failed to store data! "); }}</span>
The results of the program run as follows:
1.3 plist file storage and reading process
2. Preference settings
2.1 Usage Scenarios
Many iOS apps support preferences such as saving usernames, passwords, font size, and more, and iOS offers a standard set of solutions to add preferences to your app
Each app has a Nsuserdefaults instance that accesses preferences. For example, save the user name, font size, and whether to log in automatically.
2.2 How to use
Save data after successful login:
[[Nsuserdefaults standarduserdefaults]setobject:self.txtaccount.text forkey:@ "account"]; [[Nsuserdefaults standarduserdefaults]setobject:self.txtpwd.text forkey:@ "pwd"]; [[Nsuserdefaults standarduserdefaults]setbool:self.swchrememberpwd.on forkey:@ "Isrememberpwd"]; [[Nsuserdefaults standarduserdefaults]setbool:self.swchautologin.on forkey:@ "Isautologin"];
Read data when you log on again:
Get data from Preferences
Self.txtAccount.text = [[Nsuserdefaults standarduserdefaults]objectforkey:@ "Account"]; Self.swchAutoLogin.on = [[Nsuserdefaults standarduserdefaults]boolforkey:@ "Isautologin"]; Self.swchRememberPWD.on = [[Nsuserdefaults standarduserdefaults]boolforkey:@ "Isrememberpwd"]; Self.txtPWD.text = [[Nsuserdefaults standarduserdefaults]objectforkey:@ "pwd"];
Note: When setting the data, Userdefaults does not write immediately, but instead writes the cached data to the local disk according to the timestamp. So after calling the set method, it is possible that the data has not yet been written to the disk application to terminate. The above problem can be forced by calling the Synchornize method to write
[Defaults synchornize];
3. Archive (Nskeyedarchiver)
3.1 Use Cases
If the object is NSString, Nsdictionary, Nsarray, NSData, NSNumber and other types, you can archive and restore directly with Nskeyedarchiver
Not all objects can be archived directly in this way, only objects that comply with the Nscoding protocol can
There are 2 ways to nscoding a protocol:
1) Encodewithcoder:
This method is called every time the object is archived. In this method, you typically specify how to archive each instance variable in an object, and you can use the Encodeobject:forkey: method to archive instance variables
2) Initwithcoder:
This method is called every time the object is recovered (decoded) from the file. In this method, you typically specify how to decode the data in a file as an instance variable of an object, and you can use the Decodeobject:forkey method to decode the instance variable
3.2 How to use
1> Custom entity Classes
@interface cycontact:nsobject /** name * /@property (nonatomic,copy) nsstring *name; /** Telephone * /@property (nonatomic,copy) nsstring *phone; @end
2> implementation of Nscoding protocol method
#pragma mark-nscoding protocol method/* Encodes the receiverusing a given archiver via a given AR The chiver encodes the message receiver. The class terminal Encodewithcoder method is called when a encodeobject message is received. */-(void) Encodewithcoder: (Nscoder *) Acoder {[Acoder encodeobject:_name forkey:cynamekey]; [Acoder Encodeobject:_phone Forkey:cyphonekey]; }/* Returns an objectinitialized from the data in a given unarchiver. (required) Returns an initialization object from the data of a given unarchiver. */-(ID) Initwithcoder: (Nscoder *) Adecoder {if (self = [super init]) {_name = [Adecoder decode Objectforkey:cynamekey]; _phone = [Adecoder Decodeobjectforkey:cyphonekey]; } return self; }/* Returnsa new instance that's a copy of the receiver returns a newly copied instance of the message receiver. */-(ID) Copywithzone: (Nszone *) Zone {cycontact *copy = [[[Self class] allocwithzone:zone] init]; Copy.name = [Self.name copywithzone:zone]; Copy.phone = Self.phone; return copy; }
3> Archive
[Nskeyedarchiver archiveRootObject:self.contacts Tofile:cyfilepath];
4> Access
Self.contacts = [Nskeyedunarchiver Unarchiveobjectwithfile:cyfilepath];
5>, watch out.
If the parent class also complies with the Nscoding protocol, please note that:
? You should add a "super Encodewithcode:encode" to the Encodewithcoder: method to ensure that inherited instance variables can also be encoded, which can also be archived
? You should add a self = [super Initwithcoder:decoder] in the Initwithcoder: method to ensure that inherited instance variables can also be decoded, which can also be restored
4. NSData
4.1 Use Cases
Use the Archiverootobject:tofile: method to write an object directly to a file, but sometimes you might want to write multiple objects to the same file, then use NSData to archive the object
NSData can provide temporary storage for some data for subsequent writing to a file, or for storing the contents of a file read from disk. Variable data spaces can be created using [Nsmutabledata data]
NOTE: A black arrow indicates that an object is archived to a file, and a red arrow indicates that the object is recovered from the file
4.2 How to use
#pragma mark-store data-(ibaction) Btnsavedata_click: (UIButton *) sender{ //nsdata-archive 2 person objects into the same file & nbsp Instantiating objects cystudent *stu1 = [cystudent studentwithname:@ "Zhangsan" age:18]; cystudent *stu2 = [CY Student studentwithname:@ "Lisi" age:20]; //New variable data area nsmutabledata *data = [Nsmutabledata data ]; //Connect the data area to a Nskeyedarchiver object Nskeyedarchiver *archiver = [[Nskeyedarchiver alloc] initforwritingwithmutabledata:data]; //Start archive objects, archived data will be stored in nsmutabledata [archiver ENCODEOBJECT:STU1 forkey:@ "STU1"]; [archiver encodeobject:stu2 forkey:@ "STU2"]; //Archive Complete ( Be sure to call this method) [archiver finishencoding]; NSString *path = [Nssearchpathfordirectoriesindomains ( NSDocumentDirectory, Nsuserdomainmask, YES) [0] stringbyappendingpathcomponent:@ "datas.data"]; // Write archived data to file BOOL result = [Data Writetofile:path atomically:yes]; if (result) { NSLog (@ "Storage data Success"); } El se { NSLog (@ "failed to store data! "); } #pragma mark-read data-(ibaction) Btnreaddata_click: (UIButton *) sender{ // nsdata-Recover 2 person objects from the same file //Read data from file NSString *path = [Nssearchpathfordirectoriesindomains ( NSDocumentDirectory, Nsuserdomainmask, YES) [0] stringbyappendingpathcomponent:@ "datas.data"]; NSData * data = [NSData datawithcontentsoffile:path]; //data, resolves to a Nskeyedunarchiver object Nskeyedunarchiver *unarchiver = [[Nskeyedunarchiver alloc] initforreadingwithdata:data]; CYStudent *STU1 = [Unarchiver decodeobjectforkey:@ "STU1"]; cystudent *stu2 = [Unarchiver decodeobjectforkey:@ "STU2"]; //recovery complete [unarchiver finishdecoding]; NSLog (@ "%@", STU1); NSLog (@ "%@" , STU2);} #pragma mark-useArchive for deep copy-(ibaction) Btndeepcopy_click: (UIButton *) sender{ //For example deep copy of a Cystudent object // Temporary storage STU1 Data cystudent *STU1 = [cystudent studentwithname:@ "Zhangsan" age:18]; nsdata *data = [NS] Keyedarchiver archiveddatawithrootobject:stu1]; //parse data to generate a new person object cystudent *STU2 = [ Nskeyedunarchiver unarchiveobjectwithdata:data]; //Print memory address NSLOG (@ "stu1:%p", STU1) respectively; stu1:0x7bdb32b0 NSLog (@ "stu2:%p", STU2); STU2:0X7BDB6B80}
iOS Learning notes-data persistence