iOS 資料持久化之plist
前言:上一篇文章提到了如何使用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 @interface DemoUser : NSObject@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