CloudKit Public 未下载记录和更改
CloudKit Public Records And Changes not Downloaded
CloudKit Public 未下载记录和更改
我有一个 CloudKit 应用程序,其中包含 Public 和自定义私人记录
区。我似乎有为自定义工作的更改令牌流程
私有区域,但无法使 public 数据正常工作。我的代码
除了 public/private 之外,这两个数据库的使用是相同的
名称并使用 public 的默认区域。我明白那个
订阅不适用于默认区域,但我找不到任何
对 public 数据更改令牌的限制的引用。 Xcode10.1,iOS12.0
我创建我的 PubicData class 并初始化它:
var publicDatabase : CKDatabase!
init() {
let kAppDelegate = UIApplication.shared.delegate as! AppDelegate
context = kAppDelegate.context
let container = CKContainer.default()
publicDatabase = container.publicCloudDatabase
}//init
app入口场景调用的下载函数-tableview:
func downloadPublicUpdates(finishClosure : @ escaping(UIBackgroundFetchResult) -> Void) {
var listRecordsUpdated : [CKRecord] = []
var listRecordsDeleted : [String : String] = [:]
var publicChangeToken : CKServerChangeToken!
var publicChangeZoneToken : CKServerChangeToken!
let userSettings = UserDefaults.standard
if let data = userSettings.value(forKey: "publicChangeToken") as? Data {
if let token = try? NSKeyedUnarchiver.unarchivedObject(ofClass : CKServerChangeToken.self, from : data) {
publicChangeToken = token
print("publicChangeToken exists")
}
} else {
print("userSettings entry for publicChangeToken does not exist")
}//if let data
if let data = userSettings.value(forKey: "publicChangeZoneToken") as? Data {
if let token = try? NSKeyedUnarchiver.unarchivedObject(ofClass: CKServerChangeToken.self, from: data) {
publicChangeZoneToken = token
}
}//if let data
let zone = CKRecordZone.default()
var zonesIDs : [CKRecordZone.ID] = [zone.zoneID]
let operation = CKFetchDatabaseChangesOperation(previousServerChangeToken: publicChangeToken)
operation.recordZoneWithIDChangedBlock = {(zoneID) in
zonesIDs.append(zoneID)
}
operation.changeTokenUpdatedBlock = {(token) in
publicChangeToken = token
}
operation.fetchDatabaseChangesCompletionBlock = {(token, more, error) in
if error != nil{
finishClosure(UIBackgroundFetchResult.failed)
} else if !zonesIDs.isEmpty {
publicChangeToken = token
let configuration = CKFetchRecordZoneChangesOperation.ZoneConfiguration()
configuration.previousServerChangeToken = publicChangeZoneToken
let fetchOperation = CKFetchRecordZoneChangesOperation(recordZoneIDs: zonesIDs, configurationsByRecordZoneID: [zonesIDs[0] : configuration])
fetchOperation.recordChangedBlock = {(record) in
listRecordsUpdated.append(record)
}//fetchOperation.recordChangedBlock
fetchOperation.recordWithIDWasDeletedBlock = {(recordID, recordType) in
listRecordsDeleted[recordID.recordName] = recordType
}//fetchOperation.recordWithIDWasDeletedBlock
fetchOperation.recordZoneChangeTokensUpdatedBlock = {(zoneID, token, data) in
publicChangeZoneToken = token
}//fetchOperation.recordZoneChangeTokensUpdatedBlock
fetchOperation.recordZoneFetchCompletionBlock = {(zoneID, token, data, more, error) in
if let ckerror = error as? CKError {
self.processErrors(error: ckerror)
} else {
publicChangeZoneToken = token
self.updateLocalRecords(listRecordsUpdated : listRecordsUpdated)
self.deleteLocalRecords(listRecordsDeleted : listRecordsDeleted)
listRecordsUpdated.removeAll()
listRecordsDeleted.removeAll()
}//if else
}//fetchOperation.recordZoneFetchCompletionBlock
fetchOperation.fetchRecordZoneChangesCompletionBlock = {(error) in
if error != nil {
print("Error fetchRecordZoneChangesCompletionBlock")
finishClosure(UIBackgroundFetchResult.failed)
} else {
if publicChangeToken != nil {
if let data = try? NSKeyedArchiver.archivedData(withRootObject: publicChangeToken, requiringSecureCoding: false) {
userSettings.set(data, forKey : "publicChangeToken")
}
}//if changeToken != nil
if publicChangeZoneToken != nil {
if let data = try? NSKeyedArchiver.archivedData(withRootObject: publicChangeZoneToken, requiringSecureCoding: false) {
userSettings.set(data, forKey : "publicChangeZoneToken")
}
}
//self.updateInterface()
self.updateLocalReferences()
finishClosure(UIBackgroundFetchResult.newData)
}
}//fetchOperation.fetchRecordZoneChangesCompletionBlock
self.publicDatabase.add(fetchOperation)
} else {//else if !zonesIDs.isEmpty
finishClosure(UIBackgroundFetchResult.noData)
}//if zoneid not empty
}//fetchDatabaseChangesCompletionBlock
print("listRecordsUpdated.count is \(listRecordsUpdated.count)")
publicDatabase.add(operation)
}//downloadPublicUpdates
class 之外:var PD = PDData()
我从初始TableViewController中调用viewDidLoad中的download方法:
PD.downloadPublicUpdates { (result) in
print("in ctvc viewDidLoad and downloadPublicUpdates")
switch result {
case .noData:
print("no data")
case .newData:
print("new data")
case .failed:
print("failed to get data")
}//switch
}//downloadPublicUpdates
控制台输出总是:
publicChangeToken 的 userSettings 条目不存在
listRecordsUpdated.count 为 0
在 ctvc viewDidLoad 和 downloadPublicUpdates
获取数据失败
如有任何指导,我们将不胜感激。
public 数据库中没有可用的更改令牌。这些只存在于私有和共享数据库中。
为了保持同步,您通常必须在本地记录上保留修改日期,然后使用 CKQueryOperation
.[=11 在 CloudKit 服务器上查询更新的内容=]
祝你好运!
CloudKit Public 未下载记录和更改
我有一个 CloudKit 应用程序,其中包含 Public 和自定义私人记录 区。我似乎有为自定义工作的更改令牌流程 私有区域,但无法使 public 数据正常工作。我的代码 除了 public/private 之外,这两个数据库的使用是相同的 名称并使用 public 的默认区域。我明白那个 订阅不适用于默认区域,但我找不到任何 对 public 数据更改令牌的限制的引用。 Xcode10.1,iOS12.0
我创建我的 PubicData class 并初始化它:
var publicDatabase : CKDatabase!
init() {
let kAppDelegate = UIApplication.shared.delegate as! AppDelegate
context = kAppDelegate.context
let container = CKContainer.default()
publicDatabase = container.publicCloudDatabase
}//init
app入口场景调用的下载函数-tableview:
func downloadPublicUpdates(finishClosure : @ escaping(UIBackgroundFetchResult) -> Void) {
var listRecordsUpdated : [CKRecord] = []
var listRecordsDeleted : [String : String] = [:]
var publicChangeToken : CKServerChangeToken!
var publicChangeZoneToken : CKServerChangeToken!
let userSettings = UserDefaults.standard
if let data = userSettings.value(forKey: "publicChangeToken") as? Data {
if let token = try? NSKeyedUnarchiver.unarchivedObject(ofClass : CKServerChangeToken.self, from : data) {
publicChangeToken = token
print("publicChangeToken exists")
}
} else {
print("userSettings entry for publicChangeToken does not exist")
}//if let data
if let data = userSettings.value(forKey: "publicChangeZoneToken") as? Data {
if let token = try? NSKeyedUnarchiver.unarchivedObject(ofClass: CKServerChangeToken.self, from: data) {
publicChangeZoneToken = token
}
}//if let data
let zone = CKRecordZone.default()
var zonesIDs : [CKRecordZone.ID] = [zone.zoneID]
let operation = CKFetchDatabaseChangesOperation(previousServerChangeToken: publicChangeToken)
operation.recordZoneWithIDChangedBlock = {(zoneID) in
zonesIDs.append(zoneID)
}
operation.changeTokenUpdatedBlock = {(token) in
publicChangeToken = token
}
operation.fetchDatabaseChangesCompletionBlock = {(token, more, error) in
if error != nil{
finishClosure(UIBackgroundFetchResult.failed)
} else if !zonesIDs.isEmpty {
publicChangeToken = token
let configuration = CKFetchRecordZoneChangesOperation.ZoneConfiguration()
configuration.previousServerChangeToken = publicChangeZoneToken
let fetchOperation = CKFetchRecordZoneChangesOperation(recordZoneIDs: zonesIDs, configurationsByRecordZoneID: [zonesIDs[0] : configuration])
fetchOperation.recordChangedBlock = {(record) in
listRecordsUpdated.append(record)
}//fetchOperation.recordChangedBlock
fetchOperation.recordWithIDWasDeletedBlock = {(recordID, recordType) in
listRecordsDeleted[recordID.recordName] = recordType
}//fetchOperation.recordWithIDWasDeletedBlock
fetchOperation.recordZoneChangeTokensUpdatedBlock = {(zoneID, token, data) in
publicChangeZoneToken = token
}//fetchOperation.recordZoneChangeTokensUpdatedBlock
fetchOperation.recordZoneFetchCompletionBlock = {(zoneID, token, data, more, error) in
if let ckerror = error as? CKError {
self.processErrors(error: ckerror)
} else {
publicChangeZoneToken = token
self.updateLocalRecords(listRecordsUpdated : listRecordsUpdated)
self.deleteLocalRecords(listRecordsDeleted : listRecordsDeleted)
listRecordsUpdated.removeAll()
listRecordsDeleted.removeAll()
}//if else
}//fetchOperation.recordZoneFetchCompletionBlock
fetchOperation.fetchRecordZoneChangesCompletionBlock = {(error) in
if error != nil {
print("Error fetchRecordZoneChangesCompletionBlock")
finishClosure(UIBackgroundFetchResult.failed)
} else {
if publicChangeToken != nil {
if let data = try? NSKeyedArchiver.archivedData(withRootObject: publicChangeToken, requiringSecureCoding: false) {
userSettings.set(data, forKey : "publicChangeToken")
}
}//if changeToken != nil
if publicChangeZoneToken != nil {
if let data = try? NSKeyedArchiver.archivedData(withRootObject: publicChangeZoneToken, requiringSecureCoding: false) {
userSettings.set(data, forKey : "publicChangeZoneToken")
}
}
//self.updateInterface()
self.updateLocalReferences()
finishClosure(UIBackgroundFetchResult.newData)
}
}//fetchOperation.fetchRecordZoneChangesCompletionBlock
self.publicDatabase.add(fetchOperation)
} else {//else if !zonesIDs.isEmpty
finishClosure(UIBackgroundFetchResult.noData)
}//if zoneid not empty
}//fetchDatabaseChangesCompletionBlock
print("listRecordsUpdated.count is \(listRecordsUpdated.count)")
publicDatabase.add(operation)
}//downloadPublicUpdates
class 之外:var PD = PDData()
我从初始TableViewController中调用viewDidLoad中的download方法:
PD.downloadPublicUpdates { (result) in
print("in ctvc viewDidLoad and downloadPublicUpdates")
switch result {
case .noData:
print("no data")
case .newData:
print("new data")
case .failed:
print("failed to get data")
}//switch
}//downloadPublicUpdates
控制台输出总是:
publicChangeToken 的 userSettings 条目不存在 listRecordsUpdated.count 为 0 在 ctvc viewDidLoad 和 downloadPublicUpdates 获取数据失败
如有任何指导,我们将不胜感激。
public 数据库中没有可用的更改令牌。这些只存在于私有和共享数据库中。
为了保持同步,您通常必须在本地记录上保留修改日期,然后使用 CKQueryOperation
.[=11 在 CloudKit 服务器上查询更新的内容=]
祝你好运!