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:@"\n"];
    }
    
    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:@"\n"];
    }
    
    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

 

posted on 2015-01-01 14:13  HJiang  阅读(590)  评论(0编辑  收藏  举报