Explain four ways to save data in IOS in detail

  • 2021-07-10 20:57:48
  • OfStack

In the iOS development process, no matter what application, will encounter the problem of data preservation. Saving the data locally can make the program run more smoothly without the disgusting chrysanthemum shape, which makes the user experience better. Here's how to save data under 1:

1. NSKeyedArchiver: The data is stored as an archive. The data object must comply with the NSCoding protocol, and the corresponding class of the object must provide encodeWithCoder: and initWithCoder: methods. The first one tells the system how to encode the object, and the second one tells the system how to decode the object. For example, archive and save Possession objects.

Define Possession:


@interface Possession : NSObject<NSCoding>{// Observance NSCoding Agreement 

    NSString *name;// Type to be archived 


}

@implementation Possession

-(void)encodeWithCoder:(NSCoder *)aCoder{

      [aCoder encodeObject:name forKey:@"name"];


}
-(void)initWithCoder:(NSCoder *)aDecoder{

      name=[[aDeCoder decodeObjectforKey:@"name"] retain];
}

Archiving operation:

If the Possession object allPossession is archived, only the methods archiveRootObject: toFile: of NSCoder subclass NSKeyedArchiver are needed.


NSString *path = [self possessionArchivePath];

[NSKeyedArchiver archiveRootObject:allPossessions toFile: path ]

Decompression operation:

You can also call the method unarchiveRootObject: toFile: of NSCoder subclass NSKeyedArchiver


allPossessions = [[NSKeyedUnarchiver unarchiveObjectWithFile:path] retain];

Disadvantages: To save data in the form of archiving, only one-time archiving and one-time decompression. Therefore, it can only be used for a small amount of data, and the data operation is clumsy, that is, if you want to change a small part of the data, you still need to decompress the whole data or archive the whole data.

2. NSUserDefaults: User-saved data used to store application settings and properties. These data still exist after the user opens the program again or boots it. The data types that NSUserDefaults can store include: NSData, NSString, NSNumber, NSDate, NSArray, NSDictionary. If you want to store other types, you need to convert to the previous type before you can store them with NSUserDefaults. The specific implementation is as follows:

Save data:


NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];
 NSString *name =@ " default string " ;
 [defaults setObject:firstName forKey:@"name"];
  // Obtain UIImage Instances 

UIImage *image=[[UIImage alloc]initWithContentsOfFile:@"photo.jpg"];

 NSData *imageData = UIImageJPEGRepresentation(image, 100);//UIImage Object is converted to NSData

 [defaults synchronize];// Use synchronize Method persists data to the standardUserDefaults Database 

Read data:


NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];
 NSString *name = [defaults objectForKey:@"name"];// Take out according to the key value name
 NSData *imageData = [defaults dataForKey:@"image"];
 UIImage *Image = [UIImage imageWithData:imageData];//NSData Convert to UIImage

3. Write Write: Permanently saved on disk. The specific method is as follows:

Step 1: Get the path where the file will be saved:


NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);// Use C Function NSSearchPathForDirectoriesInDomains To get the full path of the directory in the sandbox. The function has 3 Parameters, directory types, he domain mask Boolean value. Where the Boolean value indicates whether the path needs to be extended through ~. And the first 1 Parameters are invariant, that is, NSSearchPathDirectory  . In iOS The last two parameters in are also unchanged, namely: NSUserDomainMask  And  YES . 
NSString *ourDocumentPath =[documentPaths objectAtIndex:0];

Another method is to use the NSHomeDirectory function to get the path of sandbox. The specific usage is:


NSString *sandboxPath = NSHomeDirectory();
 // Once you have the full sandbox path, you can create a path from it , but not in sandbox Write files on this file layer cannot create directories, but should be created on this basis 1 New writable directories, such as Documents,Library Or temp . 
NSString *documentPath = [sandboxPath
       stringByAppendingPathComponent:@"Documents"];// Will Documents Add to sandbox On the path, the specific reasons were analyzed before! 

The difference between the two is that it is safer to use NSSearchPathForDirectoriesInDomains than to add Document after NSHomeDirectory. Because the file directory may change on the system sent in the future.

Step 2: Generate the file under this path:


NSString *FileName=[documentDirectory stringByAppendingPathComponent:fileName];//fileName Is the file name of the saved file 

Step 3: Write data to a file:


[data writeToFile:FileName atomically:YES];// Will NSData Type object data Write to a file named FileName

Finally: Read the data from the file:


NSData data=[NSData dataWithContentsOfFile:FileName options:0 error:NULL];// From FileName Read out the data in 

4. SQLite: Use SQLite database to store data. SQLite as a small and medium-sized database, ios, compared with the previous three storage methods, relatively more complex 1. Let's do it step by step!

Step 1: Need to add SQLite related libraries and header files: under Build Phases in the project file, find ES90Binary Library (ies), and add libsqlite3.0. dylib (the difference between libsqlite3.dylib and the former is unknown for the time being, but they should be similar); Add the header # import "/usr/include/sqlite3. h" in the header file of the project file or in the source file

Step 2: Start using SQLite:


NSString *path = [self possessionArchivePath];

[NSKeyedArchiver archiveRootObject:allPossessions toFile: path ]
0

On the premise of opening the database, if there is no table in the database, then start to build the table!


NSString *path = [self possessionArchivePath];

[NSKeyedArchiver archiveRootObject:allPossessions toFile: path ]
1

After the table is built, start inserting records:


NSString *path = [self possessionArchivePath];

[NSKeyedArchiver archiveRootObject:allPossessions toFile: path ]
2

In the next step, query the record:


const char *selectSql="select id,name from a person"; 
 sqlite3_stmt *statement; 
 if (sqlite3_prepare_v2(database,selectSql, -1, &statement, nil)==SQLITE_OK) { 
     NSLog(@"select operation is ok."); 
 }
 else
 {
    NSLog(@"error: %s",error);
    sqlite3_free(error);
 } 
 while(sqlite3_step(statement)==SQLITE_ROW) { 
 int _id=sqlite3_column_int(statement, 0); 
 NSString *name=(char*)sqlite3_column_text(statement, 1); 
 NSLog(@"row>>id %i, name %s",_id,name); 
 }
 sqlite3_finalize(statement);

Finally, close the database:


NSString *path = [self possessionArchivePath];

[NSKeyedArchiver archiveRootObject:allPossessions toFile: path ]
4

Note: Write to the database, string can use char, and from the database to take out char type, when char type has Chinese characters, will appear garbled. This is because the database uses ascII encoding by default. Therefore, if you want to correctly extract Chinese from the database, you need to use NSString to receive the string extracted from the database.


Related articles: