配置iCloud
配置iCloud,首先你就先要有一個(gè)真實(shí)的蘋果開發(fā)者賬號(hào),沒錯(cuò)迫皱,就是一年688的那個(gè)。開通了之后辖众,在Xcode中新建一個(gè)項(xiàng)目卓起。然后在 TARGETS
-> Capabilities
-> iCloud
中打開開關(guān)就可以了。
就像這樣凹炸,是不是很簡(jiǎn)單啊戏阅。
誒,可是好像有什么地方不對(duì)啤它,有些地方爆紅了奕筐。
這是因?yàn)槲覀冞€沒有給這個(gè)App ID 注冊(cè),所以接下來我們?nèi)ヌO果的 開發(fā)者官網(wǎng) 添加一個(gè)App ID变骡,在添加的時(shí)候勾選 iCloud
服務(wù)就可以啦离赫。
什么?你說你已經(jīng)創(chuàng)建過App ID了锣光?笆怠??沒關(guān)系誊爹,在管理App ID這邊選擇 Edit
蹬刷,然后在勾選iCloud
也是一樣的瓢捉。
這時(shí)候回到Xcode中在看一下,應(yīng)該就已經(jīng)沒有爆紅了吧办成。
什么泡态??迂卢?還有爆紅某弦??而克? 那你重啟一下XCode試試吧靶壮。再不行,你重啟一下電腦試試好了员萍。
1腾降、Key-value storage
在Xcode中 iCloud
下邊一共有三個(gè)可以勾選的服務(wù),其中第一個(gè)就是key-value storage
碎绎,這個(gè)也是最簡(jiǎn)單的iCloud
使用方法了螃壤,他跟NSUserDefaults
的使用方法基本一樣,都是以鍵值對(duì)的方式存儲(chǔ)數(shù)據(jù)筋帖。只不過處理iCloud的類為NSUbiquitousKeyValueStore
奸晴。
存儲(chǔ)數(shù)據(jù)
存儲(chǔ)數(shù)據(jù)的方式很簡(jiǎn)單,只要使用 setObject:forkey:
之后日麸,使用synchronize
同步一下就可以了寄啼。
NSUbiquitousKeyValueStore *keyValueStore = [NSUbiquitousKeyValueStore defaultStore];
[keyValueStore setObject:@"test message" forKey:@"test"];
[keyValueStore synchronize];
獲取數(shù)據(jù)
獲取數(shù)據(jù)的方式也一樣,是要使用 objectForKey
就可以了赘淮。
NSUbiquitousKeyValueStore *keyValueStore = [NSUbiquitousKeyValueStore defaultStore];
NSString *testString = [keyValueStore objectForKey:@"test"];
NSLog(@"%@",testString);
數(shù)據(jù)改變通知
看一下NSUbiquitousKeyValueStore
的頭文件辕录,我們發(fā)現(xiàn)他還有一個(gè)通知消息
FOUNDATION_EXPORT NSNotificationName const NSUbiquitousKeyValueStoreDidChangeExternallyNotification API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
注冊(cè)這個(gè)通知睦霎,就可以在數(shù)據(jù)修改的時(shí)候接收到通知梢卸,然后做對(duì)應(yīng)的處理。最好的驗(yàn)證方法就是在存儲(chǔ)了數(shù)據(jù)之后直接刪除掉這個(gè)app副女,然后再次安裝蛤高,這個(gè)時(shí)候就會(huì)觸發(fā)該通知。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(storeDidChange:) name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification object:[NSUbiquitousKeyValueStore defaultStore]];
- (void)storeDidChange:(NSUbiquitousKeyValueStore *)defaultStore
{
NSLog(@"%@",defaultStore);
}
Demo
先放一下demo的[地址碑幅。
以上就是關(guān)于配置iCloud和key-value存儲(chǔ)的簡(jiǎn)單使用戴陡,后邊我們?cè)倏纯雌渌麅煞N服務(wù)是怎么樣使用的。
2沟涨、Documents數(shù)據(jù)的使用
相較于key-value的存儲(chǔ)類型恤批,Documents是用來管理一些比較大的文件,比如用戶創(chuàng)建的文檔等等裹赴。
基本概念
iCloud Entitlements
在我們打開iCloud選項(xiàng)的時(shí)候喜庞,系統(tǒng)就是自動(dòng)為我們添加一個(gè) xxx.entitlements
的文件诀浪,這個(gè)東西用來保證應(yīng)用的安全性,確保只有你的應(yīng)用才能訪問你自己創(chuàng)建的文檔延都,系統(tǒng)也是依賴于他來區(qū)分用戶的iCloud賬戶中每個(gè)應(yīng)用的文檔雷猪。
查看這個(gè)xxx.entitlements
我們會(huì)發(fā)現(xiàn)在他里邊有這樣的一個(gè)keyUbiquity Container Identifiers
,對(duì)應(yīng)的value為iCloud.$(CFBundleIdentifier)
晰房。其實(shí)這個(gè)$(CFBundleIdentifier)
就代表這你的APP ID求摇。所以也可以看成是iCloud.com.zzr.ZZRiCloudDemo
。
NSFileManager
NSFileManager
主要是對(duì)文件的操作殊者,我們用它來獲取iCloud的存儲(chǔ)地址与境。
根據(jù)我們的entitlements,通過NSFileManager
就可以獲得iCloud的存儲(chǔ)地址猖吴,在獲取地址之后嚷辅,我們要先判斷一下獲取的地址是否為空,如果這個(gè)地址為空距误,則說明用戶的iCloud暫時(shí)不可用簸搞,接下來一切的操作都沒辦法進(jìn)行下去。
//獲取地址
+ (NSURL *)getUbiquityContauneURLWithFileName:(NSString *)fileName
{
NSURL *ubiquityURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:UbiquityContainerIdentifiers];
//驗(yàn)證iCloud是否可用
if(!ubiquityURL)
{
NSLog(@"尚未開啟iCloud功能");
return nil;
}
NSURL *URLWithFileName = [ubiquityURL URLByAppendingPathComponent:@"Documents"];
URLWithFileName = [URLWithFileName URLByAppendingPathComponent:fileName];
return URLWithFileName;
}
UIDocument
UIDocument
主要是用于對(duì)文件內(nèi)容的操作准潭。
其實(shí)獲取了文件的地址之后趁俊,我們已經(jīng)可以直接對(duì)文件進(jìn)行操作了,但是官方還是讓我們通過UIDocument
來操作刑然,因?yàn)楫?dāng)我們?cè)趯?duì)iCloud進(jìn)行操作的時(shí)候寺擂,不止是只有我們自己對(duì)他進(jìn)行操作,iCloud daemon
也會(huì)對(duì)iCloud操作泼掠,用UIDocument
操作能夠保證存取安全怔软。
在使用UIDocument
之前,我們新建一個(gè)類择镇,繼承于UIDocument
挡逼,并且重寫兩個(gè)方法:
- (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
主要用來查詢數(shù)據(jù)。
增刪改查
創(chuàng)建文檔
有了之前的準(zhǔn)備工作腻豌,創(chuàng)建一個(gè)文檔就非常簡(jiǎn)單了家坎,只要?jiǎng)?chuàng)建好我們要保存的文件,通過
- (void)saveToURL:(NSURL *)url forSaveOperation:(UIDocumentSaveOperation)saveOperation completionHandler:(void (^ __nullable)(BOOL success))completionHandler __TVOS_PROHIBITED;
就可以將文檔上傳到iCloud中了吝梅。
我們以一個(gè)txt文件作為示范虱疏。
//創(chuàng)建文檔
+ (void)createDocument
{
NSString *fileName = @"test.txt";
NSURL *url = [iCloudHandle getUbiquityContauneURLWithFileName:fileName];
ZZRDocument *doc = [[ZZRDocument alloc] initWithFileURL:url];
NSString *docContent = @"iCloud Document 測(cè)試數(shù)據(jù)";
doc.myData = [docContent dataUsingEncoding:NSUTF8StringEncoding];
[doc saveToURL:url forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
if(success)
{
NSLog(@"創(chuàng)建文檔成功");
}
else
{
NSLog(@"創(chuàng)建文檔失敗");
}
}];
}
修改文檔
修改文檔,其實(shí)就是重寫文檔苏携,就是將上邊創(chuàng)建文檔中的UIDocumentSaveForCreating
改為UIDocumentSaveForOverwriting
做瞪。
//修改文檔 實(shí)際上是overwrite重寫
+ (void)overwriteDocument
{
NSString *fileName = @"test.txt";
NSURL *url = [iCloudHandle getUbiquityContauneURLWithFileName:fileName];
ZZRDocument *doc = [[ZZRDocument alloc] initWithFileURL:url];
NSString *docContent = @"iCloud Document 修改數(shù)據(jù)";
doc.myData = [docContent dataUsingEncoding:NSUTF8StringEncoding];
[doc saveToURL:url forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success) {
if(success)
{
NSLog(@"修改文檔成功");
}
else
{
NSLog(@"修改文檔失敗");
}
}];
}
刪除文檔
刪除文檔其實(shí)就是通過之前的地址獲取到文件,然后調(diào)用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(@"刪除文檔成功");
}
}
查詢文檔
之前講了增加装蓬、刪除衩侥、修改,好像增刪改查中只剩下查詢這個(gè)方法沒有介紹了矛物。查詢和前邊幾個(gè)有點(diǎn)不同茫死,他需要用到NSMetadataQuery
。
//獲取最新的數(shù)據(jù)
+ (void)getNewDocument:(NSMetadataQuery *)myMetadataQuery
{
[myMetadataQuery setSearchScopes:@[NSMetadataQueryUbiquitousDocumentsScope]];
[myMetadataQuery startQuery];
}
直接調(diào)用startQuery
開始查詢履羞,iCloud就已經(jīng)開始幫我們查詢了峦萎,查詢好之后,iCloud會(huì)通過通知來告訴我們查詢到了東西忆首。
所以我們注冊(cè)兩個(gè)通知
//獲取最新數(shù)據(jù)完成
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(finishedGetNewDocument:) name:NSMetadataQueryDidFinishGatheringNotification object:self.myMetadataQuery];
//數(shù)據(jù)更新通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(documentDidChange:) name:NSMetadataQueryDidUpdateNotification object:self.myMetadataQuery];
并相應(yīng)他們
- (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(@"讀取數(shù)據(jù)成功爱榔。");
NSString *docConten = [[NSString alloc] initWithData:doc.myData encoding:NSUTF8StringEncoding];
NSLog(@"%@",docConten);
}
}];
}];
}
- (void)documentDidChange:(NSMetadataQuery *)metadataQuery
{
NSLog(@"Document 數(shù)據(jù)更新");
}
其中
NSArray *item =self.myMetadataQuery.results;
就是查詢到的內(nèi)容的數(shù)組,遍歷他糙及,就可以獲取到對(duì)應(yīng)目錄下的全部文件了详幽。
Demo
先放一下demo的地址。
demo簡(jiǎn)單的制作了一個(gè)text文檔的存儲(chǔ)功能浸锨,一些交互沒有完善唇聘,但是基本的增刪改查功能都已經(jīng)實(shí)現(xiàn)了。
以上就是iCloud Document
的簡(jiǎn)單使用柱搜。此文章僅供個(gè)人學(xué)習(xí)使用迟郎,如有不當(dāng),希望大佬指出聪蘸。