iOS应用数据存储的常用方式
1.xml属性列表(plist)归档
2. Preference(偏好设置)
3.NSKeyedArchive归档(NSCoding)
4.SQLite
5.Core Data
1.xml属性列表(plist)归档
"plist文件存储" 1.字符串 数组 字典 可以直接存储数据在一个文件 2.掌握沙盒备目录的作用以及目录路径获取方式 // Document [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] // 缓存 [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; // 临时 NSTemporaryDirectory(); // 主目录 NSHomeDirectory(); 3.不是所有对象都可以保存到plist文件中,要有实现writeFile方法才可以 4.学会使用SimPholders2打开沙盒目录
@interface HJPlistController () @property (weak, nonatomic) IBOutlet UILabel *textView; @property (strong,nonatomic) NSString *docPath; - (IBAction)stringWrite:(id)sender; - (IBAction)stringRead:(id)sender; - (IBAction)arrayWrite:(id)sender; - (IBAction)arrayRead:(id)sender; - (IBAction)dictionoryWrite:(id)sender; - (IBAction)dictionaryRead:(id)sender; @end /** * 使用xml plist属性列表归档 ,preference偏好设置,使用NSKeyedArchiver归档(NSCoding) */ @implementation HJPlistController - (NSString *)docPath{ // 获取 "沙盒"document目录 if (_docPath == nil) { _docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; _docPath = [_docPath stringByAppendingPathComponent:@"data.plist"]; } return _docPath; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // Do any additional setup after loading the view, typically from a nib. //查看沙盒的路径 //1.控制台打印沙盒的路径,使用finder-前往-文件夹 打开 //2.控制台打印沙盒的路径,打开终端 open + 路径 //3.使用simpholders工具 //4.可以断点 输入po NSHomeDirectory() //获取缓存路径(cache) // NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; // NSLog(@"%@",cachePath); // // // //获取临时路径(tmp) // NSString *tmpPath = NSTemporaryDirectory(); // NSLog(@"%@",tmpPath); // // //主目录 // NSString *homePath = NSHomeDirectory(); // NSLog(@"%@",homePath); } - (IBAction)stringWrite:(id)sender { NSLog(@"%@",self.docPath); NSString *data = @"ios中国"; [data writeToFile:self.docPath atomically:YES encoding:NSUTF8StringEncoding error:nil]; } - (IBAction)stringRead:(id)sender { NSString *resultStr = [NSString stringWithContentsOfFile:self.docPath encoding:NSUTF8StringEncoding error:nil]; self.textView.text = resultStr; } - (IBAction)arrayWrite:(id)sender{ NSArray *dataArray = [NSArray arrayWithObjects:@"a",@"b",@"c",@"中",@"国", nil]; [dataArray writeToFile:self.docPath atomically:YES]; } - (IBAction)arrayRead:(id)sender{ NSArray *resultData = [NSArray arrayWithContentsOfFile:self.docPath]; NSMutableString *ms = [NSMutableString string]; for (NSString *str in resultData) { [ms appendString:str]; [ms appendString:@" "]; } self.textView.text = ms; } - (IBAction)dictionoryWrite:(id)sender{ NSDictionary *dict = @{@"a":@"1",@"2":@"2",@"zh":@"中国"}; [dict writeToFile:self.docPath atomically:YES]; } - (IBAction)dictionaryRead:(id)sender{ NSDictionary *resultData = [NSDictionary dictionaryWithContentsOfFile:self.docPath]; NSMutableString *ms = [NSMutableString string]; NSArray *keys = resultData.allKeys; for (NSString *key in keys) { [ms appendFormat:@"%@:%@",key,resultData[key]]; [ms appendString:@" "]; } self.textView.text = ms; } @end
2."用户偏好设置"
"用户偏好设置" 1.ios中有个NSUserDefaults对象有可保存数据,我们称为用户偏好设置 2.通过[NSUserDefaults standardUserDefaults]可以获取用户偏好设置对象,保存字符串 布尔值 int等数据 3.保存数据时,一定要调用synchronize,因为数据要及时保存到沙盒的文件中 /* NSUserDefaults *defualts = [NSUserDefaults standardUserDefaults]; [defualts setObject:@"zhangsan" forKey:@"username"]; [defualts setObject:@"123" forKey:@"password"]; [defualts setBool:YES forKey:@"autoLogin"]; [defualts setBool:YES forKey:@"rememberPwd"]; //同步 [defualts synchronize]; */
4.掌握用户偏好设置数据的获取,更改,删除
@interface HJPreferenceController () @property (weak, nonatomic) IBOutlet UITextField *pwdTextField; @property (weak, nonatomic) IBOutlet UISwitch *rememberSwith; @property (weak, nonatomic) IBOutlet UILabel *dataLabel; - (IBAction)saveBut:(id)sender; - (IBAction)readBut:(id)sender; - (IBAction)updateBut:(id)sender; - (IBAction)deleteBut:(id)sender; @end @implementation HJPreferenceController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } /* #pragma mark - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } */ - (IBAction)saveBut:(id)sender { NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults]; [userDefault setObject:self.pwdTextField.text forKey:@"pwd"]; [userDefault setBool:self.rememberSwith.isOn forKey:@"isRememberPwd"]; // 同步数据 [userDefault synchronize]; } - (IBAction)readBut:(id)sender { NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults]; self.dataLabel.text = [NSString stringWithFormat:@"%@:%@ %@:%d",@"pwd",[userDefault objectForKey:@"pwd"],@"isRememberPwd",[userDefault boolForKey:@"isRememberPwd"]]; } // 修改偏好设置就是把键值重写设置 这样会覆盖原有的键值 - (IBAction)updateBut:(id)sender { NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults]; [userDefault setObject:self.pwdTextField.text forKey:@"pwd"]; [userDefault setBool:self.rememberSwith.isOn forKey:@"isRememberPwd"]; [userDefault synchronize]; self.dataLabel.text = [NSString stringWithFormat:@"%@:%@ %@:%d",@"pwd",[userDefault objectForKey:@"pwd"],@"isRememberPwd",[userDefault boolForKey:@"isRememberPwd"]]; } - (IBAction)deleteBut:(id)sender { NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults]; [userDefault removeObjectForKey:@"isRememberPwd"]; [userDefault synchronize]; self.dataLabel.text = [NSString stringWithFormat:@"%@:%@ %@:%d",@"pwd",[userDefault objectForKey:@"pwd"],@"isRememberPwd",[userDefault boolForKey:@"isRememberPwd"]]; } @end
3.NSKeyedArchive归档(NSCoding)
"NSKeyedArchiver归档" /*什么叫归档 归档就是把数据保存到一个文件中*/ 1.使用NSKeyedArchiver可以将NSArray NSDictiony NSString等对象归档到一个文件 2.只有实现了NSCoding协议的对象才可使用NSKeyedArchiver进行归档 3.将模型对象保存到一个文件时,对象要遵守NSCoding协议,并实现NSKeyedArchiver的encodeWithCoder方法, 4.从归档文件里读取对象时要实现NSCoding的initWithCoder方法 5.ios中,控制器,控件都继承NSCoding,storyboard/xib都是使用NSKeyedArchiver进行归档的
#import <Foundation/Foundation.h> @interface HJPerson : NSObject<NSCoding> @property (nonatomic,copy) NSString *name; @property (nonatomic,assign) int age; @property (nonatomic,strong) NSDate *birthday; @end
#import "HJPerson.h" @implementation HJPerson - (void)encodeWithCoder:(NSCoder *)aCoder{ [aCoder encodeObject:self.name forKey:@"name"]; [aCoder encodeInt:self.age forKey:@"age"]; [aCoder encodeObject:self.birthday forKey:@"birthday"]; } - (id)initWithCoder:(NSCoder *)aDecoder{ if (self == [super init]) { self.name = [aDecoder decodeObjectForKey:@"name"]; self.age = [aDecoder decodeIntForKey:@"age"]; self.birthday = [aDecoder decodeObjectForKey:@"birthday"]; } return self; } @end
#import "HJPerson.h" #warning 父类遵循了NSCoding方法就可以再此不遵循 @interface HJStudent : HJPerson @property (nonatomic,strong) NSString *no; @end
#import "HJStudent.h" @implementation HJStudent - (void)encodeWithCoder:(NSCoder *)aCoder{ #warning 记得在此调用父类的方法进行初始化 [super encodeWithCoder:aCoder]; [aCoder encodeObject:self.no forKey:@"no"]; } - (id)initWithCoder:(NSCoder *)aDecoder{ #warning 记得在此调用父类的方法进行初始化 if (self == [super initWithCoder:aDecoder]) { #warning 记得一定在此给属性赋值操作 self.no = [aDecoder decodeObjectForKey:@"no"]; } return self; } - (NSString *)description{ return [NSString stringWithFormat:@"%@,%d,%@,%@",self.name,self.age,self.birthday,self.no]; } @end
// // HJCodingController.m // 数据存储 // // Created by HJiang on 14/12/30. // Copyright (c) 2014年 HJiang. All rights reserved. // #import "HJCodingController.h" #import "HJStudent.h" @interface HJCodingController () @property (strong,nonatomic) NSString *docPath; @property (weak, nonatomic) IBOutlet UITextField *nameTextField; @property (weak, nonatomic) IBOutlet UITextField *ageTextField; @property (weak, nonatomic) IBOutlet UITextField *noTextField; @property (weak, nonatomic) IBOutlet UITextField *birthdayTextField; @property (weak, nonatomic) IBOutlet UILabel *resultLabel; - (IBAction)birthdayChange:(UIDatePicker *)sender; - (IBAction)saveBut:(id)sender; - (IBAction)readBut:(id)sender; @end @implementation HJCodingController - (NSString *)docPath{ // 获取 "沙盒"document目录 if (_docPath == nil) { _docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; _docPath = [_docPath stringByAppendingPathComponent:@"data.archiver"]; } return _docPath; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } /* #pragma mark - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } */ - (IBAction)birthdayChange:(UIDatePicker *)sender { NSDate *birthday = sender.date; NSDateFormatter *df = [[NSDateFormatter alloc] init]; df.dateFormat = @"yyyy-MM-dd"; self.birthdayTextField.text = [df stringFromDate:birthday]; } - (IBAction)saveBut:(id)sender { HJStudent *stu = [[HJStudent alloc] init]; stu.name = self.nameTextField.text; stu.age = [self.ageTextField.text intValue]; NSDateFormatter *df = [[NSDateFormatter alloc] init]; df.dateFormat = @"yyyy-MM-dd"; stu.birthday = [df dateFromString:self.birthdayTextField.text]; stu.no = self.noTextField.text; NSLog(@"%@",stu); BOOL isSuccess = [NSKeyedArchiver archiveRootObject:stu toFile:self.docPath]; NSLog(@"%@",isSuccess?@"保存成功":@"保存失败"); } - (IBAction)readBut:(id)sender { NSLog(@"%@",self.docPath); HJStudent *stu = [NSKeyedUnarchiver unarchiveObjectWithFile:self.docPath]; NSLog(@"%@",stu); self.resultLabel.text = [NSString stringWithFormat:@"%@,%d,%@,%@",stu.name,stu.age,stu.birthday,stu.no]; } @end