iOS資料本地持久化

來源:互聯網
上載者:User

標籤:

 p1:
iOS開發中本機存放區主要有三種形式
  • XML屬性列表(plist)歸檔
  • Preference(喜好設定)
  • NSKeyedArchiver歸檔(NSCoding)
應用沙箱
什麼是應用沙箱

要想在本機存放區資料,那就要知道一下什麼是應用沙箱 ,其實很好理解應用沙箱就是應用的檔案夾,與其他檔案系統隔離。每一個iOS應用都有自己的應用沙箱,應用必須待在自己的沙箱裡,其它應用不能訪問該沙箱。
如何擷取應用沙箱路徑,可以通過列印NSHomeDirectory()來擷取應用沙箱路徑,為列印路徑結果:


螢幕快照 2015-12-03 22.10.07.png


Melody_Zhy 是使用者檔案夾(樣子是個小房子)
3CEC8EEB-C230-44BE-93B7-DF3B9A120A94 iOS8之後每次運行Xcode都會產生不同的沙箱路徑,不同之處就是最後這個檔案夾名,可能是蘋果為了安全著想

應用沙箱結構分析

首先我們先來看下,應用沙箱裡面都有什麼


螢幕快照 2015-12-03 22.27.50.png


這裡提一下Finder的快速鍵 shift + com + g 可以前往任意路徑的檔案夾,因此我們可以列印沙箱路徑之後將沙箱路徑複製到Finder前往路徑檔案夾中,前往應用沙箱。這是一個比較耽誤事的方法!幸好有一款叫做simpholders的app,它可以很簡單的訪問應用的沙箱路徑,記得去下載simpholders2哦,第一代iOS8之後就不能用了,app很簡單易懂,用下就會了~
現在我們來看看應用沙箱裡面這些檔案夾都是做什麼用的

  • Documents :儲存應用運行時產生的需要持久化的資料,iTunes同步裝置時會備份該目錄。例如,遊戲應用可將遊戲存檔儲存在該目錄
  • Library/Caches : 儲存應用運行時產生的需要持久化的資料,iTunes同步裝置時不會備份該目錄。一般儲存體積大、不需要備份的非重要資料 
  • Library/Preference : 儲存應用的所有喜好設定,iOS的Settings(設定)應用會在該目錄中尋找應用的設定資訊。iTunes同步裝置時會備份該目錄
  • tmp : 儲存應用運行時所需的臨時資料,使用完畢後再將相應的檔案從該目錄刪除。應用沒有運行時,系統也可能會清除該目錄下的檔案。iTunes同步裝置時不會備份該目錄
應用沙箱目錄的常見擷取方式
沙箱根目錄的擷取方式

正如上面我們所說:

NSString *home = NSHomeDirectory();
Documents檔案夾的擷取方式(3種)

第一種( !笨!)

// 利用沙箱根目錄拼接字串NSString *homePath = NSHomeDirectory();NSString *docPath = [homePath stringByAppendingString:@"/Documents"];

第二種( !還??!)

// 利用沙箱根目錄拼接”Documents”字串NSString *homePath = NSHomeDirectory();NSString *docPath = [homePath stringByAppendingPathComponent:@"Documents"];

但是不建議使用這種方法,因為不定哪天蘋果大大就把檔案名稱改了呢-_-!

第三種( !~推薦~ !)

// NSDocumentDirectory 要尋找的檔案// NSUserDomainMask 代表從使用者檔案夾下找// 在iOS中,只有一個目錄跟傳入的參數匹配,所以這個集合裡面只有一個元素NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];NSString *filePath = [path stringByAppendingPathComponent:@"xxx.plist"];

這裡我來詳細的說下NSSearchPathForDirectoriesInDomains這個方法的幾個參數 :
<#NSSearchPathDirectory directory#> 這個參數代表要尋找的檔案,是個枚舉! 枚舉你懂的點擊去看看就知道了~
<#NSSearchPathDomainMask domainMask#> 這個參數代表從使用者檔案夾下找,也是枚舉!
最後一個參數如果是NO的話,列印的路徑會是這種形式~/Documents,我們一般都會用YES,這樣可以擷取完整路徑字串!
這個方法的傳回值是一個數組,但在iOS中,只有一個目錄跟傳入的參數匹配,所以這個集合裡面只有一個元素,所以我們取第一個元素!

Library/Caches檔案夾的擷取方式(跟上面的方法相似)

這裡我只用上面的第三種方法!注意第一個參數!

NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];NSString *filePath = [path stringByAppendingPathComponent:@"student.data"];
tmp檔案夾的擷取方式
NSString *tmp= NSTemporaryDirectory();
Library/Preference檔案夾的擷取方式

通過NSUserDefaults類存取該目錄下的設定資訊!
!!!這個下面會有介紹!!!

XML屬性列表(plist)歸檔
plist檔案

plist的根Type只能是字典(NSDictionary)或者是數組(NSArray)所以歸檔時我們只能將數組或字典儲存到plist檔案中,但是NSString也能通過歸檔儲存到plist檔案中同時它也可以通過stringWithContentsOfFile解檔,它儲存到plist中時Type是空的,Value是有值的!

plist檔案的歸檔
NSArray *arr = [[NSArray alloc] initWithObjects:@"1", @"2", nil];// NSDocumentDirectory 要尋找的檔案// NSUserDomainMask 代表從使用者檔案夾下找// 在iOS中,只有一個目錄跟傳入的參數匹配,所以這個集合裡面只有一個元素NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];NSString *filePath = [path stringByAppendingPathComponent:@"xxx.plist"];[arr writeToFile:filePath atomically:YES];
plist檔案的解檔
NSString *filePath = [path stringByAppendingPathComponent:@"xxx.plist"];// 解檔NSArray *arr = [NSArray arrayWithContentsOfFile:filePath];NSLog(@"%@", arr);
Preference(喜好設定)

OC中有一個NSUserDefaults的單例,它可以用來儲存使用者的喜好設定,例如:使用者名稱,字型的大小,使用者的一些設定等,下面我用兩個UISwitch來示範如何儲存使用者佈建開關的關閉狀態

儲存使用者喜好設定
// 擷取使用者喜好設定對象NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];// 儲存使用者喜好設定[defaults setBool:self.one.isOn forKey:@"one"];[defaults setBool:self.two.isOn forKey:@"two"];// 注意:UserDefaults設定資料時,不是立即寫入,而是根據時間戳記定時地把緩衝中的資料寫入本地磁碟。所以調用了set方法之後資料有可能還沒有寫入磁碟應用程式就終止了。// 出現以上問題,可以通過調用synchornize方法強制寫入// 現在這個版本不用寫也會馬上寫入 不過之前的版本不會[defaults synchronize];
讀取使用者喜好設定
// 讀取使用者喜好設定NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; self.one.on = [defaults boolForKey:@"one"];self.two.on = [defaults boolForKey:@"two"];
NSKeyedArchiver歸檔(NSCoding)

只有遵守了NSCoding協議的類才可以用NSKeyedArchiver歸檔和NSKeyedUnarchiver解檔,如果對象是NSString、NSDictionary、NSArray、NSData、NSNumber等類型,可以直接用NSKeyedArchiver歸檔和NSKeyedUnarchiver解檔~
下面我舉的??是歸檔解檔一個Student模型,因此該模型應該遵守NSCoding協議

實現encodeWithCoder和initWithCoder方法
- (void)encodeWithCoder:(NSCoder *)coder{[coder encodeObject:self.name forKey:@"name"];[coder encodeInteger:self.age forKey:@"age"];}- (instancetype)initWithCoder:(NSCoder *)coder{self = [super init];if (self) {    self.age = [coder decodeIntegerForKey:@"age"];    self.name = [coder decodeObjectForKey:@"name"];}return self;}
歸檔
Student *s1 = [[Student alloc] init];s1.name = @"zzz";s1.age = 18;NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];// 這個檔案尾碼可以是任意的,只要不與熱門檔案的尾碼重複即可,我喜歡用dataNSString *filePath = [path stringByAppendingPathComponent:@"student.data"];// 歸檔[NSKeyedArchiver archiveRootObject:s1 toFile:filePath];
解檔
NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];NSString *filePath = [path stringByAppendingPathComponent:@"student.data"];// 解檔Student *s = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];NSLog(@"%@----%ld", s.name, s.age);

相關連結:iOS開發中本機資料儲存的總結

p2:

ios的機密資料用KeyChain儲存

相關連結:ios KeyChain中儲存資料

              ios KeyChain項目中應用到的內容

 

 

p3:

相關連結:使用ASIHTTPRequest和ASIDownloadCache實現本機快取

1、設定全域的Cache
    在AppDelegate.h中添加一個全域變數

 

[plain] view plaincopy 
  1. @interface AppDelegate : UIResponder   
  2. {  
  3.     ASIDownloadCache *myCache;  
  4. }  
  5. @property (strong, nonatomic) UIWindow *window;  
  6. @property (nonatomic,retain) ASIDownloadCache *myCache;  

   在AppDelegate.m中的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中添加如下代碼

 

 

[plain] view plaincopy 
  1. //自訂緩衝  
  2. ASIDownloadCache *cache = [[ASIDownloadCache alloc] init];  
  3. self.myCache = cache;  
  4. [cache release];  
  5.       
  6. //設定緩衝路徑  
  7. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
  8. NSString *documentDirectory = [paths objectAtIndex:0];  
  9. [self.myCache setStoragePath:[documentDirectory stringByAppendingPathComponent:@"resource"]];  
  10. [self.myCache setDefaultCachePolicy:ASIOnlyLoadIfNotCachedCachePolicy];  
    

 

    在AppDelegate.m中的dealloc方法中添加如下語句

 

[plain] view plaincopy 
  1. [myCache release];  

    到這裡為止,就完成了全域變數的聲明。

 

    2、設定緩衝策略

    在實現ASIHTTPRequest請求的地方設定request的儲存方式,代碼如下

 

[plain] view plaincopy 
  1. NSString *str = @"http://....../getPictureNews.aspx";  
  2. NSURL *url = [NSURL URLWithString:str];  
  3. ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];  
  4. //擷取全域變數  
  5. AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];  
  6. //設定緩衝方式  
  7. [request setDownloadCache:appDelegate.myCache];  
  8. //設定快取資料儲存策略,這裡採取的是如果無更新或無法連網就讀取快取資料  
  9. [request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];  
  10. request.delegate = self;  
  11. [request startAsynchronous];  

    3、清理快取資料

 

    我在這裡採用的是手動清理資料的方式,在適當的地方添加如下代碼,我將清理緩衝放在了應用的設定模組:

 

[plain] view plaincopy 
  1. AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];  
  2. [appDelegate.myCache clearCachedResponsesForStoragePolicy:ASICachePermanentlyCacheStoragePolicy];  

 

 

    這裡清理的是ASICachePermanentlyCacheStoragePolicy這種儲存策略的快取資料,如果更換其他的參數的話,即可清理對應儲存策略的快取資料。(參考:http://zycto.blog.163.com/blog/static/17152400201110221340738/)

iOS資料本地持久化

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.