CloudKit订阅未在iOS10上保存

Wil*_*son 3 ios swift cloudkit cksubscription ios10

我正在关注"CloudKit最佳实践"WWDC关于添加订阅的讨论,这似乎在iOS10中有所改变.

下面的代码返回'Success!',但是我的'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)
Run Code Online (Sandbox Code Playgroud)

E. *_*vie 6

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

我先列出一些警告,以防他们解释你的问题:

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

解:

解决这个问题的方法是创建一个自定义私有区域并将我的所有数据保存到该区域(仅在私有数据库中工作).然后,我会收到有关该区域的任何更改的推送通知.

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

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)
Run Code Online (Sandbox Code Playgroud)

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

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

然后跳过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)
Run Code Online (Sandbox Code Playgroud)