IOS數(shù)據(jù)存儲有很多方式 今天主要講的是plist存儲
一.數(shù)據(jù)存儲主要方式
- XML屬性列表(plist)歸檔 /寫入Document目錄下 存儲 數(shù)組,字符串,字典等數(shù)據(jù)
- Preference(偏好設置) /我們一般使用它來進行一些設置的記錄,比如用戶名,開關是否打開等設置。
- NSKeyedArchiver歸檔(NSCoding)
- SQLite3
- Core Data
- keychain(SQLite API進行封裝的庫)
- FMDB
plist存儲
特點:只能存儲OC常用數(shù)據(jù)類型(NSString、NSDictionary、NSArray、NSData、NSNumber等類型)而不能直接存儲自定義模型對象
- 如果想存儲自定義模型對象 -> 只能將自定義模型對象轉換為字典存儲;
plist保存的地方
- 工程自身里(就是在工程里手動創(chuàng)建一個如.plist文件,把固定的內(nèi)容寫入,這個需要人工手動寫入)
- 工程沙盒里(保存到user Document下,不過不需要讀寫文件,用系統(tǒng)的 NSUserDefaults 可以快速保存添加讀取刪除基本數(shù)據(jù)類型 )
plist是什么
它全名是:Property List,屬性列表文件,它是一種用來存儲串行化后的對象的文件。屬性列表文件的擴展名為.plist ,因此通常被稱為 plist文件。文件是xml格式的。Plist文件通常用于儲存用戶設置,也可以用于存儲捆綁的信息。
使用plist——plist的讀取,修改和刪除
1. plist的讀取(使用在工程自身里的方式)
1.1 創(chuàng)建一項測試project
1.2 在plist中添加一些信息
1.3 讀取代碼
- (void)viewDidLoad {
[super viewDidLoad];
//讀取plist
[self getDataFromPlist];
}
- (void)getDataFromPlist {
NSString *plistPath = [[NSBundle mainBundle]pathForResource:@"PropertyListTest" ofType:@"plist"];
NSMutableDictionary *dataDic = [[NSMutableDictionary alloc]initWithContentsOfFile:plistPath];
NSLog(@"%@",dataDic);//直接打印數(shù)據(jù)
}
2. plist的存儲,讀取(工程沙盒里)
保存在工程自身的plist并不能修改寫入,所以這里需要通過沙盒路徑創(chuàng)建plist并修改保存,還有一個坑,模擬器與真機權限可能不一致,在模擬機上能夠通過nsbundle路徑修改成功,但是真機上并不能,所以建議需要修改的plist都使用沙盒路徑 來新建和修改并且兩者所獲取的plist并不是同一個文件,代碼解釋如下:
- (void)viewDidLoad {
[super viewDidLoad];
//讀取plist
[self getDataFromPlist];
// 寫入plist
[self writeDataToPlist];
}
- (void)getDataFromPlist {
//沙盒獲取路徑
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [pathArray objectAtIndex:0];
//獲取文件的完整路徑
NSString *filePatch = [path stringByAppendingPathComponent:@"PropertyListTest.plist"];//沒有會自動創(chuàng)建
NSLog(@"file patch%@",filePatch);
NSMutableDictionary *sandBoxDataDic = [[NSMutableDictionary alloc]initWithContentsOfFile:filePatch];
if (sandBoxDataDic==nil) {
sandBoxDataDic = [NSMutableDictionary new];
sandBoxDataDic[@"test"] = @"test";
[sandBoxDataDic writeToFile:filePatch atomically:YES];
}
NSLog(@"sandBox %@",sandBoxDataDic);//直接打印數(shù)據(jù)
}
- (void)writeDataToPlist {
//這里使用位于沙盒的plist(程序會自動新建的那一個)
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [pathArray objectAtIndex:0];
//獲取文件的完整路徑
NSString *filePatch = [path stringByAppendingPathComponent:@"PropertyListTest.plist"];
NSMutableDictionary *sandBoxDataDic = [[NSMutableDictionary alloc]initWithContentsOfFile:filePatch];
NSLog(@"old sandBox is %@",sandBoxDataDic);
sandBoxDataDic[@"test"] = @"hello world";
[sandBoxDataDic writeToFile:filePatch atomically:YES];
sandBoxDataDic = [[NSMutableDictionary alloc]initWithContentsOfFile:filePatch];
NSLog(@"new sandBox is %@",sandBoxDataDic);
}
//刪除整體文件
- (void)deleteField {
NSFileManager *manager=[NSFileManager defaultManager];
//文件路徑
NSString *filepath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:@"PropertyListTest.plist"];
[manager removeItemAtPath:filepath error:nil];
}
3. Preference
plist文件讀取的三種方式還有一種就是使用UserDefaults來訪問一個特殊的plist文件,使用方法簡單,不需要文件讀取,使用系統(tǒng)方法。
Preference是通過NSUserDefaults來使用的,是通過鍵值對的方式記錄設置。下面舉個例子。
// 啟動的時候判斷key有沒有value,如果有,說明已經(jīng)啟動過了,如果沒有,說明是第一次啟動
if (![[NSUserDefaults standardUserDefaults] valueForKey:@"first"]) {
//如果是第一次啟動,就運用偏好設置給key設置一個value
[[NSUserDefaults standardUserDefaults] setValue:@"start" forKey:@"first"];
NSLog(@"是第一次啟動");
} else {
NSLog(@"不是第一次啟動");
}
而如果需要存儲plist文件不支持的類型,比如圖片,可以先將其歸檔為NSData類型,再存入plist文件,需要注意的是,即使對象是NSArray或NSDictionary,他們存儲的類型也應該是以上范圍包括的。
存/讀不同類型數(shù)據(jù)
###存
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@”jack“ forKey:@"firstName"];
[defaults setInteger:10 forKey:@"Age"];
UIImage *image =[UIImage imageNamed:@"somename"];
NSData *imageData = UIImageJPEGRepresentation(image, 100);//把image歸檔為NSData
[defaults setObject:imageData forKey:@"image"];
[defaults synchronize];
其中,方法synchronise是為了強制存儲,其實并非必要,因為這個方法會在系統(tǒng)中默認調(diào)用,但是你確認需要馬上就存儲,這樣做是可行的。
###讀
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *firstName = [defaults objectForKey:@"firstName"]
NSInteger age = [defaults integerForKey:@"Age"];
NSData *imageData = [defaults dataForKey:@"image"];
UIImage *image = [UIImage imageWithData:imageData];
我們通過為三個數(shù)據(jù)設置key的方式把NSInteger、NSString和UIImage三種數(shù)據(jù)存儲下來,其中圖片是通過歸檔為NSData的方式進行存儲的,除此之外,還可以被轉為NSNumber或NSString類型。順便提一句,這里NSInteger沒有星號,因為NSInteger根據(jù)系統(tǒng)是64位還是32位來判斷自身是long還是int類型,并且它也不是一個標準Objective-C對象。
簡便方法存取不同類型數(shù)據(jù)
由上邊的例子可以看到一個方法-setInteger:,這跟常用的-setObject:相比設置類型更明確。其實,NSUserDefaults提供了若干簡便方法可以存儲某些常用類型的值,例如:
- setBool:forKey:
- setFloat:forKey:
- setInteger:forKey:
- setDouble:forKey:
- setURL:forKey:
這將使某些值的設置更簡單。
注意:
UserDefaults設置數(shù)據(jù)時,不是立即寫入,而是根據(jù)時間戳定時地把緩存中的數(shù)據(jù)寫入本地磁盤。所以調(diào)用了set方法之后數(shù)據(jù)有可能還沒有寫入磁盤應用程序就終止了。出現(xiàn)以上問題,可以通過調(diào)用synchornize方法強制寫入
以上是對NSUserDefaults的總結,如果后續(xù)發(fā)現(xiàn)錯誤,將會第一時間更新。