ios - CloudKit 订阅未在 iOS10 上保存

标签 ios swift cloudkit ios10 cksubscription

我正在关注 'CloudKit Best Practices' WWDC talk关于添加订阅,这似乎在 iOS10 中发生了变化。

下面的代码返回“成功!”,但是我的“AllChanges”订阅从未出现在 CloudKit 仪表板上的订阅类型中。

我正在使用 Xcode 8 beta 6。

    let subscription = CKDatabaseSubscription(subscriptionID:"AllChanges")
    let notificationInfo = CKNotificationInfo()
    notificationInfo.shouldSendContentAvailable = true
    subscription.notificationInfo = notificationInfo

    let operation = CKModifySubscriptionsOperation(subscriptionsToSave: [subscription], subscriptionIDsToDelete: [])
    operation.modifySubscriptionsCompletionBlock =  {
        (modifiedSubscriptions: [CKSubscription]?, deletedSubscriptionIDs: [String]?, error: Error?) -> Void in

        if error != nil {
            print(error!.localizedDescription)
        } else {
            print("Success!")
        }
    }
    operation.qualityOfService = .utility
    privateDatabase.add(operation)

最佳答案

我和 CKDatabaseSubscription 有同样的问题,还有很多其他问题:

我首先列出一些注意事项,以防它们解释您的问题:

  • 订阅通常不会出现在“开发者”CloudKit 仪表板中(它们存在,但不会显示 - 最简单的测试方法是重命名订阅并查看 CloudKit 是否提示重复订阅)
  • 推送通知不会发送到模拟器

解决方法:

为我解决此问题的方法是创建自定义私有(private)区域并将我的所有数据保存到该区域(仅适用于私有(private)数据库)。然后我会收到有关该区域的任何更改的推送通知。

您将需要创建区域(-检查 CKAccountStatus = .available 和-之前- 任何记录保存):

let operation = CKModifyRecordZonesOperation(recordZonesToSave: [CKRecordZone(zoneName: "MyCustomZone")], recordZoneIDsToDelete: nil)
operation.modifyRecordZonesCompletionBlock = { (savedRecordZones: [CKRecordZone]?, deletedRecordZoneIDs: [CKRecordZoneID]?, error: Error?) in
    if let error = error {
        print("Error creating record zone \(error.localizedDescription)")
    }
}
privateDatabase?.add(operation)

然后在保存记录时使用该区域:

let record = CKRecord(recordType: "MyRecordType", zoneID: CKRecordZone(zoneName: "MyCustomZone")) 
// you can save zone to CKRecordID instead, if you want a custom id

然后跳过 CKFetchDatabaseChangesOperation(因为我们已经知道我们的区域),并使用 CKFetchRecordZoneChangesOptions 代替:

let options = CKFetchRecordZoneChangesOptions()
options.previousServerChangeToken = myCachedChangeToken
let operation = CKFetchRecordZoneChangesOperation(
    recordZoneIDs: [myCustomZoneId],
    optionsByRecordZoneID: [myCustomZoneId: options]
)
operation.fetchAllChanges = true
operation.recordChangedBlock = { (record: CKRecord) -> Void in
        ... do something
}
operation.recordWithIDWasDeletedBlock = { (recordId: CKRecordID, recordType: String) -> Void in
        ... do something
}
operation.recordZoneFetchCompletionBlock = { (recordZoneId, changeToken, tokenData, isMoreComing, error) in
    if let error = error {
        print("Error recordZoneFetchCompletionBlock: \(error.localizedDescription)")
        return
    }
    myCachedChangeToken = changeToken
}
privateDatabase?.add(operation)

关于ios - CloudKit 订阅未在 iOS10 上保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39181455/

相关文章:

ios - CloudKit 错误 "User Deleted Zone"(28/2042)

objective-c - 在应用程序内播放音乐

objective-c - 如何在 objective-c 中使用NSArray对象的NSArray?

ios - 在 Swift 中从 HealthKit 读取血型、年龄、性别等

ios - 使用 TableView 或 CollectionView 时的 Swift、Slim Controller 代码

ios - CKQueryOperation 可见性、取消和超时可能性

ios - 难以附加到 Swift 中的数组

iphone - Obj-C(iPhone)中的读写文件锁定

swift - 如何在 SwiftUI 中将单击事件添加到整个 View

ios - 云通过 cloudKit 或解析方案数据