The usual way of using data storage for iOS
1.XML attribute list (plist) archive.
2.Preference (preference setting).
3.NSKeyedArchiver archiving.
4.sqlite3
5.Core Data
Apply Sandbox
Each iOS application has its own application sandbox (the application sandbox is the file system directory) that is isolated from other file systems. Applications must stay in their sandbox, and other applications cannot access the sandbox.
Emulator applies the root path of the sandbox in: (Apple is username, 6.0 is emulator version)
/users/apple/library/application Support/iphone simulator/6.0/applications
Or:
/users/User name/resource pool/application Support/iphone simulator/6.1/applications
Attention:
By default, the directory of the emulator is hidden, and to display it, you need to enter the following command at the Mac Terminal:
To display the Mac hidden files command:defaults write com.apple.finder AppleShowAllFiles YES
To hide a mac hidden file command:defaults write com.apple.finder AppleShowAllFiles NO
Applying sandbox structure analysis
Documents:
Saves the data that is generated by the application runtime that needs to be persisted, which is backed up by the itunes synchronization device. For example, game applications can save game archives in this directory.
Temp
Save the temporary data required by the application runtime, and then remove the appropriate files from the directory when it is finished. When the application is not running, the system may also purge files from that directory. The itunes Sync device does not back up the directory.
Library/caches:
Save the data that is generated by the application runtime that needs to be persisted, and the itunes synchronization device does not back up the directory. General storage is large and does not need to be backed up by unimportant data.
Library/preference:
Save all the preferences for the application, the iOS setting (settings) application will find the application settings information in the directory. The itunes sync device backs up the directory.
Common ways to get the sandbox directory to apply:
Sandbox Root Path
NSString *home = Nshomedirectory ();
Documents: (2 ways)
To splice the "Documents" string using the sandbox root directory:
NSString *home = Nshomedirectory ();
NSString *documents = [Home stringbyappendingpathcomponent:@ "Documents"];
Not recommended because the new version of the operating system may modify the directory name
Using the Nssearchpathfordirectoriesindomains function:
Nsuserdomainmask represents the
wave character "~"
nsarray *array = nssearchpathfordirectoriesindomains in the expanded path from the user folder ( Nsdocumentdirectory,nsuserdomainmask, NO);
In iOS, only one directory matches the parameters passed in, so there is only one element in the set
nsstring *documents = [array objectatindex:0];
Tmp:
NSString *tmp= nstemporarydirectory ();
Library/catches: (Two ways similar to documents)
1. Use the sandbox and catalogue to stitch the "catches" string.
2. Use the Nssearchpathfordirectoriesindomains function (change the first argument of the function to: nscachesdirectory).
Library/preference: Access the settings information in the directory through the Nsuserdefaults class.
The following is a detailed description of how data is stored in 5
Property List
A property list is an XML-formatted file that expands to be named Plist.
If the object is NSString, Nsdictionary, Nsarray, NSData, NSNumber, and so on, you can use: writetofile:atomiclly: Method to write the object directly into the property list file.
. Properties List-Archive nsdictionary
Archive a nsdictionary into a list of plist properties.
Encapsulate data into a dictionary
nsmutabledictionary *dict = [nsmutabledictionary dictionary];
[Dict setobject:@ "15013141314" forkey:@ "phone"];
[Dict setobject:@ "forkey:@"];
Persisting the dictionary to the documents/stu.plist file
[dict writetofile:path Atomically:yes];
. List of properties-Restore Nsdictionary
Read the property list to restore the Nsdictionary object
Reads the contents of the documents/stu.plist, instantiates nsdictionary
nsdictionary *dict = [Nsdictionary dictionarywithcontentsoffile: Path];
NSLog (@ "phone:%@", [dict objectforkey:@ "Phone"]);
NSLog (@ "age:%@", [Dict objectforkey:@ "Age"]);
Preference Settings (preference)
Many iOS apps support preferences such as saving user names, passwords, automatically logging in, and so on, and iOS offers a set of standard solutions to add preferences to applications.
Each application has an NSUserDefaults
instance that accesses the preference settings.
If you save the user name, font size, log in
Nsuserdefaults *defaults = [Nsuserdefaults standarduserdefaults];
[Defaults setobject:@ "Cat" forkey:@ "username"];
[Defaults setfloat:14.0f forkey:@ "Text_size"];
[Defaults setbool:yes forkey:@ "Auto_login"];
Read the Last saved settings
Nsuserdefaults *defaults = [Nsuserdefaults standarduserdefaults];
NSString *username = [Defaults stringforkey:@ "username"];
float TEXTSIZE = [Defaults floatforkey:@ "Text_size"];
BOOL autologin = [Defaults boolforkey:@ "Auto_login"];
Attention:
Userdefaults sets the data, instead of writing it immediately, the data in the cache is written to the local disk periodically based on the timestamp. So when the set method is invoked, the data may not have been written to the disk application and terminated. This problem occurs, and you can force a write by invoking the synchornize
method.
Nskeyedarchiver
If the object is NSString, Nsdictionary, Nsarray, NSData, NSNumber, and so on, it can be used directly: Nskeyedarchiver for archiving and recovery.
Not all objects can be archived directly in this way, only objects that adhere to the Nscoding protocol.
The Nscoding protocol has 2 methods:
. Encodewithcoder:
This method is called every time the object is archived. In this method, you specify how to archive each instance variable in the object. You can use the: encodeObject:forkey:
method to archive instance variables.
. Initwithcoder:
This method is called every time the object is recovered (decoded) from a file. In this method, you specify how to decode the data in the file as an object's instance variable, and you can use the decodeObject:forkey
method to decode the instance variable.
Archive a Nsarray object to documents/array.archive:
NSString *path = [NSString stringwithformat:@ "documents/array.archive"];
Nsarray *array = [Nsarray arraywithobjects:@ "a", @ "B", nil];
[Nskeyedarchiver Archiverootobject:array Tofile:path];
Recover (decode) Nsarray object
Nsarray *array = [Nskeyedunarchiver Unarchiveobjectwithfile:path];
nskeyedarchiver-Archive Person Object:
In Person.h:
@interface person:nsobject <NSCoding>
@property (nonatomic,copy) nsstring *name;
@property (nonatomic,assign) int age;
@property (nonatomic,assign) float height; @end
In PERSON.M:
@implementation person
-(void) Encodewithcoder: (nscoder*) encoder{
[encoder encodeObject:self.name forkey:@ "Name"];
[Encoder encodeInt:self.age forkey:@ "age"];
[Encoder encodeFloat:self.height forkey:@ "height"];
}
-(ID) Initwithcoder: (nscoder*) Decoder {
self.name= [decoder decodeobjectforkey:@ ' name '];
self.age= [Decoder decodeintforkey:@ "age"];
self.height= [Decoder decodefloatforkey:@ "height"];
return self;
}
Archive (encoded) person
*person = [[Person alloc] init];
Person.name = @ "JN";
Person.age =;
Person.height = 1.63f;
[Nskeyedarchiver Archiverootobject:person Tofile:path];
Restore (decode) person
*person = [Nskeyedunarchiver Unarchiveobjectwithfile:path];
@end
Nskeyedarchiver-Archive object's attention
If the parent class also complies with the Nscoding protocol, please note:
1. The Uencodewithcoder: method should be added to [super encodeWithCode:encode];
ensure that inherited instance variables can also be encoded, that is, they can also be archived.
2. It should be added in the Initwithcoder: method to self = [super initWithCoder:decoder];
ensure that inherited instance variables can also be decoded, which can also be recovered.
NSData
Using archiveRootObject:toFile:
methods you can write an object directly into a file, but sometimes you may want to write multiple objects to the same file, then use NSData to archive the object.
NSData can provide temporary storage space for some data for subsequent writing to files or for storing the contents of files read from disk. You can use [Nsmutabledata data] To create variable data spaces.
NSData Archive 2 person objects to the same file:
Archive:
Create a new variable data area
nsmutabledata *data = [Nsmutabledata data];
Connect the data area to a Nskeyedarchiver object
nskeyedarchiver *archiver = [[[Nskeyedarchiver Alloc] Initforwritingwithmutabledata:data] autorelease];
Starts archiving the object, and the archived data is stored in the Nsmutabledata
[archiver encodeobject:person1 forkey:@ "Person1"];
[Archiver encodeobject:person2 forkey:@ "Person2"];
Archive complete (make sure to call this method)
[Archiver finishencoding];
Writes archived data to the file
[data Writetofile:path Atomically:yes];
Recovery (decoding):
Reading data from a file
nsdata *data = [NSData Datawithcontentsoffile:path];
According to the data, parse into a Nskeyedunarchiver object
nskeyedunarchiver *unarchiver = [[Nskeyedunarchiver alloc] Initforreadingwithdata:data];
Person *person1 = [Unarchiver decodeobjectforkey:@ "Person1"];
Person *person2 = [Unarchiver decodeobjectforkey:@ "Person2"];
Recovery completed [Unarchiver finishdecoding];
Deep replication with archiving: For example, deep replication of a person object
Temporary storage of Person1 data
nsdata *data = [Nskeyedarchiver archiveddatawithrootobject:person1];
Parse data to generate a new person object
Student *person2 = [Nskeyedunarchiver unarchiveobjectwithdata:data];
Print memory addresses separately
NSLog (@ "person1:%@", person1);//person1:0x8d3ed10>
NSLog (@ "person2:%@", Person2); Person2:0x8d3e2f0>
SQLite3
1.sqlite3 is an open source embedded relational database, the portability is good, easy to use, the memory cost is small.
2.sqlite3 is no type, meaning you can save any type of data to any field in any table.
3.sqlite3 4 data types commonly used: text (literal string), Integer (integer value), real (floating-point value), BLOB (binary data (such as file)).
To use SQLite3 in iOS, first add the library file 'libsqlite3.dylib'
and import the main header file#import<sqlite3.h>
Features of SQL statements:
1> is not case-sensitive;
2> Each statement must be a semicolon;
Keywords commonly used in sql:
Pselect, INSERT, UPDATE, Delete, from, create, where, desc, order, by, Group, table, Alter, view, index, etc.
You cannot use keywords to name tables, fields in the database.
Types of SQL statements:
1> data definition statement (ddl:data definition Language)
Including create and drop operations;
Creates a new table or deletes a table (CREATE table or drop table) in the database.
2> Data Action Statement (Dml:data manipulation Language)
Including INSERT, UPDATE, delete and other operations;
The above 3 actions are used to add, modify, and delete the data in the table, respectively.
3> data query Statement (dql:data query Language)
can be used to query to get the data in the table;
The keyword Select is the most frequently used operation for DQL (and all SQL);
Other dql commonly used keywords are where,order by,group by and having created.
Create a table:
CREATE table if not exists t_student (ID integer, name text, age Inetger, score real);
Delete table:
drop table if exists t_student;
Inserting data (insert):
Insert into T_student (name, age) VALUES (' JN ', 22);
Note: The string contents in the database should be enclosed in single quotes.
Update data (Updata):
Pupdate t_student Set name = ' Jack ', age = 20;
Note: The above update changes the name of all records in the T_student table to Jack,age to 20;
Delete data (delete):
Will erase all the records in the T_student table.
If you only want to update or delete some of the fixed records, you must add some criteria after the DML statement. The example is as follows:
The T_student table is older than 10 and the name is not equal to Jack's record, and the age is changed to 5
update t_student Set ages = 5 where Age > Name!= ' Jack ';
Delete records in the T_student table that are less than or equal to 10 or older than 30
delete from t_student where age <= and age > 30;
Query Statement (DQL):
SELECT * from T_student where age > 10; Conditional query Criteria statement:
PRIMARY KEY constraint:
Each table must have a primary key to identify the uniqueness of the record.
What is a primary key:
Primary KEY (Primary key, short PK), used to uniquely identify a record.
For example, t_student can add an ID field as a primary key, equivalent to a person's identity card.
A primary key can be a field or multiple fields.
FOREIGN KEY constraint:
The use of FOREIGN key constraints can be used to establish the relationship between tables.
A foreign key is typically a field in a table that references the primary key field of another table.
Open, close the database
To create or open a database:
Path is: ~/documents/person.db
sqlite3 *db;int result = Sqlite3_open ([path utf8string], &db);
Code resolution:
Sqlite3_open () will open the database according to the file path, and if not, a new database will be created. If result equals constant SQLITE_OK, the database is opened successfully.
SQLite *db: An open database instance.
The path to the database file must be passed in as a C string rather than nsstring.
Close database: sqlite3_close (db);
Execute an SQL statement that does not return a statement
Char *errormsg; Use to store error message
char *sql = "CREATE table if not exists T_person (ID integer primary key autoincrement, name text, age inte GER); ";
int result = SQLITE3_EXEC (db, SQL, NULL, NULL, &ERRORMSG);
Code resolution:
Sqlite3_exec () can execute any SQL statements, such as create a table, update, insert, and delete operations. But generally do not use it to execute query statements, because it does not return the query to the data.
Sqlite3_exec () A statement that can also be executed:
1> Open Business: begain transaction;
2> ROLLBACK TRANSACTION: Rollback
3> COMMIT TRANSACTION: Commit
SQLite Function Summary:
1. Open database int sqlite3_open (const char *filename,//Database file path sqlite3 **ppdb//database instance); 2. Execute any SQL statement int sqlite3_exec (sqlite3*,//An open database instance const char *SQL,//SQL statement required to execute INT (*callb
Error message); 3. Check the legality of the SQL statement (before querying) int sqlite3_prepare_v2 (Sqlite3 *db,///Database Instance const char *ZSQL,//SQL statement to check for int nbyt
E,//SQL statement maximum byte length sqlite3_stmt **ppstmt,//sqlite3_stmt instance, used to obtain database data const char **pztail); 4. Query one row of data int sqlite3_step (sqlite3_stmt*); If you query to one row of data, you return Sqlite_row 5. Use stmt to get the value of a field (the Subscript for a field starts at 0) Double sqlite3_column_double (sqlite3_stmt*, int icol); floating-point data int sqlite3_column_int (sqlite3_stmt*, int icol); Integral type Data Sqlite3_int64 Sqlite3_column_int64 (sqlite3_stmt*, int icol); Long-integer Data const void *sqlite3_column_blob (sqlite3_stmt*, int icol); Binary Text Data const unsigned char *sqlite3_column_text (sqlite3_stmt*, int icol); //String data
CoreData
The Core data Framework provides object-relational mapping (ORM) functionality that converts an OC object into data, is saved in a SQLite3 database file, and restores data saved in a database to an OC object. No SQL statements need to be written during the secondary data operation.
Use this feature to add coredata.framework and import the main header file <coredate/coredata.h>.
Model files: In CoreData, the objects that need to be mapped are called entities (entity), and the CoreData model file is used to describe all the entity and entity attributes that are applied.
Nsmanagedobject
objects removed from the database by core data are Nsmanagedobject objects by default.
Nsmanagedobject's working mode is somewhat similar to the Nsdictionary object, which accesses all entity attributes through a key-value pair.
Setvalue:forkey: Store Property Value (property name key);
Valueforkey: Gets the property value (the property name is key).
CoreData Main objects
Nsmanagedobjectcontext: Responsible for interaction between data and application libraries (CRUD);
Nspersistentstorecoordinator: Add persistent repositories (such as SQLite databases);
Nsmanagedobjectmodel: A model file representing core data;
Nsentitydescription: Used to describe an entity;
Build CoreData Context:
Load the model file from the application package Nsmanagedobjectmodel *model = [Nsmanagedobjectmodel Mergedmodelfrombundles:nil]; Incoming model, initialize nspersistentstorecoordinator nspersistentstorecoordinator *PSC = [[Nspersistentstorecoordinator alloc]
Initwithmanagedobjectmodel:model]; Build sqlite file path nsstring *docs = [Nssearchpathfordirectoriesindomains (nsdocumentdirectory, Nsuserdomainmask, YES) Lastobject];
Nsurl *url = [Nsurl fileurlwithpath:[docs stringbyappendingpathcomponent:@ "Person.data"]];
Add a persistent repository, where SQLite is used as the repository nserror *error = nil; Nspersistentstore *store = [PSC addpersistentstorewithtype:nssqlitestoretype configuration:nil URL:url Options:nil
error:&error]; if (store = = nil) {//Direct throw exception [NSException raise:@ "Add Database Error" format:@ "%@", [Error localizeddescription]];}//initialization context, Set the Persistentstorecoordinator property Nsmanagedobjectcontext *context = [[Nsmanagedobjectcontext alloc] init];
Context.persistentstorecoordinator = PSC;
After use, or to [context release]; /* Type of Persistent repository: Nssqlitestoretype SQLite database NsbinaryStoretype binary Flat file Nsinmemorystoretype memory Library, unable to persist data although these 3 types of performance are similar in speed, the information kept from the data model is different in almost all scenarios, the default setting should be used. Use SQLite as a persistent repository * *
Add Data:
Incoming context, create a person entity object
nsmanagedobject *person = [nsentitydescription insertnewobjectforentityforname:@ "person "Inmanagedobjectcontext:context];
Set simple properties
[person setvalue:@ ' JN ' forkey:@ ' name '];
[Person Setvalue:[nsnumber numberwithint:22] forkey:@ ' age '];
Incoming context, create a card entity object
nsmanagedobject *card = [nsentitydescription insertnewobjectforentityforname:@ "card" Inmanagedobjectcontext:context];
[Card setvalue:@ "447640819" forkey:@ "no"];
Set the association between person and card
[person Setvalue:card forkey:@ ' card '];
Use context objects to synchronize data to a persisted repository
nserror *error = nil; BOOL success = [Context save:&error];
if (!success) {
[nsexception raise:@ "Access database Error" format:@ "%@", [Error localizeddescription]];
}
If you want to do an update: You can synchronize changed data to a database by invoking [context Save:&error] after changing the properties of the entity object
Query data:
Initializes a query request
nsfetchrequest *request = [[Nsfetchrequest alloc] init];
Set the entity to query
nsentitydescription *desc = [nsentitydescription entityforname:@ ' person ' inmanagedobjectcontext: Context];
Set sort (in descending order of age)
nssortdescriptor *sort = [nssortdescriptor sortdescriptorwithkey:@ ' age ' ascending:no];
Request.sortdescriptors = [Nsarray arraywithobject:sort];
Set conditional filtering (name like '%jn-1% ')
nspredicate *predicate = [nspredicate predicatewithformat:@ "name like%@", @ "*jn-1*"];
request.predicate = predicate;
Note: When setting conditional filtering, the% in the database should be replaced with */
/execute request
nserror *error = nil;
Nsarray *OBJS = [Context executefetchrequest:request error:&error];
if (error) {
[nsexception raise:@ "Query Error" format:@ "%@", [Error localizeddescription]];
}
Traversal data
for (Nsmanagedobject *obj in Objs) {
NSLog (@ "name=%@", [obj valueforkey:@ ' name ']
}
Delete data:
Incoming entity objects that need to be deleted
[context Deleteobject:managedobject];
Synchronizes the results to the database nserror *error = nil;
[Context save:&error];
if (error) {
[nsexception raise:@ "Delete error" format:@ "%@", [Error localizeddescription]];
}
Delay loading of Core data:
Core data does not immediately get the associated object based on the association relationship in the entity; For example, when you remove the person entity from core data, the associated card entity is not immediately queried, and when the application does need to use the card, the database is queried and the card entity information is loaded.
To create a nsmanagedobject subclass:
By default, entities taken out of core data are nsmanagedobject types and can access data using key-value pairs.
However, in general, entities are required to create nsmanagedobject subclasses by accessing data and sometimes adding business methods to accomplish other tasks.
So a person entity object should be generated to write the person
*person = [nsentitydescription insertnewobjectforentityforname:@ ' person ' Inmanagedobjectcontext:context];
Person.name = @ "JN";p erson.age = [NSNumber numberwithint:24];
Card *card = [nsentitydescription insertnewobjectforentityforname:@ ' card ' inmanagedobjectcontext:context];
card.no = @ "447640819";
Person.card = Card;
The above is the commonly used data storage mode in iOS and its detailed usage, this article introduces the XML attribute list (plist) archiving, preference (preferences), Nskeyedarchiver Archive, SQLite3 and core data respectively, The implementation process and matters needing attention are introduced in detail by the example. I hope this article will help you learn about iOS development. And please continue to support the cloud-dwelling community.