iOS 数据持久化之plist

原创Blog,转载请注明出处。
http://blog.csdn.net/hello_hwc?viewmode=list


前言:上一篇文章提到了如何使用NSUserDefaults来保存用户偏好信息,本文介绍如何使用plist以及普通文件来保存结构化的数据,通常用Plist来存储不需要结构化查询的数据,结构化查询通常使用CoreData,毕竟建立在数据库上的查询什么的都方便些。希望通过这篇文章,读者可以学到

  • 如何使用程序读写plist
  • 如何创建目录
  • library目录和document目录的区别
  • 将自定义的model类保存到plist中

library目录和document目录

关于这两个目录的区别我之前写过,这里还是再提一下:

document是那些暴露给用户的数据文件,用户可见,可读写;

library目录是App替用户管理的数据文件,对用户透明。所以,那些用户显式访问不到的文件要存储到这里,可读写。

获取Library目录

NSFileManager * defaultManager = [NSFileManager defaultManager];
    NSURL * applicationSupportPath = [[defaultManager URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask]firstObject];

获取Document目录

  NSFileManager * defaultManager = [NSFileManager defaultManager];
    NSURL * applicationSupportPath = [[defaultManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]firstObject];

读写Plist

Plist文件是iOS系统存储结构化数据的文件,方便用户进行读取(以Array和Dictionary的方式返回)。
写文件

    NSArray * array = @[@"1",@"2",@"3",@"4"];
    NSFileManager * defaultManager = [NSFileManager defaultManager];
    NSURL * documentPath = [[defaultManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]firstObject];
    NSString * fileSavePath = [documentPath.path stringByAppendingPathComponent:@"file.plist"];
    BOOL success =  [array writeToFile:fileSavePath atomically:YES];

写完之后,查看模拟器沙盒-写入成功,当然上述代码的返回值success也可以判断写入是否成功


读取文件

    NSFileManager * defaultManager = [NSFileManager defaultManager];
    NSURL * documentPath = [[defaultManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]firstObject];
    NSString * fileSavePath = [documentPath.path stringByAppendingPathComponent:@"file.plist"];
    NSArray * array = [NSArray arrayWithContentsOfFile:fileSavePath];
    NSLog(@"%@",array);

注意:如果上述代码的文件不存在,则读取结果为nil。这里不需要判断是否存在。


如何创建目录?

往自己新建目录里写文件的时候,一定要判断目录是否存在,否则程序会崩溃。
使用函数来判断

 - (BOOL)fileExistsAtPath:(NSString *)path isDirectory:(BOOL *)isDirectory

如果不存在,则要创建路径

 - (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(NSDictionary *)attributes error:(NSError **)error
  • createIntermediates 是创建所有不存在的父目录例如:…document/DicA/DicB/file.txt会自动创建多层目录。
  • attributes 通常为nil,用来设置权限,nil表示默认权限

例如
往Application Support/Demo/目录下写入,如果这个目录不存在,就创建

 NSDictionary * dic = @{@"name":@"Wenchenhuang",@"URL":@"blog.csdn.net/hello_hwc?viewmode=list"};
    NSFileManager * defaultManager = [NSFileManager defaultManager];
    NSURL * libraryPath = [[defaultManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask]firstObject];
    NSString * fileContainFloder = [libraryPath.path stringByAppendingPathComponent:@"DemoData"];
    BOOL isDic = YES;
    if (![defaultManager fileExistsAtPath:fileContainFloder isDirectory:&isDic]) {
        [defaultManager createDirectoryAtPath:fileContainFloder withIntermediateDirectories:YES attributes:nil error:nil];
    }
    NSString * fileSavePath = [fileContainFloder stringByAppendingPathComponent:@"file.plist"];
    BOOL success =  [dic writeToFile:fileSavePath atomically:YES];

再看看沙盒

Application Support这个目录是Library的子目录,文档上来看,这个目录用来存放常见的对用户透明的数据,CoreData就可以存在这里。


如何保存自定义的Model

通常,自定义的Model要想使用简单的方式写入到plist文件里,要遵循NSCoding协议。然后使用NSKeyedArchiver进行编码生成NSData,读取以后使用NSUnKeyedArchiver进行解码。
定义一个Model

自定义一个Model有很多地方要实现,例如NSCopying协议,hash,isEqual函数等等,也可以使用第三方库,不过超出了本文的范畴,后续我会讲解如何写好一个Model类,这里知道NSCoding协议即可。

#import <Foundation/Foundation.h>

@interface DemoUser : NSObject<NSCoding>
@property (copy,nonatomic) NSString * name;
@property (copy,nonatomic) NSString * uniqueID;
-(instancetype)initWithName:(NSString *)name UnqiueID:(NSString *)uniqueID;
@end
#import "DemoUser.h"

@implementation DemoUser
//协议的两个必需实现的方法
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
    self = [super init];
    if (!self) {
        return nil;
    }
    _uniqueID = [aDecoder decodeObjectForKey:@"KUnqiueID"];
    _name = [aDecoder decodeObjectForKey:@"KName"];
    return self;
}
-(void)encodeWithCoder:(NSCoder *)aCoder{
-(void)encodeWithCoder:(NSCoder *)aCoder{
    if (self.name != nil) {
        [aCoder encodeObject:self.name forKey:@"KName"];
    }
    if (self.uniqueID != nil) {
        [aCoder encodeObject:self.uniqueID forKey:@"KUnqiueID"];
    }
}
//一个初始化方法
-(instancetype)initWithName:(NSString *)name UnqiueID:(NSString *)uniqueID{
    if(self = [super init]){
        _name = name;
        _uniqueID = uniqueID;
    }
    return self;
}
@end

存入

    DemoUser * user = [[DemoUser alloc] initWithName:@"wenchenhuang" UnqiueID:@"123456"];
    NSMutableDictionary * dic = [[NSMutableDictionary alloc] init];
    [dic setObject:@"1.0 " forKey:@"version"];
    NSData * data = [NSKeyedArchiver archivedDataWithRootObject:user];
    [dic setObject:data forKey:@"user"];
    //Get path
    NSFileManager * defaultManager = [NSFileManager defaultManager];
    NSURL * applicationSupportPath = [[defaultManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask]firstObject];
    NSString * fileContainFloder = [applicationSupportPath.path stringByAppendingPathComponent:@"DemoData"];
    BOOL isDic = YES;
    if (![defaultManager fileExistsAtPath:fileContainFloder isDirectory:&isDic]) {
        [defaultManager createDirectoryAtPath:fileContainFloder withIntermediateDirectories:YES attributes:nil error:nil];
    }

    NSString * fileSavePath = [fileContainFloder stringByAppendingPathComponent:@"user.plist"];
    BOOL success =  [dic writeToFile:fileSavePath atomically:YES];

读出

    NSFileManager * defaultManager = [NSFileManager defaultManager];
    NSURL * applicationSupportPath = [[defaultManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask]firstObject];
    NSString * filePath = [applicationSupportPath.path stringByAppendingPathComponent:@"DemoData/user.plist"];
    NSDictionary * dic = [NSDictionary dictionaryWithContentsOfFile:filePath];
    NSString * version = [dic objectForKey:@"version"];
    NSData * data = [dic objectForKey:@"user"];
    DemoUser * user = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    NSLog(@"%@ %@",user.name,user.uniqueID);

这是我博客的iOS部分目录,或许这里你能找到想要的内容。
http://blog.csdn.net/hello_hwc/article/details/45365385

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值