好了者填,看完了key-value
,看完了Document
的存儲(chǔ)露戒,終于到了Cloud kit
的使用了。
比起前邊的兩種捶箱,Cloud kit
更像是一個(gè)數(shù)據(jù)庫(kù)智什。蘋果會(huì)提供一個(gè)dashboard作為云存儲(chǔ)的管理端。
Cloud Kit 基礎(chǔ)
cloud kit一共有7個(gè)基礎(chǔ)類丁屎,簡(jiǎn)單了解一下這些基礎(chǔ)類接下來的使用就比較容易理解了荠锭。
CKContainer
CKContainer
類似于應(yīng)用運(yùn)行時(shí)的沙盒,一個(gè)應(yīng)用只能訪問自己的沙盒晨川,同樣的证九,一個(gè)應(yīng)用也只能訪問自己的Container删豺。
通過初始化之后就可以使用
CKContainer *container = [CKContainer defaultContainer];
CKDatabase
CKDatabase
很明顯就是數(shù)據(jù)庫(kù),他擁有私有數(shù)據(jù)庫(kù)和公有數(shù)據(jù)庫(kù)兩種類型愧怜。用戶只能訪問自己的私有數(shù)據(jù)庫(kù)呀页,一些不敏感的數(shù)據(jù)也可以存儲(chǔ)在公有數(shù)據(jù)庫(kù)中。
//公有數(shù)據(jù)庫(kù)
CKDatabase *datebase = container.publicCloudDatabase;
//私有數(shù)據(jù)庫(kù)
CKDatabase *datebase = container.privateCloudDatabase;
CKRecord
CKRecord
就是數(shù)據(jù)庫(kù)中的一條數(shù)據(jù)記錄拥坛,他通過key-value的方式來存儲(chǔ)和獲取數(shù)據(jù)蓬蝶。目前可以支持如下格式的數(shù)據(jù):
NSString(swift中的Sting)
NSNumber
NSData
NSDate
CLLocation
CKReference
CKAsset
其中圖片的數(shù)據(jù)類型需要先初始化一個(gè)URL,然后把圖片保存到本地沙盒猜惋,生成URL丸氛,再創(chuàng)建CKAsset
來存儲(chǔ)。
CKRecordZone
CKRecordZone
是用來保存Record
的著摔。所有的Record
都是保存在這里缓窜,應(yīng)用有一個(gè)默認(rèn)的zone
,也可以自定義zone
梨撞。
CKRecordIdentifier
CKRecordIdentifier
是Record
的唯一標(biāo)示雹洗,用來確定Record
在數(shù)據(jù)庫(kù)中的位置。
CKReference
CKReference
是一種引用關(guān)系卧波。
CKAsset
CKAsset
為資源文件,比如之前提到的照片就是用這種方式存儲(chǔ)的庇茫。
CloudKit Dashboard
更新:
這里還有一個(gè)WWDC的視頻介紹Cloud dashboard
Build Better Apps with CloudKit Dashboard]
CloudKit Dashboard 的入口在這里:
你也可以直接訪問地址港粱。
這個(gè)界面好像更新過了,和網(wǎng)上很多教程的樣式都不太一樣旦签。新的界面長(zhǎng)這樣:
新的界面包括開發(fā)版和產(chǎn)品版(線上版)兩種查坪,在開發(fā)的時(shí)候我們就只針對(duì)左邊的開發(fā)版進(jìn)行操作就可以了。無論是那個(gè)版本宁炫,都有五個(gè)相同的入口偿曙。
Data
Cloud kit的數(shù)據(jù)管理中心入口。在這里可以進(jìn)行數(shù)據(jù)的字段羔巢,索引等內(nèi)容設(shè)定望忆。
Logs
查看Cloud kit的服務(wù)日志,顯示數(shù)據(jù)庫(kù)操作竿秆,推送通知以及對(duì)應(yīng)環(huán)境中的其他活動(dòng)启摄。
Telemetry
查看對(duì)應(yīng)環(huán)境中服務(wù)器端性能和數(shù)據(jù)庫(kù)利用率的圖表。
Public Database Usage
查看公共數(shù)據(jù)庫(kù)的使用情況圖標(biāo)幽钢,包括活躍用戶歉备、請(qǐng)求頻率等。
Api Access
管理API令牌和服務(wù)器密鑰匪燕,允許對(duì)應(yīng)環(huán)境進(jìn)行web服務(wù)調(diào)用蕾羊。
使用
這次我們只講簡(jiǎn)單的操作喧笔,所以本篇文章就只使用 Data中的部分功能。
創(chuàng)建 RECORD TYPE
首先點(diǎn)擊Data , RECORD TYPE , Create New Type創(chuàng)建一個(gè)新的RECORD TYPE龟再。
這里注意书闸,我們的RECORD TYPE Name 是Note,這個(gè)在之后代碼里操作非常重要吸申,所以記得不要寫錯(cuò)了梗劫。
添加 Field
有了表,接下來就是添加字段了截碴。點(diǎn)擊Add Field 然后輸入字段名梳侨,選擇類型就可以了。這里可以一次性添加多條日丹,添加完點(diǎn)擊保存就可以了走哺。
添加的內(nèi)容有:
title String
content String
photo Asset
添加 indexs
為了搜索更方便一些,我們添加一些索引哲虾。
點(diǎn)擊INDEXS丙躏,選擇我們剛剛添加的Note,然后添加索引束凑,添加的索引類型有QUERYABLE,SEARCHABLE,SORTABLE晒旅。
添加的內(nèi)容有:
title QUERYABLE
title SEARCHABLE
title SORTABLE
content QUERYABLE
content SEARCHABLE
content SORTABLE
recordName QUERYABLE
添加完就是這樣的,對(duì)照一下看看有沒有添加錯(cuò)啊汪诉。
添加數(shù)據(jù)
接下來废恋,我們就可以給表里添加數(shù)據(jù)了。
選擇RECORD ,確認(rèn)LOAD RECORDS FROM和QUERY FOR RECORDS OF TYPE 都正確了之后扒寄,點(diǎn)擊Creat New Record...鱼鼓,在右邊輸入想要插入的數(shù)據(jù),添加個(gè)幾條就可以了该编。
查詢數(shù)據(jù)
隨便添加幾條數(shù)據(jù)之后迄本,還是在這個(gè)頁(yè)面,點(diǎn)擊左側(cè)的Query Records课竣,就可以查詢到數(shù)據(jù)了嘉赎。
到此,Cloud Dashboard的簡(jiǎn)單使用就介紹到這稠氮,接下來我們看看通過代碼怎么來操作Cloud kit曹阔。
擼起袖子寫代碼吧。
通過代碼操作 Cloud Kit
使用Cloud Kit時(shí)隔披,首先要先引入Cloud kit的框架赃份。
#import <CloudKit/CloudKit.h>
添加數(shù)據(jù)
首先創(chuàng)建一個(gè)容器
//獲取容器
CKContainer *container = [CKContainer defaultContainer];
然后獲取數(shù)據(jù)庫(kù),這里我們使用公有數(shù)據(jù)庫(kù)
//公共數(shù)據(jù)
CKDatabase *datebase = container.publicCloudDatabase;
接下來創(chuàng)建一條數(shù)據(jù),這里的RECORD_TYPE_NAME
就是之前創(chuàng)建表的名字Note
//創(chuàng)建保存數(shù)據(jù)
CKRecord *noteRecord = [[CKRecord alloc] initWithRecordType:RECORD_TYPE_NAME];
添加數(shù)據(jù)是使用Key-value的方式抓韩。
[noteRecord setValue:title forKey:@"title"];
[noteRecord setValue:content forKey:@"content"];
這里要特殊注意的是圖片的處理纠永,我們先要?jiǎng)?chuàng)建一個(gè)URL,然后把圖片數(shù)據(jù)保存到沙盒中谒拴,生成一個(gè)URL尝江,再創(chuàng)建CKAsset。
NSDate *dateID = [NSDate dateWithTimeIntervalSinceNow:0];
NSTimeInterval timeInterval = [dateID timeIntervalSince1970] * 1000; //*1000表示到毫秒級(jí)英上,這樣可以保證不會(huì)同時(shí)生成兩個(gè)同樣的id
NSString *idString = [NSString stringWithFormat:@"%.0f", timeInterval];
NSString *filePath = [NSString stringWithFormat:@"%@/%@",tempPath,idString];
NSURL *url = [NSURL fileURLWithPath:filePath];
[imageData writeToURL:url atomically:YES];
CKAsset *asset = [[CKAsset alloc]initWithFileURL:url];
[noteRecord setValue:asset forKey:@"photo"];
對(duì)了炭序,還有CKAsset轉(zhuǎn)UIImage的方法:
CKAsset *asset = [record objectForKey:@"photo"];
UIImage *image = [UIImage imageWithContentsOfFile:asset.fileURL.path];
這樣數(shù)據(jù)的內(nèi)容就處理好了,接下來我們只要把它保存起來就可以咯苍日。
[datebase saveRecord:noteRecord completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
if(!error)
{
NSLog(@"保存成功");
}
else
{
NSLog(@"保存失敗");
NSLog(@"%@",error.description);
}
}];
整個(gè)代碼合起來就是這樣的:
+ (void)saveCloudKitModelWithTitle:(NSString *)title content:(NSString *)content photoImage:(UIImage *)image
{
//獲取容器
CKContainer *container = [CKContainer defaultContainer];
//公共數(shù)據(jù)
CKDatabase *datebase = container.publicCloudDatabase;
// //私有數(shù)據(jù)
// CKDatabase *datebase = container.privateCloudDatabase;
// //創(chuàng)建主鍵
// CKRecordID *noteID = [[CKRecordID alloc] initWithRecordName:@"NoteID"];
//創(chuàng)建保存數(shù)據(jù)
CKRecord *noteRecord = [[CKRecord alloc] initWithRecordType:RECORD_TYPE_NAME];
NSData *imageData = UIImagePNGRepresentation(image);
if (imageData == nil)
{
imageData = UIImageJPEGRepresentation(image, 0.6);
}
NSString *tempPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/imagesTemp"];
NSFileManager *manager = [NSFileManager defaultManager];
if (![manager fileExistsAtPath:tempPath]) {
[manager createDirectoryAtPath:tempPath withIntermediateDirectories:YES attributes:nil error:nil];
}
NSDate *dateID = [NSDate dateWithTimeIntervalSinceNow:0];
NSTimeInterval timeInterval = [dateID timeIntervalSince1970] * 1000; //*1000表示到毫秒級(jí)惭聂,這樣可以保證不會(huì)同時(shí)生成兩個(gè)同樣的id
NSString *idString = [NSString stringWithFormat:@"%.0f", timeInterval];
NSString *filePath = [NSString stringWithFormat:@"%@/%@",tempPath,idString];
NSURL *url = [NSURL fileURLWithPath:filePath];
[imageData writeToURL:url atomically:YES];
CKAsset *asset = [[CKAsset alloc]initWithFileURL:url];
[noteRecord setValue:title forKey:@"title"];
[noteRecord setValue:content forKey:@"content"];
[noteRecord setValue:asset forKey:@"photo"];
[datebase saveRecord:noteRecord completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
if(!error)
{
NSLog(@"保存成功");
}
else
{
NSLog(@"保存失敗");
NSLog(@"%@",error.description);
}
}];
}
查詢數(shù)據(jù)
查詢所有數(shù)據(jù)
查詢數(shù)據(jù)同樣,我們也要先獲取容器和數(shù)據(jù)庫(kù)相恃。
//獲取位置
CKContainer *container = [CKContainer defaultContainer];
CKDatabase *database = container.publicCloudDatabase;
之后我們添加一個(gè)查詢的條件辜纲,cloud kit和core data一樣,都是使用NSPredicate
拦耐。
而且還要用到CKQuery
這個(gè)類耕腾。
//添加查詢條件
NSPredicate *predicate = [NSPredicate predicateWithValue:YES];
CKQuery *query = [[CKQuery alloc] initWithRecordType:RECORD_TYPE_NAME predicate:predicate];
準(zhǔn)備好了,接下來就可以調(diào)用查詢方法了杀糯,獲取到的results就是獲取到數(shù)據(jù)的數(shù)組了扫俺,這里我用了通知的方法把查詢到的數(shù)據(jù)傳出去。
//開始查詢
[database performQuery:query inZoneWithID:nil completionHandler:^(NSArray<CKRecord *> * _Nullable results, NSError * _Nullable error) {
NSLog(@"%@",results);
//把數(shù)據(jù)做成字典通知出去
NSDictionary *userinfoDic = [NSDictionary dictionaryWithObject:results forKey:@"key"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"CloudDataQueryFinished" object:nil userInfo:userinfoDic];
}];
整個(gè)代碼合起來就是這樣的:
//查詢數(shù)據(jù)
+ (void)queryCloudKitData
{
//獲取位置
CKContainer *container = [CKContainer defaultContainer];
CKDatabase *database = container.publicCloudDatabase;
//添加查詢條件
NSPredicate *predicate = [NSPredicate predicateWithValue:YES];
CKQuery *query = [[CKQuery alloc] initWithRecordType:RECORD_TYPE_NAME predicate:predicate];
//開始查詢
[database performQuery:query inZoneWithID:nil completionHandler:^(NSArray<CKRecord *> * _Nullable results, NSError * _Nullable error) {
NSLog(@"%@",results);
//把數(shù)據(jù)做成字典通知出去
NSDictionary *userinfoDic = [NSDictionary dictionaryWithObject:results forKey:@"key"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"CloudDataQueryFinished" object:nil userInfo:userinfoDic];
}];
}
查詢單個(gè)數(shù)據(jù)
同樣也是獲取容器和數(shù)據(jù)庫(kù)固翰。
//獲取位置
CKContainer *container = [CKContainer defaultContainer];
CKDatabase *database = container.publicCloudDatabase;
然后我們需要獲取查詢的數(shù)據(jù)的RecordID牵舵。
[database fetchRecordWithID:recordID completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"%@",record);
//把數(shù)據(jù)做成字典通知出去
NSDictionary *userinfoDic = [NSDictionary dictionaryWithObject:record forKey:@"key"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"CloudDataSingleQueryFinished" object:nil userInfo:userinfoDic];
});
}];
合起來代碼就是這樣的:
//查詢單條數(shù)據(jù)
+ (void)querySingleRecordWithRecordID:(CKRecordID *)recordID
{
//獲取容器
CKContainer *container = [CKContainer defaultContainer];
//獲取公有數(shù)據(jù)庫(kù)
CKDatabase *database = container.publicCloudDatabase;
[database fetchRecordWithID:recordID completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"%@",record);
//把數(shù)據(jù)做成字典通知出去
NSDictionary *userinfoDic = [NSDictionary dictionaryWithObject:record forKey:@"key"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"CloudDataSingleQueryFinished" object:nil userInfo:userinfoDic];
});
}];
}
刪除數(shù)據(jù)
刪除數(shù)據(jù)同樣,我們也要先獲取容器和數(shù)據(jù)庫(kù)倦挂。
//獲取位置
CKContainer *container = [CKContainer defaultContainer];
CKDatabase *database = container.publicCloudDatabase;
然后,在刪除數(shù)據(jù)時(shí)担巩,要獲取到你要?jiǎng)h除的數(shù)據(jù)的RecordID方援,之后直接執(zhí)行刪除方法即可
[database deleteRecordWithID:recordID completionHandler:^(CKRecordID * _Nullable recordID, NSError * _Nullable error) {
if(error)
{
NSLog(@"刪除失敗");
}
else
{
NSLog(@"刪除成功");
}
}];
合起來代碼就是這樣
//刪除數(shù)據(jù)
+ (void)removeCloudKitDataWithRecordID:(CKRecordID *)recordID
{
CKContainer *container = [CKContainer defaultContainer];
CKDatabase *database = container.publicCloudDatabase;
[database deleteRecordWithID:recordID completionHandler:^(CKRecordID * _Nullable recordID, NSError * _Nullable error) {
if(error)
{
NSLog(@"刪除失敗");
}
else
{
NSLog(@"刪除成功");
}
}];
}
修改數(shù)據(jù)
還是那句話,先獲取容器
CKContainer *container = [CKContainer defaultContainer];
CKDatabase *database = container.publicCloudDatabase;
其實(shí)修改數(shù)據(jù)就是重新把數(shù)據(jù)寫入涛癌。在寫入的時(shí)候如果選擇之前沒有的key犯戏,就相當(dāng)于新增了一個(gè)字段。然后執(zhí)行保存操作就可以了拳话。
直接上全部的代碼好了:
//修改數(shù)據(jù)
+ (void)changeCloudKitWithTitle:(NSString *)title content:(NSString *)content photoImage:(UIImage *)image RecordID:(CKRecordID *)recordID
{
//獲取容器
CKContainer *container = [CKContainer defaultContainer];
//獲取公有數(shù)據(jù)庫(kù)
CKDatabase *database = container.publicCloudDatabase;
[database fetchRecordWithID:recordID completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
NSData *imageData = UIImagePNGRepresentation(image);
if (imageData == nil)
{
imageData = UIImageJPEGRepresentation(image, 0.6);
}
NSString *tempPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/imagesTemp"];
NSFileManager *manager = [NSFileManager defaultManager];
if (![manager fileExistsAtPath:tempPath]) {
[manager createDirectoryAtPath:tempPath withIntermediateDirectories:YES attributes:nil error:nil];
}
NSDate *dateID = [NSDate dateWithTimeIntervalSinceNow:0];
NSTimeInterval timeInterval = [dateID timeIntervalSince1970] * 1000; //*1000表示到毫秒級(jí)先匪,這樣可以保證不會(huì)同時(shí)生成兩個(gè)同樣的id
NSString *idString = [NSString stringWithFormat:@"%.0f", timeInterval];
NSString *filePath = [NSString stringWithFormat:@"%@/%@",tempPath,idString];
NSURL *url = [NSURL fileURLWithPath:filePath];
[imageData writeToURL:url atomically:YES];
CKAsset *asset = [[CKAsset alloc]initWithFileURL:url];
[record setObject:title forKey:@"title"];
[record setObject:content forKey:@"content"];
[record setValue:asset forKey:@"photo"];
[database saveRecord:record completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
if(error)
{
NSLog(@"修改失敗 %@",error.description);
}
else
{
NSLog(@"修改成功");
}
}];
}];
}
Demo
先放一下demo的地址。
demo簡(jiǎn)單的制作了一個(gè)簡(jiǎn)單的cloud kit存儲(chǔ)功能弃衍,一些交互沒有完善呀非,但是基本的增刪改查功能都已經(jīng)實(shí)現(xiàn)了。
以上就是Cloud Kit
的簡(jiǎn)單使用。此文章僅供個(gè)人學(xué)習(xí)使用岸裙,如有不當(dāng)猖败,希望大佬指出。