IOS數(shù)據(jù)存儲常用方式(一)plist

IOS數(shù)據(jù)存儲有很多方式 今天主要講的是plist存儲

一.數(shù)據(jù)存儲主要方式

  1. XML屬性列表(plist)歸檔 /寫入Document目錄下 存儲 數(shù)組,字符串,字典等數(shù)據(jù)
  2. Preference(偏好設置) /我們一般使用它來進行一些設置的記錄,比如用戶名,開關是否打開等設置。
  3. NSKeyedArchiver歸檔(NSCoding)
  4. SQLite3
  5. Core Data
  6. keychain(SQLite API進行封裝的庫)
  7. FMDB

plist存儲

特點:只能存儲OC常用數(shù)據(jù)類型(NSString、NSDictionary、NSArray、NSData、NSNumber等類型)而不能直接存儲自定義模型對象

  • 如果想存儲自定義模型對象 -> 只能將自定義模型對象轉換為字典存儲;

plist保存的地方

  1. 工程自身里(就是在工程里手動創(chuàng)建一個如.plist文件,把固定的內(nèi)容寫入,這個需要人工手動寫入)
  2. 工程沙盒里(保存到user Document下,不過不需要讀寫文件,用系統(tǒng)的 NSUserDefaults 可以快速保存添加讀取刪除基本數(shù)據(jù)類型 )

plist是什么

它全名是:Property List,屬性列表文件,它是一種用來存儲串行化后的對象的文件。屬性列表文件的擴展名為.plist ,因此通常被稱為 plist文件。文件是xml格式的。Plist文件通常用于儲存用戶設置,也可以用于存儲捆綁的信息。

使用plist——plist的讀取,修改和刪除

1. plist的讀取(使用在工程自身里的方式)

1.1 創(chuàng)建一項測試project

image.png

1.2 在plist中添加一些信息

image.png

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);
}
image.png
//刪除整體文件
- (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)錯誤,將會第一時間更新。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容