What is CloudKit?
“The CloudKit framework provides interfaces for moving data between
your app and your iCloud containers”
- CloudKit Framework Reference
Slide 4
Slide 4 text
What is CloudKit?
“CloudKit is not a replacement for your app’s existing data objects.
Instead, CloudKit provides complementary services for managing the
transfer of data to and from iCloud servers.”
- CloudKit Framework Reference
Slide 5
Slide 5 text
What is CloudKit?
• it is a transfer api to move data to and from the cloud
• it behaves like a remote database in many parts
• but: It is not your app’s database
Slide 6
Slide 6 text
Structure
Slide 7
Slide 7 text
Structure
• local api
• remote database
• remote dashboard
• records
• references
• containers
• queries
• operations
• zones
• subscriptions
Slide 8
Slide 8 text
Structure
Data
Container
Public Database
Private
Database
Private
Database
Private
Database
Private
Database
Private
Database
Private
Database
Private
Database
Private
Database
Private
Database
Bulk Storage
Zone
Record
Record
Record
Asset
Asset
Asset
Slide 9
Slide 9 text
Structure
Convenience API
CKContainer CKDatabase
CKRecord
Slide 10
Slide 10 text
Structure
Convenience API
CKContainer CKDatabase
CKRecord
CKQuery
Slide 11
Slide 11 text
Structure
Convenience API
CKContainer CKDatabase CKSubscription
Slide 12
Slide 12 text
Structure
Not so convenient API
CKContainer CKDatabase
CKRecord
CKModifyRecordsOperation
CKRecord
CKQueryOperation
CKQuery
CKRecord
CKModifySubscriptionsOperation
CKSubscription
CKModifyRecordsOperation
CKQueryOperation
CKModifySubscriptionsOperation CKModifyRecordZonesOperation
CKFetchSubscriptionsOperation CKFetchRecordZonesOperation
CKFetchRecordsOperation
CKFetchRecordChangesOperation
CKDiscoverAllContactsOperation
CKDiscoverUserInfosOperation
CKFetchNotificationChangesOperation
CKMarkNotificationsReadOperation
CKModifyBadgeOperation
Structure
Do not start with CloudKit in your productive application!
Slide 16
Slide 16 text
Structure
• This api has nothing to do with convenience
• …but this api is great
• It gives you a lot of responsibility
• …but also a lot of power and flexibility
Slide 17
Slide 17 text
Dashboard
Slide 18
Slide 18 text
Dashboard
• Web based administration
• View, create, edit, and remove records
• Edit, and remove record layouts
• Edit access groups / privileges
Slide 19
Slide 19 text
No content
Slide 20
Slide 20 text
No content
Slide 21
Slide 21 text
Demo
Slide 22
Slide 22 text
CKDatabase
Slide 23
Slide 23 text
CKDatabase
• Public database
• readable by everyone
• writable by every iCloud user
• Private database
• readable and writable by the current iCloud user
CKRecord
• Data object
• Dictionary like api
• On the fly model generation
Slide 34
Slide 34 text
CKRecord
Each record has a…
• …record type
• …record id
• …creation date / user record id
• …modification date / user record id
Slide 35
Slide 35 text
CKRecord
Class
record type
record id
creation date / user record id
modification date / user record id
Type
NSString*
CKRecordID*
NSDate* / CKRecordID*
NSDate* / CKRecordID*
Slide 36
Slide 36 text
CKRecord
CloudKit
record type
record id
creation date / user record id
modification date / user record id
CoreData
entity name
object id
n/a
n/a
Slide 37
Slide 37 text
CKRecord
CKRecord *record = [[CKRecord alloc] initWithRecordType:@"Todo"];
record[@"title"] = @"Get christmas presents";
[database saveRecord:record
completionHandler:^(CKRecord *record, NSError *error) {
if (error) {
// TODO: handle error
return;
}
// TODO: store record id to your local model
}];
Slide 38
Slide 38 text
CKRecord
CKRecord *record = [[CKRecord alloc] initWithRecordType:@"Todo"];
record[@"title"] = @"Get christmas presents";
[database saveRecord:record
completionHandler:^(CKRecord *record, NSError *error) {
if (error) {
// TODO: handle error
return;
}
// TODO: store record id to your local model
}];
Slide 39
Slide 39 text
CKRecord
CKRecord *record = [[CKRecord alloc] initWithRecordType:@"Todo"];
record[@"title"] = @"Get christmas presents";
[database saveRecord:record
completionHandler:^(CKRecord *record, NSError *error) {
if (error) {
// TODO: handle error
return;
}
// TODO: store record id to your local model
}];
Slide 40
Slide 40 text
CKRecord
CKRecord *record = [[CKRecord alloc] initWithRecordType:@"Todo"];
record[@"title"] = @"Get christmas presents";
[database saveRecord:record
completionHandler:^(CKRecord *record, NSError *error) {
if (error) {
// TODO: handle error
return;
}
// TODO: store record id to your local model
}];
Slide 41
Slide 41 text
CKRecord
CKRecord *record = [[CKRecord alloc] initWithRecordType:@"Todo"];
record[@"title"] = @"Get christmas presents";
[database saveRecord:record
completionHandler:^(CKRecord *record, NSError *error) {
if (error) {
// TODO: handle error
return;
}
// TODO: store record id to your local model
}];
Slide 42
Slide 42 text
Container
Public Database
Zone
CKRecord
Todo
creationDate
modificationDate
title
Slide 43
Slide 43 text
CKRecord
CKRecordID *recordID = …; // get record id from your model
[database fetchRecordWithID:recordID
completionHandler:^(CKRecord *record, NSError *error) {
if (error) {
// TODO: handle error
return;
}
record[@"done"] = @YES;
[database saveRecord:record
completionHandler:^(CKRecord *record, NSError *error) {
// TODO: check & handle error
}];
}];
Slide 44
Slide 44 text
CKRecord
CKRecordID *recordID = …; // get record id from your model
[database fetchRecordWithID:recordID
completionHandler:^(CKRecord *record, NSError *error) {
if (error) {
// TODO: handle error
return;
}
record[@"done"] = @YES;
[database saveRecord:record
completionHandler:^(CKRecord *record, NSError *error) {
// TODO: check & handle error
}];
}];
Slide 45
Slide 45 text
CKRecord
CKRecordID *recordID = …; // get record id from your model
[database fetchRecordWithID:recordID
completionHandler:^(CKRecord *record, NSError *error) {
if (error) {
// TODO: handle error
return;
}
record[@"done"] = @YES;
[database saveRecord:record
completionHandler:^(CKRecord *record, NSError *error) {
// TODO: check & handle error
}];
}];
Slide 46
Slide 46 text
CKRecord
CKRecordID *recordID = …; // get record id from your model
[database fetchRecordWithID:recordID
completionHandler:^(CKRecord *record, NSError *error) {
if (error) {
// TODO: handle error
return;
}
record[@"done"] = @YES;
[database saveRecord:record
completionHandler:^(CKRecord *record, NSError *error) {
// TODO: check & handle error
}];
}];
Slide 47
Slide 47 text
Container
Public Database
Zone
CKRecord
Todo
creationDate
modificationDate
title
Todo
creationDate
modificationDate
title
done
Slide 48
Slide 48 text
CKSubscription
Slide 49
Slide 49 text
CKSubscription
• Subscribe to push notifications
• Bound to a record type & predicate
• on create / on update / on delete
• silent / badge / alert / sound
Slide 50
Slide 50 text
CKSubscription
• Configure push notifications
• Register for push notifications
• Subscribe to cloud kit
CKSubscription
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:
(void(^)(UIBackgroundFetchResult))completionHandler {
// TODO: fetch updates and handle them
completionHandler(UIBackgroundFetchResultNewData);
}
Slide 65
Slide 65 text
CKSubscription
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:
(void(^)(UIBackgroundFetchResult))completionHandler {
// TODO: fetch updates and handle them
completionHandler(UIBackgroundFetchResultNewData);
}
Slide 66
Slide 66 text
CKSubscription
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:
(void(^)(UIBackgroundFetchResult))completionHandler {
// TODO: fetch updates and handle them
completionHandler(UIBackgroundFetchResultNewData);
}
Slide 67
Slide 67 text
CKSubscription
• mark notifications as read
• fetch missed notifications
• handle badges on all devices
Slide 68
Slide 68 text
// TODO: handle error
Slide 69
Slide 69 text
// TODO: handle error
• You need to handle them
• Otherwise your data models will become inconsistent
• They might occur often
Slide 70
Slide 70 text
// TODO: handle error
• Handle errors in a central place if possible
• HRSCustomErrorHandling might help you
Slide 71
Slide 71 text
// TODO: handle error
CloudKit
Transaction cache
Data model
Slide 72
Slide 72 text
// TODO: handle error
CloudKit
Transaction cache
Data model
Slide 73
Slide 73 text
Problems
Slide 74
Slide 74 text
Problems
• convenient API can not handle complexity of CloudKit
• lack of documentation
• strange behavior
• iOS simulator is not working
• privileges handling is lacking features
Slide 75
Slide 75 text
Next steps
Slide 76
Slide 76 text
Next steps
• experiment with the convenient api
• check if CloudKit is the right iCloud api for your task
• move to the operation based api
• get your models together