在 iOS 11 中用 CloudKit 将通知标记为已读
Mark Notifications as Read in iOS 11 with CloudKit
我有一个使用 CloudKit
的应用程序,在 iOS 11
之前一切正常。
在以前的 iOS 版本中,我使用 CKQuerySubscription
和 NSPredicate
来在用户更改特定 table 时接收通知,匹配 NSPredicate
属性。
这样做之后,每当服务器发送通知时,我都会遍历它们,获取它的更改,然后将它们标记为 READ
,这样我会再次解析它们(保存 serverToken
) .
现在在 iOS 11 中,Xcode 通知我这些代表是 deprecated
,我应该更改它们,但这是我遇到问题的地方 - 我不能iOS 11.
弄清楚如何以未弃用的方式进行操作
这是我的代码:
正在保存订阅
fileprivate func setupCloudkitSubscription() {
let userDefaults = UserDefaults.standard
let predicate = NSPredicate(format: /*...*/) // predicate here
let subscription = CKQuerySubscription(recordType: "recordType", predicate: predicate, subscriptionID: "tablename-changes", options: [.firesOnRecordUpdate, .firesOnRecordCreation])
let notificationInfo = CKNotificationInfo()
notificationInfo.shouldSendContentAvailable = true // if true, then it will push as a silent notification
subscription.notificationInfo = notificationInfo
let publicDB = CKContainer.default().publicCloudDatabase
publicDB.save(subscription) { (subscription, err) in
if err != nil {
print("Failed to save subscription:", err ?? "")
return
}
}
}
检查未决通知
fileprivate func checkForPendingNotifications() {
let serverToken = UserDefaults.standard.pushNotificationsChangeToken
let operation = CKFetchNotificationChangesOperation(previousServerChangeToken: serverToken)
var notificationIDsToMarkRead = [CKNotificationID]()
operation.notificationChangedBlock = { (notification) -> Void in
if let notificationID = notification.notificationID {
notificationIDsToMarkRead.append(notificationID)
}
}
operation.fetchNotificationChangesCompletionBlock = {(token, err) -> Void in
if err != nil {
print("Error occured fetchNotificationChangesCompletionBlock:", err ?? "")
print("deleting existing token and refetch pending notifications")
UserDefaults.standard.pushNotificationsChangeToken = nil
return
}
let markOperation = CKMarkNotificationsReadOperation(notificationIDsToMarkRead: notificationIDsToMarkRead)
markOperation.markNotificationsReadCompletionBlock = { (notificationIDsMarkedRead: [CKNotificationID]?, operationError: Error?) -> Void in
if operationError != nil {
print("ERROR MARKING NOTIFICATIONS:", operationError ?? "")
return
}
}
let operationQueue = OperationQueue()
operationQueue.addOperation(markOperation)
if token != nil {
UserDefaults.standard.pushNotificationsChangeToken = token
}
}
let operationQueue = OperationQueue()
operationQueue.addOperation(operation)
}
如您所见,上面的代码在 iOS 直到 11;
上运行完美
现在Xcode在以下几行提示警告:
let operation = CKFetchNotificationChangesOperation(previousServerChangeToken: serverToken)
警告:
'CKFetchNotificationChangesOperation' was deprecated in iOS 11.0: Instead of iterating notifications to enumerate changed record zones, use CKDatabaseSubscription, CKFetchDatabaseChangesOperation, and CKFetchRecordZoneChangesOperation
AND
let markOperation = CKMarkNotificationsReadOperation(notificationIDsToMarkRead: notificationIDsToMarkRead)
警告:
'CKMarkNotificationsReadOperation' was deprecated in iOS 11.0: Instead of iterating notifications, consider using CKDatabaseSubscription, CKFetchDatabaseChangesOperation, and CKFetchRecordZoneChangesOperation as appropriate
我尝试应用 CKDatabaseSubscription
,但这样做我无法像使用 CKQuerySubscription
那样应用 NSPredicate
来过滤订阅,如果我尝试获取并标记为待处理通知
Read
它显示了这些警告。
在这种情况下,iOS 11
的最佳方法是什么?有什么提示吗?
谢谢。
因此,正如我在 openradar
错误报告上面的评论中提到的那样,可以找到 here 这是 iOS 11
中为 [ 获取更改时的一个已知问题=34=] 记录,然后将这些更改标记为已读,保存给定的标记。
因为这个问题没有真正的解决方案,因为 Apple 没有为此提供解决方法,或者在给出解决方案之前可能不会将这些委托功能标记为已弃用,我不得不走另一条路,这是以下内容:
我必须在 Private Database
中创建一个自定义 CKRecordZone
,然后我必须订阅 zoneID
中的数据库更改,通过这样做,每当用户更改其中的内容时数据库所需的 push-notifications
and/or silent-push-notifications
按预期触发,然后我可以解析新数据。
我的问题是我在 public 数据库中有 User Profile
,所以每当用户更改与他相关的内容(姓名、简历等)时,它都会保存在 CloudKit 并且静默通知会触发用户的其他设备以更新此数据 - 我也可以使用私有数据库完美地做到这一点 - 但我的问题是其他用户可以搜索应用程序用户来关注 - 取消关注他们并且如果该数据存储在私有数据库中,一般用户搜索范围之外。
为了克服这个问题,我不得不半复制用户配置文件数据。
用户通过私有数据库获取和编辑其数据,并在保存时还更新 public 数据库中的半相关 table 以便普通用户可以搜索。
直到 Apple 允许我们像以前在 iOS 10
中那样从 public 数据库中获取更改,此解决方案暂时对我有用。
我有一个使用 CloudKit
的应用程序,在 iOS 11
之前一切正常。
在以前的 iOS 版本中,我使用 CKQuerySubscription
和 NSPredicate
来在用户更改特定 table 时接收通知,匹配 NSPredicate
属性。
这样做之后,每当服务器发送通知时,我都会遍历它们,获取它的更改,然后将它们标记为 READ
,这样我会再次解析它们(保存 serverToken
) .
现在在 iOS 11 中,Xcode 通知我这些代表是 deprecated
,我应该更改它们,但这是我遇到问题的地方 - 我不能iOS 11.
这是我的代码:
正在保存订阅
fileprivate func setupCloudkitSubscription() {
let userDefaults = UserDefaults.standard
let predicate = NSPredicate(format: /*...*/) // predicate here
let subscription = CKQuerySubscription(recordType: "recordType", predicate: predicate, subscriptionID: "tablename-changes", options: [.firesOnRecordUpdate, .firesOnRecordCreation])
let notificationInfo = CKNotificationInfo()
notificationInfo.shouldSendContentAvailable = true // if true, then it will push as a silent notification
subscription.notificationInfo = notificationInfo
let publicDB = CKContainer.default().publicCloudDatabase
publicDB.save(subscription) { (subscription, err) in
if err != nil {
print("Failed to save subscription:", err ?? "")
return
}
}
}
检查未决通知
fileprivate func checkForPendingNotifications() {
let serverToken = UserDefaults.standard.pushNotificationsChangeToken
let operation = CKFetchNotificationChangesOperation(previousServerChangeToken: serverToken)
var notificationIDsToMarkRead = [CKNotificationID]()
operation.notificationChangedBlock = { (notification) -> Void in
if let notificationID = notification.notificationID {
notificationIDsToMarkRead.append(notificationID)
}
}
operation.fetchNotificationChangesCompletionBlock = {(token, err) -> Void in
if err != nil {
print("Error occured fetchNotificationChangesCompletionBlock:", err ?? "")
print("deleting existing token and refetch pending notifications")
UserDefaults.standard.pushNotificationsChangeToken = nil
return
}
let markOperation = CKMarkNotificationsReadOperation(notificationIDsToMarkRead: notificationIDsToMarkRead)
markOperation.markNotificationsReadCompletionBlock = { (notificationIDsMarkedRead: [CKNotificationID]?, operationError: Error?) -> Void in
if operationError != nil {
print("ERROR MARKING NOTIFICATIONS:", operationError ?? "")
return
}
}
let operationQueue = OperationQueue()
operationQueue.addOperation(markOperation)
if token != nil {
UserDefaults.standard.pushNotificationsChangeToken = token
}
}
let operationQueue = OperationQueue()
operationQueue.addOperation(operation)
}
如您所见,上面的代码在 iOS 直到 11;
上运行完美现在Xcode在以下几行提示警告:
let operation = CKFetchNotificationChangesOperation(previousServerChangeToken: serverToken)
警告:
'CKFetchNotificationChangesOperation' was deprecated in iOS 11.0: Instead of iterating notifications to enumerate changed record zones, use CKDatabaseSubscription, CKFetchDatabaseChangesOperation, and CKFetchRecordZoneChangesOperation
AND
let markOperation = CKMarkNotificationsReadOperation(notificationIDsToMarkRead: notificationIDsToMarkRead)
警告:
'CKMarkNotificationsReadOperation' was deprecated in iOS 11.0: Instead of iterating notifications, consider using CKDatabaseSubscription, CKFetchDatabaseChangesOperation, and CKFetchRecordZoneChangesOperation as appropriate
我尝试应用 CKDatabaseSubscription
,但这样做我无法像使用 CKQuerySubscription
那样应用 NSPredicate
来过滤订阅,如果我尝试获取并标记为待处理通知
Read
它显示了这些警告。
在这种情况下,iOS 11
的最佳方法是什么?有什么提示吗?
谢谢。
因此,正如我在 openradar
错误报告上面的评论中提到的那样,可以找到 here 这是 iOS 11
中为 [ 获取更改时的一个已知问题=34=] 记录,然后将这些更改标记为已读,保存给定的标记。
因为这个问题没有真正的解决方案,因为 Apple 没有为此提供解决方法,或者在给出解决方案之前可能不会将这些委托功能标记为已弃用,我不得不走另一条路,这是以下内容:
我必须在 Private Database
中创建一个自定义 CKRecordZone
,然后我必须订阅 zoneID
中的数据库更改,通过这样做,每当用户更改其中的内容时数据库所需的 push-notifications
and/or silent-push-notifications
按预期触发,然后我可以解析新数据。
我的问题是我在 public 数据库中有 User Profile
,所以每当用户更改与他相关的内容(姓名、简历等)时,它都会保存在 CloudKit 并且静默通知会触发用户的其他设备以更新此数据 - 我也可以使用私有数据库完美地做到这一点 - 但我的问题是其他用户可以搜索应用程序用户来关注 - 取消关注他们并且如果该数据存储在私有数据库中,一般用户搜索范围之外。
为了克服这个问题,我不得不半复制用户配置文件数据。 用户通过私有数据库获取和编辑其数据,并在保存时还更新 public 数据库中的半相关 table 以便普通用户可以搜索。
直到 Apple 允许我们像以前在 iOS 10
中那样从 public 数据库中获取更改,此解决方案暂时对我有用。