上次說到了iCloud的簡單配置和key-value類型的簡單使用视事,這次我們來看一下另外一種類型Documents
類型的使用胆萧。
相較于key-value的存儲類型,Documents
是用來管理一些比較大的文件俐东,比如用戶創(chuàng)建的文檔等等跌穗。
基本概念
iCloud Entitlements
在我們打開iCloud選項的時候,系統(tǒng)就是自動為我們添加一個 xxx.entitlements
的文件犬性,這個東西用來保證應用的安全性瞻离,確保只有你的應用才能訪問你自己創(chuàng)建的文檔腾仅,系統(tǒng)也是依賴于他來區(qū)分用戶的iCloud賬戶中每個應用的文檔乒裆。
查看這個xxx.entitlements
我們會發(fā)現在他里邊有這樣的一個keyUbiquity Container Identifiers
,對應的value為iCloud.$(CFBundleIdentifier)
推励。其實這個$(CFBundleIdentifier)
就代表這你的APP ID鹤耍。所以也可以看成是iCloud.com.zzr.ZZRiCloudDemo
。
NSFileManager
NSFileManager
主要是對文件的操作验辞,我們用它來獲取iCloud的存儲地址稿黄。
根據我們的entitlements,通過NSFileManager
就可以獲得iCloud的存儲地址跌造,在獲取地址之后杆怕,我們要先判斷一下獲取的地址是否為空族购,如果這個地址為空,則說明用戶的iCloud暫時不可用陵珍,接下來一切的操作都沒辦法進行下去。
//獲取地址
+ (NSURL *)getUbiquityContauneURLWithFileName:(NSString *)fileName
{
NSURL *ubiquityURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:UbiquityContainerIdentifiers];
//驗證iCloud是否可用
if(!ubiquityURL)
{
NSLog(@"尚未開啟iCloud功能");
return nil;
}
NSURL *URLWithFileName = [ubiquityURL URLByAppendingPathComponent:@"Documents"];
URLWithFileName = [URLWithFileName URLByAppendingPathComponent:fileName];
return URLWithFileName;
}
UIDocument
UIDocument
主要是用于對文件內容的操作互纯。
其實獲取了文件的地址之后瑟幕,我們已經可以直接對文件進行操作了只盹,但是官方還是讓我們通過UIDocument
來操作殖卑,因為當我們在對iCloud進行操作的時候懦鼠,不止是只有我們自己對他進行操作肛冶,iCloud daemon
也會對iCloud操作,用UIDocument
操作能夠保證存取安全荣刑。
在使用UIDocument
之前馅笙,我們新建一個類,繼承于UIDocument
厉亏,并且重寫兩個方法:
- (BOOL)loadFromContents:(id)contents ofType:(NSString *)typeName error:(NSError * _Nullable __autoreleasing *)outError
{
self.myData = [contents copy];
return YES;
}
- (nullable id)contentsForType:(NSString *)typeName error:(NSError * _Nullable __autoreleasing *)outError
{
if(!self.myData)
{
self.myData = [[NSData alloc] init];
}
return self.myData;
}
NSMetadataQuery
NSMetadataQuery
主要用來查詢數據董习。
增刪改查
創(chuàng)建文檔
有了之前的準備工作,創(chuàng)建一個文檔就非常簡單了爱只,只要創(chuàng)建好我們要保存的文件皿淋,通過
- (void)saveToURL:(NSURL *)url forSaveOperation:(UIDocumentSaveOperation)saveOperation completionHandler:(void (^ __nullable)(BOOL success))completionHandler __TVOS_PROHIBITED;
就可以將文檔上傳到iCloud中了。
我們以一個txt文件作為示范恬试。
//創(chuàng)建文檔
+ (void)createDocument
{
NSString *fileName = @"test.txt";
NSURL *url = [iCloudHandle getUbiquityContauneURLWithFileName:fileName];
ZZRDocument *doc = [[ZZRDocument alloc] initWithFileURL:url];
NSString *docContent = @"iCloud Document 測試數據";
doc.myData = [docContent dataUsingEncoding:NSUTF8StringEncoding];
[doc saveToURL:url forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
if(success)
{
NSLog(@"創(chuàng)建文檔成功");
}
else
{
NSLog(@"創(chuàng)建文檔失敗");
}
}];
}
修改文檔
修改文檔窝趣,其實就是重寫文檔,就是將上邊創(chuàng)建文檔中的UIDocumentSaveForCreating
改為UIDocumentSaveForOverwriting
训柴。
//修改文檔 實際上是overwrite重寫
+ (void)overwriteDocument
{
NSString *fileName = @"test.txt";
NSURL *url = [iCloudHandle getUbiquityContauneURLWithFileName:fileName];
ZZRDocument *doc = [[ZZRDocument alloc] initWithFileURL:url];
NSString *docContent = @"iCloud Document 修改數據";
doc.myData = [docContent dataUsingEncoding:NSUTF8StringEncoding];
[doc saveToURL:url forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success) {
if(success)
{
NSLog(@"修改文檔成功");
}
else
{
NSLog(@"修改文檔失敗");
}
}];
}
刪除文檔
刪除文檔其實就是通過之前的地址獲取到文件哑舒,然后調用remove方法即可。
//刪除文檔
+ (void)removeDocument
{
NSString *fileName = @"test.txt";
NSURL *url = [iCloudHandle getUbiquityContauneURLWithFileName:fileName];
NSError *error;
[[NSFileManager defaultManager] removeItemAtURL:url error:&error];
if(error)
{
NSLog(@"刪除文檔失敗 %@",error);
}
else
{
NSLog(@"刪除文檔成功");
}
}
查詢文檔
之前講了增加幻馁、刪除洗鸵、修改越锈,好像增刪改查中只剩下查詢這個方法沒有介紹了。查詢和前邊幾個有點不同膘滨,他需要用到NSMetadataQuery
瞪浸。
//獲取最新的數據
+ (void)getNewDocument:(NSMetadataQuery *)myMetadataQuery
{
[myMetadataQuery setSearchScopes:@[NSMetadataQueryUbiquitousDocumentsScope]];
[myMetadataQuery startQuery];
}
直接調用startQuery
開始查詢,iCloud就已經開始幫我們查詢了吏祸,查詢好之后对蒲,iCloud會通過通知來告訴我們查詢到了東西。
所以我們注冊兩個通知
//獲取最新數據完成
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(finishedGetNewDocument:) name:NSMetadataQueryDidFinishGatheringNotification object:self.myMetadataQuery];
//數據更新通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(documentDidChange:) name:NSMetadataQueryDidUpdateNotification object:self.myMetadataQuery];
并相應他們
- (void)finishedGetNewDocument:(NSMetadataQuery *)metadataQuery
{
NSArray *item =self.myMetadataQuery.results;
[item enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSMetadataItem *item = obj;
//獲取文件名
NSString *fileName = [item valueForAttribute:NSMetadataItemFSNameKey];
//獲取文件創(chuàng)建日期
NSDate *date = [item valueForAttribute:NSMetadataItemFSContentChangeDateKey];
NSLog(@"%@,%@",fileName,date);
ZZRDocument *doc = [[ZZRDocument alloc] initWithFileURL:[iCloudHandle getUbiquityContauneURLWithFileName:fileName]];
[doc openWithCompletionHandler:^(BOOL success) {
if(success)
{
NSLog(@"讀取數據成功贡翘。");
NSString *docConten = [[NSString alloc] initWithData:doc.myData encoding:NSUTF8StringEncoding];
NSLog(@"%@",docConten);
}
}];
}];
}
- (void)documentDidChange:(NSMetadataQuery *)metadataQuery
{
NSLog(@"Document 數據更新");
}
其中
NSArray *item =self.myMetadataQuery.results;
就是查詢到的內容的數組蹈矮,遍歷他,就可以獲取到對應目錄下的全部文件了鸣驱。
Demo
先放一下demo的地址泛鸟。
demo簡單的制作了一個text文檔的存儲功能,一些交互沒有完善踊东,但是基本的增刪改查功能都已經實現了北滥。
以上就是iCloud Document
的簡單使用。此文章僅供個人學習使用闸翅,如有不當再芋,希望大佬指出。