iOS项目综合

iOS CloudKit的使用

2018-02-12  本文已影响330人  快乐的老船长

主要讲解iCloud工程的创建和CloudKit的使用


CloudKit是什么

  1. 一个仪表web页面,用于管理公开数据的记录类型.
  2. 一组API接口,用于iCloud和设备之间的数据传递.

一、开发者账号中启用iCloud服务

1.选择要添加iCloud功能的appid,勾选iCloud,选择Include CloudKit support (requires Xcode 6),后点击Edit,选择需要额外添加的Container。
42B967C8-332B-4259-A0F5-DEC606A1E3B7.png
2.每个bundleid下本身会有一个Container,如果需要额外的Container,可以通过iCloud Containers创建
E6670FF0-5D68-4E7C-AB3F-EEAA001E977D.png
3.然后可以在Edit里选择需要的Container后,点击continue 以及Assign就完成了添加。
18BB7039-E95E-4A07-BFA1-A960BBF20096.png

->>

32CBA831-1CD4-47FE-A542-CD1C546E406A.png

二、在Xcode中启用iCloud

1.必须在Xcode中添加账号,选择对应的Team
7B55F20E-9685-4EA8-AE91-17997179A68C.png
2.在Capabilities里,打开iCloud开关,并勾选CloudKit,如果需要额外的容器,勾选Specify custom containers,选择额外的容器,这个容器也可以在其他app中添加。
503D2F6C-0972-48A7-A381-7FCA60CC25CB.png

三、关于 CloudKit Dashboard

1.可以点击上图中的CloudKit Dashboard按钮进入,也可以在https://developer.apple.com里进入
572E8EC0-2D44-4B46-BA79-F8DD6ECBC75F.png
2.选择该Team下其中一个容器
403D8483-B2E3-4188-8E2F-5E6E388BBB38.png D9CEE71F-8AC5-4781-AF6A-DDFBE137DA6C.png

其中主要使用的是Record Types

一个Record Type用来定义一个单独的记录(可以理解为一个数据模型),相当于存储数据的模板,和数据库的表结构类似

PUBLIC DATA 和 PRIVATE DATA 就是你保存数据的地方,开发者可以查看所有的共享数据,但是只能看到自己的私密数据,无法看到用户的私密数据;这里没有显示PRIBATE DATA,其结果和PUBLIC DATA是一样的;

可以在Dashboard中添加记录、添加记录模型等

492E3956-9141-4AB3-8F2C-D49C985604C7.png D6619556-DE0D-470F-A3E0-3F267EB66E8B.png

支持的数据类型

四、代码中使用

CloudKit 基础对象类型

CloudKit 的基础对象类型有 7 种。

1.增加一条记录
//获取默认的容器
CKContainer *container = [CKContainer defaultContainer];

//    如果是自定义的容器
//    CKContainer *shareContainer = [CKContainer containerWithIdentifier:ContainerID];

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 *_Nullablerecord,NSError *_Nullableerror) {
    if(!error)
    {
        NSLog(@"保存成功");
    }
    else
    {
        NSLog(@"保存失败: %@",error);
    }
 }];
注意 :
2.获取一条记录
CKRecordID *noteId = [[CKRecordID alloc]initWithRecordName:recordID];
CKDatabase *publicDatabase = [[CKContainer defaultContainer] publicCloudDatabase];

//通过主键ID查找记录
[publicDatabase fetchRecordWithID:noteId completionHandler:^(CKRecord *_Nullablerecord,NSError *_Nullableerror) {
   if(!error)
    {
       NSLog(@"查询成功: %@",record);
    }
    else
    {
       NSLog(@"查询失败: %@",error);
    }
}];
3.查询多条记录
CKDatabase *publicDatabase = [[CKContainer defaultContainer] publicCloudDatabase];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name != %@",@"xiaowang"];
CKQuery *query = [[CKQuery alloc] initWithRecordType:recordTypeName predicate:predicate];

NSSortDescriptor *firstDescriptor = [[NSSortDescriptor alloc] initWithKey:@"gender" ascending:NO];
NSSortDescriptor *secondDescriptor = [[NSSortDescriptor alloc] initWithKey:@"age" ascending:NO];

query.sortDescriptors = @[firstDescriptor,secondDescriptor];

//通过谓词查找记录
[publicDatabase performQuery:query inZoneWithID:nil completionHandler:^(NSArray<CKRecord*>  *_Nullableresults,NSError *_Nullableerror) {
    if(!error)
    {
       NSLog(@"results: %@",results);
    }
    else
    {
       NSLog(@"查询失败: %@",error);
    }
}];
4.更新一条记录
CKRecordID *noteId = [[CKRecordID alloc] initWithRecordName:recordID];
CKDatabase *publicDatabase = [[CKContainer defaultContainer] publicCloudDatabase];

//先找到记录,再修改记录
[publicDatabase fetchRecordWithID:noteId completionHandler:^(CKRecord *_Nullablerecord,NSError *_Nullableerror) {
   if(!error) 
   {
       [recordsetObject:@"123456789" forKey:@"password"];
       [recordsetObject:@"m" forKey:@"gender"];
       [recordsetObject:@20 forKey:@"age"];

       //修改后保存记录
       [database saveRecord:record completionHandler:^(CKRecord *_Nullablerecord,NSError *_Nullableerror) {
           if(!error) 
           {
               NSLog(@"修改成功 %@",record);
           }
           else
           {
               NSLog(@"修改失败: %@",error);
           }
        }];
    }
    else
    {
       NSLog(@"找不到该记录,查询失败: %@",error);
    }
}];
5.删除一条记录
CKRecordID *noteId = [[CKRecordID alloc] initWithRecordName:recordID];
CKDatabase *publicDatabase = [[CKContainer defaultContainer] publicCloudDatabase];

[publicDatabase deleteRecordWithID:noteId completionHandler:^(CKRecordID *_NullablerecordID,NSError *_Nullableerror) {

   if(!error)
   {
       NSLog(@"删除成功");
   }
   else
   {
       NSLog(@"删除失败: %@",error);
   }
}];
6.保存大文件
CKDatabase *publicDatabase = [[CKContainer defaultContainer] publicCloudDatabase];

CKRecordID *noteId = [[CKRecordID alloc] initWithRecordName:recordID];
CKRecord *noteRecord = [[CKRecord alloc]initWithRecordType:@"User" recordID:noteId];

NSString *path = [[NSBundle mainBundle] pathForResource:@"lcz" ofType:@"jpg"];
CKAsset *asset = [[CKAsset alloc] initWithFileURL:[NSURL fileURLWithPath:path]];

[noteRecord setObject:name forKey:@"name"];
[noteRecord setObject:password forKey:@"password"];
[noteRecord setObject:asset forKey:@"userImage"];

[publicDatabase saveRecord:noteRecord completionHandler:^(CKRecord *_Nullablerecord,NSError *_Nullableerror) {

   if(!error) 
   {
       NSLog(@"保存成功");

   }
   else
   {
       NSLog(@"保存失败: %@",error);
   }
}];
7.添加地理位置
__weak typeof(self) weakSelf = self;

CLGeocoder *geocoder = [CLGeocoder new];
[geocoder geocodeAddressString:@"北京" completionHandler:^(NSArray<CLPlacemark*>  *_Nullableplacemarks,NSError *_Nullableerror) {

   if(!error) 
   {
       if(placemarks.count>0)
       {
           CLPlacemark *placemark = placemarks[0];
           NSLog(@"%@",placemark.location);

           weakSelf.person.location = placemark.location;

          [weakSelf saveRecordWithPublic:YES andKey:@"location" andObject:weakSelf.person.location andRecordType:@"Person" andRecordID:@"sunjie2"];
        }
    }
}];
8.添加引用(外键)
- (void)addReferenceWithPublic:(BOOL)isPublic
                        action:(CKReferenceAction)action
               andReferenceKey:(NSString*)key
             andSourceRecordID:(NSString*)sourceRecordID
             andTargetRecordID:(NSString*)targetRecordID
{

    CKRecordID *noteID = [[CKRecordID alloc]initWithRecordName:targetRecordID];
    CKReference *reference =  [[CKReference alloc]initWithRecordID:noteID action:action];
    CKContainer *container = [CKContainer defaultContainer];

    CKDatabase *database;

    if(isPublic)
    {
        database = container.publicCloudDatabase;
    }
    else
    {
        database = container.privateCloudDatabase;
    }

    CKRecordID *sourceRecordId = [[CKRecordID alloc]initWithRecordName:sourceRecordID];

    [database fetchRecordWithID:sourceRecordId completionHandler:^(CKRecord *_Nullablerecord,NSError *_Nullableerror) {

       if(!error)
       {
            [record setObject:reference forKey:key];

            [database saveRecord:record completionHandler:^(CKRecord *_Nullablerecord,NSError *_Nullableerror) {

               if(!error)
               {
                   NSLog(@"保存成功");
                   self.person.workN = reference;
               }
               else
               {
                   NSLog(@"保存失败: %@",error);
               }
            }];
        }
    }];
}
9.查询引用的记录
//拿到引用的id
CKRecordID *recordID = reference.recordID;

//根据id查询
[database fetchRecordWithID:recordID completionHandler:^(CKRecord *record,NSError *error) {

   if(error) 
   {
       //错误处理
       NSLog(@"查询失败%@",error);
   }
   else
   {
       // 查询成功
       NSLog(@"查询成功%@",record);
   }
}];
10.批操作处理

CKFetchRecordsOperation;
CKModifyRecordsOperation;
CKQueryOperation;
CKDatabaseOperation;
CKModifyBadgeOperation;
CKOperation;
CKSubscriptionOptions;
CKModifySubscriptionsOperation;
CKFetchSubscriptionsOperation;

- (void)fetchOperationWithRecordID:(NSArray<CKRecordID*>*)fetchRecordIDs
{
    CKFetchRecordsOperation *fetchRecordsOperation = [[CKFetchRecordsOperation alloc] initWithRecordIDs:fetchRecordIDs];

    fetchRecordsOperation.perRecordCompletionBlock = ^(CKRecord *record,CKRecordID *recordID,NSError *error) {

       if(error)
       {
           //错误处理
           NSLog(@"查询失败%@",error);
       }
       else
       {
           // 查询成功
           NSLog(@"查询成功%@",record);
       }
    };

    fetchRecordsOperation.fetchRecordsCompletionBlock= ^(NSDictionary*recordsByRecordID,NSError*error) {

       if(error) 
       {
           //错误处理
           NSLog(@"查询失败%@",error);
       }
       else
       {
           // 查询成功
           NSLog(@"查询成功%@",recordsByRecordID);
       }
    };

    fetchRecordsOperation.database = [[CKContainer defaultContainer] publicCloudDatabase];
    [fetchRecordsOperation start];
}
11.添加订阅和通知

options参数的可能值是:

CKSubscriptionOptionsFiresOnRecordCreation,
CKSubscriptionOptionsFiresOnRecordDeletion,
CKSubscriptionOptionsFiresOnRecordUpdate,
CKSubscriptionOptionsFiresOnce.

因为options参数是一个位掩码,可以订阅的改变的类型的任何组合。

例如,您可以通过CKSubscriptionOptionsFiresOnRecordCreation| CKSubscriptionOptionsFiresOnRecordUpdate作为选项:参数来接收所有新数据的通知。

- (void)addSubscriptionAndNotificationsWithRecordID:(NSString*)recordID AndRecordType:(NSString*)recordType
{
   NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@",@"Lu"];

   //创建一个订阅
    CKSubscription*subscription = [[CKSubscription alloc]
                               initWithRecordType:recordType
                               predicate:predicate
                               options:CKSubscriptionOptionsFiresOnRecordCreation];

    CKNotificationInfo *notificationInfo = [CKNotificationInfo new];
    notificationInfo.alertLocalizationKey = @"订阅新推送";
    notificationInfo.shouldBadge=YES;
    subscription.notificationInfo= notificationInfo;

    CKDatabase *publicDatabase = [[CKContainer defaultContainer] publicCloudDatabase];

    [publicDatabase saveSubscription:subscription
                   completionHandler:^(CKSubscription *subscription,NSError *error) {
                      if(!error)
                      {
                          NSLog(@"订阅成功%@",subscription);
                      }
                      else
                      {
                          NSLog(@"订阅失败%@",error);
                      }

               }];
}
上一篇下一篇

猜你喜欢

热点阅读