Last active
September 11, 2018 08:31
-
-
Save aqubi/d45e350ab3d2dfa43469c487ee20053c to your computer and use it in GitHub Desktop.
http://blog.sorausagi.org: CloudKit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let record = CKRecord(recordType: "MyType", recordID: recordID) | |
record["title"] = "name" as CKRecordValue? | |
record["price"]= 1 as CKRecordValue? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let subscription = CKDatabaseSubscription(subscriptionID: subscriptionID) | |
let notificationInfo = CKNotificationInfo() | |
notificationInfo.shouldSendContentAvailable = true | |
subscription.notificationInfo = notificationInfo | |
let operation = CKModifySubscriptionsOperation(subscriptionsToSave: [subscription], subscriptionIDsToDelete: nil) | |
operation.modifySubscriptionsCompletionBlock = { _, _, error in | |
print("added Database Subscriptions") | |
} | |
database.add(operation) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { | |
guard let userInfo = userInfo as? [String: NSObject] else { return } | |
let notification = CKNotification(fromRemoteNotificationDictionary: userInfo) | |
guard let subscriptionID = notification.subscriptionID else { return } | |
if notification.notificationType == .database { | |
//CKDatabaseSubscription | |
//subscriptionID から 該当のDatabaseを判断して、 | |
//CKFetchDatabaseChangesOperation で変更情報を取得して反映する | |
} else if notification.notificationType == .recordZone { | |
guard let zoneNotification = notification as? CKRecordZoneNotification else { return } | |
guard let recordZoneID = zoneNotification.recordZoneID else { return } | |
//CKRecordZoneSubscription | |
//recordZoneIDから該当のRecord Zoneを判断して、 | |
//CKFetchRecordZoneChangesOptions で変更情報を取得して反映する | |
} else if notification.notificationType == .query { | |
guard let queryNotification = notification as? CKQueryNotification else { return } | |
guard let recordID = queryNotification.recordID else { return } | |
let recordZoneID = recordID.zoneID | |
//CKQuerySubscription | |
//対象のRecordIDがNotificationから取得できる | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let operation = CKFetchDatabaseChangesOperation(previousServerChangeToken: cachedToken) | |
operation.fetchDatabaseChangesCompletionBlock = { serverChangeToken, moreComing, error in | |
if let e = error { | |
if let ckError = e as? CKError, ckError.code == .changeTokenExpired { | |
print("token expired") | |
} | |
return | |
} | |
print("new token is ", serverChangeToken) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var currentToken:String? | |
func fetchChanges(from database: CKDatabase) { | |
let operation = CKFetchDatabaseChangesOperation(previousServerChangeToken: currentToken) | |
var newZoneIDs = [CKRecordZoneID]() | |
operation.changeTokenUpdatedBlock = { serverChangeToken in | |
//Databaseの新しいTokenを保存しておき、次回に利用する | |
self.currentToken = serverChangeToken | |
} | |
operation.recordZoneWithIDWasDeletedBlock = { zoneID in | |
//対象のRecord Zoneをキャッシュから削除する | |
} | |
operation.recordZoneWithIDChangedBlock = { zoneID in | |
if {キャッシュに対象のRecordZoneがあれば} { | |
//Record Zoneの差分を取得して更新する | |
} else { | |
newZoneIDs.append(zoneID) | |
} | |
} | |
operation.fetchDatabaseChangesCompletionBlock = { serverChangeToken, moreComing, error in | |
if CloudKitError.share.handle(error: error, operation: .fetchChanges, alert: true) != nil { | |
if let ckError = error as? CKError, ckError.code == .changeTokenExpired { | |
//トークン切れ | |
self.currentToken = nil | |
self.fetchChanges(from: database) | |
} | |
return | |
} | |
self.currentToken = serverChangeToken | |
guard moreComing == false else { return } | |
guard newZoneIDs.count > 0 else { return } | |
//新しいRecord Zoneの処理 | |
let fetchZonesOp = CKFetchRecordZonesOperation(recordZoneIDs: newZoneIDs) | |
fetchZonesOp.fetchRecordZonesCompletionBlock = { results, error in | |
guard error == nil, let zoneDictionary = results else { return } | |
for (_, zone) in zoneDictionary { | |
//Record Zoneをキャッシュに追加して、内容を取得する | |
} | |
} | |
database.add(fetchZonesOp) | |
} | |
database.add(operation) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let options = CKFetchRecordZoneChangesOptions() | |
options.previousServerChangeToken = cachedToken | |
let zone:CKRecordZone = ... | |
let operation = CKFetchRecordZoneChangesOperation(recordZoneIDs: [zone.zoneID], optionsByRecordZoneID: [zone.zoneID: options]) | |
operation.recordZoneFetchCompletionBlock = { (zoneID, serverChangeToken, clientChangeTokenData, moreComing, error) in | |
if let e = error { | |
if let ckError = e as? CKError, ckError.code == .changeTokenExpired { | |
print("token expired") | |
} | |
return | |
} | |
print("new token is ", serverChangeToken) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let operation = CKModifyRecordsOperation(recordsToSave: recordsToSave, recordIDsToDelete: nil) | |
operation.longLivedOperationWasPersistedBlock = { | |
print("Call longLivedOperationWasPersistedBlock ID=", operation.operationID) | |
UserDefaults.standard.setValue(operation.operationID, forKey: "LongLivedOperationID") | |
UserDefaults.standard.synchronize() | |
} | |
let configuration = CKOperationConfiguration() | |
configuration.isLongLived = true | |
operation.configuration = configuration | |
database.add(operation) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let container = CKContainer.default() | |
//全てのIDを取得 | |
container.fetchAllLongLivedOperationIDs { (operationIDs, error) in | |
print("called fetchAllLongLivedOperationIDs") | |
if let e = error { print(e) } | |
if let ids = operationIDs { | |
print("operationIDs count=", ids.count) | |
} | |
} | |
//保存したOperationIDから検索 | |
if let longLivedID = UserDefaults.standard.string(forKey: "LongLivedOperationID") { | |
container.fetchLongLivedOperation(withID: longLivedID, completionHandler: { (operation, error) in | |
if let e = error { | |
print(e) | |
} else if let ope = operation { | |
print("find operation ID=", ope.operationID) | |
} | |
}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let database = CKContainer.default().privateCloudDatabase | |
let operation = CKModifyRecordsOperation(recordsToSave: recordsToSave, recordIDsToDelete: recordIDsToDelete) | |
operation.modifyRecordsCompletionBlock = { (records, recordIDs, error) in | |
//TODO: | |
} | |
operation.database = database |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let notificationCenter = UNUserNotificationCenter.current() | |
notificationCenter.requestAuthorization(options:[.alert]) { (granted, error) in | |
assert(granted == true) | |
} | |
UIApplication.shared.registerForRemoteNotifications() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment