你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> iOS項目iCloud及CloudKit Dashboard運用

iOS項目iCloud及CloudKit Dashboard運用

編輯:IOS開發基礎

CloudKit是蘋果推出的基於iCloud的一個雲端數據存儲服務.其 主要由下面兩部分組成:

  • 一個儀表web頁面,用於管理公開數據的記錄類型.

  • 一組API接口,用於iCloud和設備之間的數據傳遞.

一:首先在XCode上面打開關於iCloud功能

1:進入對應的項目Targets 中的Capabilities 選項卡,打開關於iCloud功能;如果勾選iCloud Documents或CloudKit會自動生成一個帶iCloud.開頭的Containers,要配置證書支持;CloudKit Dashboard則可以直接跳轉到Web配置關於iCloud的內容;而關於Steps則是配置的步驟是否都成功;

001.png

二:關於證書如何配置支持iCloud功能

1:進入蘋果證書管理後台中的Identifiers裡有個iCloud Containers菜單

02.png

因為實例中的Bundle Identifier的名字wjy.com.MobileProject;所以在這邊創建一個iCloud.wjy.com.MobileProject的ID值;都是前面增加一個iCloud為開頭;app的bundle id需要與iCloud容器相對應,?iCloud容器名必須是唯一的,因為這是Cloudkit用來訪問數據所使用的全局標識符。由於iCloud容器名包含bundle id,因此bundle id也必須是唯一的(這就是為何需要修改com.raywendrelich.BabiFud)。

為了讓entitlements起作用,需要在App的證書、標識符與配置文件中ID的部分列出app/bundle id。這意味著標識的證書使用了設置的team id與app id,從中可得到iCloud容器的id。若已經在一個可用的開發者賬號中標識了的話Xcode會自動完成這一切。不巧的是,這有時是不同步的,需要更新ID-使用iCloud功能面板修改CloudKit容器ID。否則的話需要修改info.plist文件或BabiFud.entitlements文件來確保id values與所設置的bundle id一致。

2:創建完上面的ID後,同樣進行Identifiers裡的App IDs,找到我們當前的App ID然後對它進行編輯

打開iCloud的功能選擇,並且選擇Include CloudKit support,這邊這時會有一個警告出現,選擇右邊的Edit進行編輯

04.png

這時會有剛才創建好的那個iCloud ID可以選擇綁定;選擇好以後外面的警告也會消除;然後生成對應的描述文件安裝後,XCode上面的步驟報錯也會消除;

三:設置iCloud的數據

1:要進入CloudKit Dashboard操作有兩種方式,第一種如上面第一點所說可以直接點CloudKit Dashboard進入,另一種就是進入蘋果賬號後台也有一個相應的菜單;

05.png

2:進入CloudKit Dashboard可以看到如下的頁面

06.png

2.1 SCHEMA :

CloudKit容器的高級類:Record Types, Security Roles, 和Subscription Types,其中主要使用的是Record Types;

一個Record Type用來定義一個單獨的記錄(可以理解為一個數據模型),相當於存儲數據的模板,和數據庫的表結構類似;

2.2 PUBLIC DATA 和 PRIVATE DATA

就是你保存數據的地方,開發者可以查看所有的共享數據,但是只能看到自己的私密數據,無法看到用戶的私密數據;這裡沒有顯示PRIBATE DATA,其結構和PUBLIC DATA是一樣的;

User Records 記錄一些當前使用者的信息;

Default Zone :這裡可以查看數據的詳細信息,也是後面主要使用的;

2.3 ADMIN 主要是管理開發者團隊權限的,這裡不做過多介紹;

3:切回Record Type選項,點擊右邊欄的左上角的 "+ ",新增一個模型:

07.png

輸入模型名稱: 默認只有一個StringField的屬性(這裡暫且這麼稱呼吧),可以點擊下面的Add Field... 新增屬性列表;

同樣可以選擇屬性的類型,如下圖:

08.png

設置完成後,點擊右下角的 Save按鈕即可保存!這樣,一個模型就建立好了;存儲類型的數據:

NSData (single bytes)  
NSDate (date and time)  
NSNumber (both Int and Double)  
NSString (or String in Swift)  
NSArray (list)  
CKReference (used to create relationships between objects)  
CLLocation (location)  
CKAsset (file)

5:回到Default Zone,中間藍色區域的右上角的名稱旁有個倒三角,這裡可以選擇使用(查詢)哪個模型下的數據:

09.png

6:如果要存是圖片字段記得選Asset類型

10.png

注意:1 Public Record ,1 Private Record,意思是:使用模型Note的有一條公共數據,一條隱私數據,由於我登陸的iCloud賬號和開發者賬號不一樣,相當於是用戶賬號,所以這裡是看不到那個隱私數據的

四:代碼操作iCloud功能

1:首先引入CloudKit.framework系統框架,並引入命名空間#import就可以進行操作

2:首先是判斷手機中的iCloud功能是否開啟,如下面如果有值則表示已經開啟的iCloud功能;

id cloudUrl=[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];

這個方法接受一個參數, 就是要獲取的容器標識。 所謂容器標識, 大多數應用只會用到一個 iCloud 容器,所以我們這裡傳入 nil, 就代表默認獲取第一個可用的容器。這個方法內部會查找當前應用擁有的 iCloud 容器, 如果找到就會返回這個容器的 URL, 證明當前應用的 iCloud 容器可用。 如果找不到,就會返回 nil, 證明當前應用的 iCloud 不可用。

注意: iCloud 容器和你 App 文件沙盒, 在 iOS 文件系統中其實是分別存放在兩個不同的地方的:

iCloud 文件路徑格式 file:///private/var/mobile/Library/Mobile%20Documents/iCloud~com~xxx~aaa/Documents

App 沙盒文件路徑格式 file:///var/mobile/Containers/Data/Application/3B4376B3-89B5-3342-8057-3450D4224518/Documents/

由此可見, 這也是為什麼 iCloud 和 Sandbox 文件路徑訪問需要兩套不同的方式的原因了。

3:增加一條記錄,可以給它一個固定的recordID,就像數據表的主鍵一樣,查找、更新跟刪除有用;

-(void)addCloudDataWithPublic:(BOOL)isPublic recordID:(NSString *)recordID name:(NSString *)name password:(NSString *)password
{
    //CloudKit給應用程序分配部分空間,用於存儲數據,首先要獲取這個存儲空間,這裡我們直接獲取了默認的存儲器(可以自定義存儲器):
    CKContainer *container=[CKContainer defaultContainer];
    CKDatabase *database;
    if (isPublic) {
        database=container.publicCloudDatabase; //公共數據
    }
    else
    {
        database=container.privateCloudDatabase;//隱藏數據
    }
   
    //創建主鍵ID  這個ID可以到時查找有用到
    CKRecordID *noteId=[[CKRecordID alloc]initWithRecordName:recordID];
    //創建CKRecord 保存數據
    CKRecord *noteRecord = [[CKRecord alloc]initWithRecordType:@"User" recordID:noteId];
    
    //設置數據
    [noteRecord setObject:name forKey:@"name"];
    [noteRecord setObject:password forKey:@"password"];
    
    //保存操作
    [database saveRecord:noteRecord completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
        if (!error) {
            [self showAlertMessage:@"保存成功"];
        }
    }];
}

4:假如要保存帶有圖片的字段,需要用到CKAsset,他的初始化需要一個URL,所以這裡,我先把圖片數據保存到本地沙盒,生成一個URL,然後再去創建CKAsset:

//增加帶圖片的提交 圖片的保存,需要用到CKAsset,他的初始化需要一個URL,所以這裡,我先把圖片數據保存到本地沙盒,生成一個URL,然後再去創建CKAsset:
-(void)saveImageDataWithPublic:(BOOL)isPublic recordID:(NSString *)recordID name:(NSString *)name password:(NSString *)password
{
    //保存圖片 圖片的保存,需要用到CKAsset,他的初始化需要一個URL,所以這裡,我先把圖片數據保存到本地沙盒,生成一個URL,然後再去創建CKAsset:
    UIImage *image=[UIImage imageNamed:@"icloudImage"];
    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];
    }
    
    NSString *filePath = [NSString stringWithFormat:@"%@/%@",tempPath,@"iCloudImage"];
    NSURL *url = [NSURL fileURLWithPath:filePath];
    [imageData writeToURL:url atomically:YES];
    
    CKAsset *asset = [[CKAsset alloc]initWithFileURL:url];
    
    //與iCloud進行交互
    CKContainer *container=[CKContainer defaultContainer];
    CKDatabase *database;
    if (isPublic) {
        database=container.publicCloudDatabase; //公共數據
    }
    else
    {
        database=container.privateCloudDatabase;//隱藏數據
    }
    
    //創建主鍵ID  這個ID可以到時查找有用到
    CKRecordID *noteId=[[CKRecordID alloc]initWithRecordName:recordID];
    //創建CKRecord 保存數據
    CKRecord *noteRecord = [[CKRecord alloc]initWithRecordType:@"User" recordID:noteId];
    
    //設置數據
    [noteRecord setObject:name forKey:@"name"];
    [noteRecord setObject:password forKey:@"password"];
    [noteRecord setObject:asset forKey:@"userImage"];
    
    //保存操作
    [database saveRecord:noteRecord completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
        if (!error) {
            [self showAlertMessage:@"保存成功"];
        }
    }];
}

5:查找單條記錄的功能,通過recordID進行

//查找單條記錄
-(void)searchRecordWithRecordID:(NSString *)recordID withFormPublic:(BOOL)isPublic
{
    //獲得指定的ID
    CKRecordID *noteId=[[CKRecordID alloc]initWithRecordName:recordID];
    
    //獲得容器
    CKContainer *container=[CKContainer defaultContainer];
    
    //獲得數據的類型 是公有還是私有
    CKDatabase *database;
    if (isPublic) {
        database=container.publicCloudDatabase;
    }
    else
    {
        database=container.privateCloudDatabase;
    }
    
    __weak typeof(self)weakSelf = self;
    //查找操作
    [database fetchRecordWithID:noteId completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
        NSString *message=[NSString stringWithFormat:@"獲得RecordID為%@ 的數據:%@,%@",recordID,[record objectForKey:@"name"],[record objectForKey:@"password"]];
        [weakSelf showAlertMessage:message];
    }];
}

6:查詢多條記錄的功能,用到的謂詞進行

//查找多條記錄(可以用謂詞進行)
-(void)searchRecordWithFormPublic:(BOOL)isPublic withRecordTypeName:(NSString *)recordTypeName
{
    CKContainer *container=[CKContainer defaultContainer];
    //獲得數據的類型 是公有還是私有
    CKDatabase *database;
    if (isPublic) {
        database=container.publicCloudDatabase;
    }
    else
    {
        database=container.privateCloudDatabase;
    }
    
    NSPredicate *predicate=[NSPredicate predicateWithValue:YES];
    CKQuery *query=[[CKQuery alloc]initWithRecordType:recordTypeName predicate:predicate];
    
    __weak typeof(self)weakSelf = self;
    [database performQuery:query inZoneWithID:nil completionHandler:^(NSArray* _Nullable results, NSError * _Nullable error) {
        [weakSelf showAlertMessage:[NSString stringWithFormat:@"%@",results]];
    }];
}

7:更新一條記錄首先要查找出該條記錄,再對它進行修改,如果對應的鍵值存在進修改其值,如果鍵值不存在則增加新的類型字段;

//更新一條記錄 首先要查找出這一條  然後再對它進行修改
-(void)updateRecordWithFormPublic:(BOOL)isPublic withRecordTypeName:(NSString *)recordTypeName withRecordID:(NSString *)recordID
{
    //獲得指定的ID
    CKRecordID *noteId=[[CKRecordID alloc]initWithRecordName:recordID];
    
    //獲得容器
    CKContainer *container=[CKContainer defaultContainer];
   
    //獲得數據的類型 是公有還是私有
    CKDatabase *database;
    if (isPublic) {
        database=container.publicCloudDatabase;
    }
    else
    {
        database=container.privateCloudDatabase;
    }
    
    __weak typeof(self)weakSelf = self;
    //查找操作
    [database fetchRecordWithID:noteId completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
        if (!error) {
           
            //對原有的健值進行修改
            [record setObject:@"aa123456789" forKey:@"password"];
            //如果健值不存在 則會增加一個
            [record setObject:@"男" forKey:@"gender"];
            
            [database saveRecord:record completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
                if (!error) {
                    [weakSelf showAlertMessage:@"修改保存成功"];
                }
                else
                {
                    [weakSelf showAlertMessage:[NSString stringWithFormat:@"出錯誤 :%@",error]];
                }
            }];
            
        }
    }];
}

8:刪除一條記錄

//刪除記錄
-(void)deleteRecordWithFormPublic:(BOOL)isPublic withRecordID:(NSString *)recordID
{
    //獲得指定的ID
    CKRecordID *noteId=[[CKRecordID alloc]initWithRecordName:recordID];

    //獲得容器
    CKContainer *container=[CKContainer defaultContainer];
    
    //獲得數據的類型 是公有還是私有
    CKDatabase *database;
    if (isPublic) {
        database=container.publicCloudDatabase;
    }
    else
    {
        database=container.privateCloudDatabase;
    }
    
    __weak typeof(self)weakSelf = self;
    [database deleteRecordWithID:noteId completionHandler:^(CKRecordID * _Nullable recordID, NSError * _Nullable error) {
        if (!error) {
            [weakSelf showAlertMessage:@"刪除成功"];
            return;
        }
        [weakSelf showAlertMessage:[NSString stringWithFormat:@"刪除失敗 %@",error]];
    }];
    
}

五:操作實例

編寫一個關於在同一台手機上免登錄的實例,主要原理是通過獲取手機設備唯一碼,然後通過iCloud保存到雲端,在刪除APP後再安裝後就可以直接從雲端獲得用戶跟密碼;會不斷完善此實例,如果感興趣可以點星並關注,會接著編寫關於iCloud關於文件的同步功能;注意證書可以換成自個的,步驟如上:

源代碼地址:https://github.com/wujunyang/iCloudProject

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved