Pet*_*wen 6 database ios swift cloudkit
在 CloudKit 中订阅公共数据库的最佳方式是什么?我有一个人的桌子。每个人都包含一个名字和一个位置。一旦位置发生变化,该位置就会在 CloudKit 中更新。那部分工作正常。
但是我无法在记录更新时获得通知。
一些例子会非常有帮助,因为我已经研究了可能的选项。我查看了在数据库中保存订阅的选项以及 CKModifySubscriptionsOperation 选项。
目前,我的订阅代码如下所示:
let predicate = NSPredicate(format: "TRUEPREDICATE")
let newSubscription = CKQuerySubscription(recordType: "Person", predicate: predicate, options: [.firesOnRecordCreation, .firesOnRecordDeletion, .firesOnRecordUpdate])
let info = CKSubscription.NotificationInfo()
info.shouldSendContentAvailable = true
newSubscription.notificationInfo = info
database.save(newSubscription, completionHandler: {
(subscription, error) in
if error != nil {
print("Error Creating Subscription")
print(error)
} else {
userSettings.set(true, forKey: "subscriptionSaved")
}
})
Run Code Online (Sandbox Code Playgroud)
有人也可以告诉我我的 AppDelegate 应该是什么样子吗?
我已将 didReceiveRemoteNotification 函数添加到我的 AppDelegate。我还调用了 application.registerForRemoteNotifications()。这就是我的 didReceiveRemoteNotification 函数的样子:我什至没有打印出来。
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print("Notification!!")
let notification = CKNotification(fromRemoteNotificationDictionary: userInfo) as? CKDatabaseNotification
if notification != nil {
AppData.checkUpdates(finishClosure: {(result) in
OperationQueue.main.addOperation {
completionHandler(result)
}
})
}
}
Run Code Online (Sandbox Code Playgroud)
您可以检查以下一些其他事项:
= 1 =
确保代码中定义的 CloudKit 容器与您在 CloudKit 仪表板中访问的容器相同。有时,当我们创建和测试多个容器时,我们会忽略在 Xcode 中选择的 CloudKit 容器。
= 2 =
检查CloudKit 仪表板中的“订阅”选项卡,并确保Person在启动应用程序时正在创建您的订阅。如果您看到它,请尝试在 CK Dashboard 中删除它,然后再次运行您的应用程序并确保它再次显示。
= 3 =
检查 CK 仪表板中的日志。push每当发送推送通知时,它们都会显示类型的日志条目。如果当您在 CK Dashboard 中更新/添加记录时记录它,那么您就知道问题出在您的设备上。
= 4 =
请记住,推送通知在 iOS 模拟器中不起作用。您需要一台实际设备(如果您正在制作 macOS 应用程序,则需要一台 Mac)。
= 5 =
通过广泛的测试,我发现如果您始终设置 ,alertBody即使它为空,通知也会更可靠。像这样:
let info = CKSubscription.NotificationInfo()
info.shouldSendContentAvailable = true
info.alertBody = "" //This needs to be set or pushes don't always get sent
subscription.notificationInfo = info
Run Code Online (Sandbox Code Playgroud)
= 6 =
对于 iOS 应用程序,我的应用程序委托处理如下通知:
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
//Ask Permission for Notifications
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound], completionHandler: { authorized, error in
DispatchQueue.main.async {
if authorized {
UIApplication.shared.registerForRemoteNotifications()
}
}
})
return true
}
//MARK: Background & Push Notifications
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]{
let dict = userInfo as! [String: NSObject]
let notification = CKNotification(fromRemoteNotificationDictionary: dict)
if let sub = notification.subscriptionID{
print("iOS Notification: \(sub)")
}
}
//After we get permission, register the user push notifications
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
//Add your CloudKit subscriptions here...
}
}
Run Code Online (Sandbox Code Playgroud)
如果您只进行后台推送,则不需要获得通知权限,但对于用户以弹出通知形式看到的任何内容,您必须获得权限。如果您的应用程序没有请求该权限,请尝试将其从设备上删除并在 Xcode 中重新构建。
祝你好运!:)