Several data persistence scenarios in iOS

Source: Internet
Author: User
Tags sqlite database stmt

Introduction

The so-called persistence is to save the data to the hard disk so that the previously saved data can continue to be accessed after the application or machine restarts. There are many scenarios for data persistence in iOS development, and then I'll try to introduce 5 scenarios:

    • plist file (attribute list)

    • Preference (preference setting)

    • Nskeyedarchiver (archive)

    • SQLite 3

    • CoreData

Sand box

Before describing the various storage methods, it is necessary to describe the following sandbox mechanism. iOS programs can only access the program's own directory by default, which is called a "sandbox."

1. Structure

Since the sandbox is a folder, let's see what's inside. The directory structure of the sandbox is as follows:

"Application Package" Documentslibrary    Caches    preferencestmp

2. Catalog Features

Although there are so many folders in the sandbox, no folders are different and each has its own characteristics. So when you choose to store the directory, be sure to carefully select the appropriate directory.

Application package: This is where the application's source files, including resource files and executables, are stored.

  NSString *path = [[NSBundle mainbundle] bundlepath];  NSLog (@ "%@", Path);

Documents: The most commonly used directory, itunes synchronizes the content in this folder when syncing the app, and is ideal for storing important data.

  NSString *path = Nssearchpathfordirectoriesindomains (NSDocumentDirectory, Nsuserdomainmask, YES). FirstObject;  NSLog (@ "%@", Path);

Library/caches:itunes does not synchronize this folder for non-critical data that is large in size and does not need to be backed up.

NSString *path = Nssearchpathfordirectoriesindomains (Nscachesdirectory, Nsuserdomainmask, YES). FirstObject;  NSLog (@ "%@", Path);

Library/preferences:itunes syncing the app synchronizes the contents of this folder, typically saving the app's settings information.

Tmp:itunes does not synchronize this folder, the system may delete the files under this directory when the app is not running, so this directory is suitable for saving some temporary files in the app and deleting them when they are exhausted.

NSString *path = Nstemporarydirectory ();  NSLog (@ "%@", Path);

plist file

The plist file is a specific class that is saved in the directory by means of an XML file.

There are only a few types that can be serialized:

Nsarray; Nsmutablearray; Nsdictionary; Nsmutabledictionary; NSData; Nsmutabledata; NSString; nsmutablestring; NSNumber; NSDate;

1. Get the file path

NSString *path = Nssearchpathfordirectoriesindomains (NSDocumentDirectory, Nsuserdomainmask, YES). FirstObject;    NSString *filename = [path stringbyappendingpathcomponent:@ "123.plist"];

2. Storage

Nsarray *array = @[@ "123", @ "456", @ "789"]; [Array writetofile:filename atomically:yes];

3. Read

Nsarray *result = [Nsarray arraywithcontentsoffile:filename]; NSLog (@ "%@", result);

4. Note

    • Only the types listed above can use the Plist file store.

    • Use writetofile:atomically when storing: method. Where atomically indicates whether a secondary file needs to be written before the secondary file is copied to the destination file address. This is a more secure way to write to a file, and generally write yes.

    • Use Arraywithcontentsoffile when reading: method.

Preference

1. How to use

1. Get nsuserdefaults file Nsuserdefaults *userdefaults = [Nsuserdefaults standarduserdefaults];//2. Writing to a file [ Userdefaults setobject:@ "AAA" forkey:@ "a"]; [Userdefaults setbool:yes forkey:@ "Sex"]; [Userdefaults setinteger:21 forkey:@ "age"];//2.1 sync now [userdefaults synchronize];//3. read file NSString *name = [ Userdefaults objectforkey:@ "a"]; BOOL sex = [userdefaults boolforkey:@ "sex"]; Nsinteger age = [userdefaults integerforkey:@ ' age ']; NSLog (@ "%@,%d,%ld", Name, sex, age);

2. Note

    • Preferences are designed to save configuration information for your application, and you should not save other data in your preferences.

    • If the Synchronize method is not called, the system will be saved to the file in an indefinite time, depending on the I/O situation. So if you need to write the file immediately, you must call the Synchronize method.

    • Preferences will save all the data in the same file. A plist file that is named under this application package name in the preference directory.

Nskeyedarchiver

Archiving is another form of serialization in iOS, as long as objects that follow the Nscoding protocol can be serialized through it. Because most of the foundation and cocoa touch classes that support storing data adhere to the Nscoding protocol, archiving is relatively easy to implement for most classes.

1. Follow the nscoding agreement

The Nscoding protocol declares two methods, both of which must be implemented. One to illustrate how to encode an object into an archive, and another to explain how to get a new object.

    • Following protocols and setting properties

1. Follow the nscoding agreement   @interface person:nsobject   //2. Set Properties  @property (Strong, nonatomic) UIImage *avatar;  @property (copy, nonatomic) NSString *name;  @property (Assign, nonatomic) Nsinteger age;  @end

    • Implementing Protocol Methods

  Solution  -(ID) Initwithcoder: (Nscoder *) Adecoder {      if ([Super init]) {          Self.avatar = [Adecoder decodeobjectforkey:@ "Avatar"];          Self.name = [Adecoder decodeobjectforkey:@ "name"];          Self.age = [Adecoder decodeintegerforkey:@ "age"];      }      return self;  }  Archive  -(void) Encodewithcoder: (Nscoder *) acoder {      [acoder encodeObject:self.avatar forkey:@ "Avatar"];      [Acoder encodeObject:self.name forkey:@ "name"];      [Acoder encodeInteger:self.age forkey:@ "age"];  }

    • Special attention

If the class that needs to be archived is a subclass of a custom class, you need to implement the archive and file method of the parent class before archiving and reconciling the files. [Super Encodewithcoder:acoder] and [Super Initwithcoder:adecoder] method;

2. Use

The object file needs to be archived is the factory method called Nskeyedarchiver Archiverootobject:tofile: Method.

NSString *file = [Nssearchpathfordirectoriesindomains (nsdocumentdirectory, Nsuserdomainmask, YES). FirstObject stringbyappendingpathcomponent:@ "Person.data"];  Person *person = [[Person alloc] init];  Person.avatar = Self.avatarView.image;  Person.name = Self.nameField.text;  Person.age = [Self.ageField.text integervalue];  [Nskeyedarchiver Archiverootobject:person Tofile:file];

A factory method called Nskeyedunarchiver that needs to be unpacked from a file Unarchiveobjectwithfile: you can.

  NSString *file = [Nssearchpathfordirectoriesindomains (nsdocumentdirectory, Nsuserdomainmask, YES). FirstObject stringbyappendingpathcomponent:@ "Person.data"];  Person *person = [Nskeyedunarchiver unarchiveobjectwithfile:file];  if (person) {     self.avatarView.image = Person.avatar;     Self.nameField.text = Person.name;     Self.ageField.text = [NSString stringwithformat:@ "%ld", Person.age];  }

3. Note

    • The nscoding protocol must be followed and implemented

    • The extension of the saved file can be specified arbitrarily

    • You must first call the parent class's archive solution method when inheriting

SQLite3

All previous storage methods are overwrite storage. If you want to add a piece of data, you must read the entire file, then modify the data before overwriting the entire content to the file. So they are not suitable for storing large amounts of content.

1. Field type

On the surface, SQLite divides the data into the following types:

    • Integer: Integers

    • Real: Real number (floating point)

    • Text: literal string

    • BLOB: Binary data, such as files, pictures, etc.

In fact, SQLite is untyped. That is, no matter what type of field you specify when you create a table, storage can still store any type of data. Also, you can not specify a field type when creating a table. SQLite is what type is for good programming norms and facilitate the communication of developers, so usually in use when the best set the correct field type! primary key must be set to integer

2. Preparatory work

Preparation is to import the dependent library, in iOS to use SQLite3, you need to add library files: Libsqlite3.dylib and import the main header file, this is a C language library, so the direct use of SQLite3 is still a bit cumbersome.

3. Use

    • Create a database and open

You must specify the database file and the table you want to manipulate before you manipulate the database, so using SQLite3, you first open the database file and then specify or create a table.

/***  Open the database and create a table */-(void) OpenDatabase {   //1. set file name   nsstring *filename = [ Nssearchpathfordirectoriesindomains (NSDocumentDirectory, Nsuserdomainmask, YES). Firstobject stringbyappendingpathcomponent:@ "Person.db"];   2. Open the database file, if not automatically create a file   nsinteger result = Sqlite3_open (filename. Utf8string, &_sqlite3);   if (result = = SQLITE_OK) {       NSLog (@) Open the database successfully! ");       3. Create a database table       char *errmsg = NULL;       Sqlite3_exec (_sqlite3, "CREATE TABLE IF not EXISTS t_person (ID integer primary key autoincrement, name text, age integer)" , NULL, NULL, &ERRMSG);       if (errmsg) {           NSLog (@ "error:%s", errmsg);       } else {           NSLog (@ "Create a table success! ");       }   } else {       NSLog (@) failed to open the database! ");   }}

    • Execution instructions

Use the Sqlite3_exec () method to execute any SQL statements, such as Create tables, update, insert, and delete operations. However, it is generally not necessary to execute a query statement because it does not return the queried data.

/***  inserting 1000 data into the table */-(void) InsertData {nsstring *namestr; Nsinteger age;for (Nsinteger i = 0; i <; i++) {  nameStr = [NSString stringwithformat:@ "bourne-%d", arc4random_ Uniform (10000)];  Age = Arc4random_uniform (+) +;  NSString *sql = [NSString stringwithformat:@ "INSERT into T_person (name, age) VALUES ('%@ ', '%ld ') ', nameStr, age];  char *errmsg = NULL;  Sqlite3_exec (_sqlite3, SQL. Utf8string, NULL, NULL, &ERRMSG);  if (errmsg) {      NSLog (@ "error:%s", errmsg);}  } NSLog (@ "Insert complete!) ");}

    • Query instructions

As I said earlier, you typically do not use the Sqlite3_exec () method to query data. Because query data has to get query results, queries are relatively cumbersome. The sample code is as follows:

      • Sqlite3_prepare_v2 (): Check the legality of SQL

      • Sqlite3_step (): Gets the result of the query line by row, repeating until the last record

      • Sqlite3_coloum_xxx (): Gets the contents of the corresponding type, icol corresponds to the order of the fields in the SQL statement, starting with 0. Depending on the properties of the actual query field, use Sqlite3_column_xxx to get the corresponding content.

      • Sqlite3_finalize (): Release stmt

/***  reads data from the table into the array */-(void) readdata {   Nsmutablearray *marray = [Nsmutablearray arraywithcapacity:1000];   Char *sql = "SELECT Name, age from T_person;";   Sqlite3_stmt *stmt;   Nsinteger result = SQLITE3_PREPARE_V2 (_sqlite3, SQL,-1, &stmt, NULL);   if (result = = SQLITE_OK) {while       (Sqlite3_step (stmt) = = Sqlite_row) {           char *name = (char *) Sqlite3_column_text (STM T, 0);           Nsinteger age = Sqlite3_column_int (stmt, 1);           Create object           *person = [Person personwithname:[nsstring stringwithutf8string:name] age:age];           [Marray Addobject:person];       }       Self.datalist = Marray;   }   Sqlite3_finalize (stmt);}

4. Summary

Generally speaking, the use of SQLite3 is more troublesome, because it is a C language function, it is difficult to understand. However, in the general development process, the use of the third-party open Source Library FMDB, encapsulated the basic C language methods, so that we use more easily understand, improve development efficiency.

FMDB

1. Introduction

Fmdb is the SQLite database framework of the iOS platform, which encapsulates the C language API of SQLite in OC, which has the following advantages over the Cocoa C framework:

Use more object-oriented, save a lot of cumbersome, redundant C language code

More lightweight and flexible compared to Apple's own core data framework

Provides a multi-threaded secure database operation method to effectively prevent data confusion

Note: Fmdb's github address

2. Core class

The Fmdb has three main classes:

    • Fmdatabase

A Fmdatabase object represents a separate SQLite database for executing SQL statements

    • Fmresultset

Result set after query execution with Fmdatabase

    • Fmdatabasequeue

Used to execute multiple queries or updates in multiple threads, which is thread-safe

3. Open the Database

Like the C language Framework, Fmdb creates Fmdatabase objects by specifying the SQLite database file path, but Fmdb is easier to understand, easier to use, and requires importing sqlite3.dylib as before. Open the database method as follows:

NSString *path = [Nssearchpathfordirectoriesindomains (nsdocumentdirectory, Nsuserdomainmask, YES). FirstObject stringbyappendingpathcomponent:@ "Person.db"]; Fmdatabase *database = [Fmdatabase Databasewithpath:path];    if (![    Database Open] {NSLog (@) failed to turn on databases! ");}

It is important to note that the value of path can be passed in the following three scenarios:

    • The specific file path, if not present, is automatically created

    • The empty string @ "" Creates an empty database in the temp directory, and the database file is deleted when the Fmdatabase connection is closed

    • Nil, an in-memory staging database is created and the database is destroyed when the Fmdatabase connection is closed

4. Update

In Fmdb, all operations except queries are called "updates," such as: Create, DROP, insert, UPDATE, Delete, and so on, using the Executeupdate: method to perform the update:

The following 3 types of methods are used:   -(BOOL) Executeupdate: (nsstring*) SQL, ...-(BOOL) Executeupdatewithformat: (nsstring*) format, ...-( BOOL) Executeupdate: (nsstring*) SQL Withargumentsinarray: (Nsarray *) arguments//example [Database executeupdate:@ "CREATE TABLE IF not EXISTS t_person (ID integer primary key autoincrement, name text, age integer) "];   or  [Database executeupdate:@ INSERT into T_person (name, age) VALUES (?,?) "@" Bourne ", [NSNumber numberwithint:42 ]];

5. Enquiry

There are 3 query methods, which are fairly simple to use:

-(Fmresultset *) ExecuteQuery: (nsstring*) SQL, ...-(Fmresultset *) Executequerywithformat: (nsstring*) format, ...-( Fmresultset *) ExecuteQuery: (NSString *) SQL Withargumentsinarray: (Nsarray *) arguments

Query Example:

1. Execute query fmresultset *result = [Database executequery:@ "SELECT * from T_person"];//2. Traversal result set while ([result next]) {    NSString *name = [result stringforcolumn:@ "name"];    int age = [result intforcolumn:@ ' age '];}

6. Thread Safety

It is unwise to use one Fmdatabase instance in multiple threads at the same time. Do not allow multiple threads to share the same fmdatabase instance, which cannot be used concurrently in multiple threads. If you use one fmdatabase instance at a time in multiple threads, it can cause problems such as data confusion. So, use Fmdatabasequeue, which is thread-safe. Here's how to use it:

    • Create a queue.

Fmdatabasequeue *queue = [Fmdatabasequeue Databasequeuewithpath:apath];

    • Using queues

[Queue indatabase:^ (Fmdatabase *database) {              [database executeupdate:@] INSERT into T_person (name, age) VALUES (?,?) "@" Bourne_1 ", [NSNumber Numberwithint:1]] ;              [Database executeupdate:@ INSERT into T_person (name, age) VALUES (?,?) "@" bourne_2 ", [NSNumber Numberwithint:2]];              [Database executeupdate:@ INSERT into T_person (name, age) VALUES (?,?) "@" Bourne_3 ", [NSNumber Numberwithint:3]];                Fmresultset *result = [Database executequery:@ "SELECT * from T_person"];             while ([result next]) {            }    }];

And it's easy to wrap simple tasks into a transaction:

[Queue intransaction:^ (Fmdatabase *database, BOOL *rollback) {              [database executeupdate:@] INSERT into T_person (name, age) VALUES (?,?) "@" Bourne_1 ", [NSNumber Numberwithint:1]] ;              [Database executeupdate:@ INSERT into T_person (name, age) VALUES (?,?) "@" bourne_2 ", [NSNumber Numberwithint:2]];              [Database executeupdate:@ INSERT into T_person (name, age) VALUES (?,?) "@" Bourne_3 ", [NSNumber Numberwithint:3]];                Fmresultset *result = [Database executequery:@ "SELECT * from T_person"];                 while ([result next]) {                }              //rollback           *rollback = YES;      }];

The fmdatabasequeue background creates a serialized g-c-d queue and executes the blocks you pass to the g-c-d queue. This means that you invoke the calling method from multiple threads at the same time, and GDC executes in the order of the blocks it receives.

CoreData See:

http://www.jianshu.com/p/6e048f7c5812

Several data persistence scenarios in iOS

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.