tvOS 中的 CloudKit 订阅

Posted

技术标签:

【中文标题】tvOS 中的 CloudKit 订阅【英文标题】:CloudKit subscriptions in tvOS 【发布时间】:2016-04-22 03:07:47 【问题描述】:

我正在尝试使用 CloudKit 和 CKSubcription 在几台 Apple TV 之间同步数据。问题是当我添加、删除或更新记录时,永远不会调用 application:didReceiveRemoteNotification:。我相信我正确配置了订阅,并且我已经确认它们已添加到 CloudKit 仪表板。我曾多次尝试在仪表板中重置开发环境,但这无济于事。我真的不想创建一个计时器来经常获取。感谢您的帮助!

另外,如果重要的话,我使用的是 CloudKit 中的私有数据库而不是公共数据库。

这是我的代码:

AppDelegate.swift

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 

    CloudKitManager.subscribeToItemUpdates()
    application.registerForRemoteNotifications()

    ...

    return true

CloudKitManager.swift

class func subscribeToItemUpdates() 

    if let uuid = UIDevice.currentDevice().identifierForVendor?.UUIDString 

        saveSubscriptionWithIdentifier(uuid + "create", options: CKSubscriptionOptions.FiresOnRecordCreation)
        saveSubscriptionWithIdentifier(uuid + "update", options: CKSubscriptionOptions.FiresOnRecordUpdate)
        saveSubscriptionWithIdentifier(uuid + "delete", options: CKSubscriptionOptions.FiresOnRecordDeletion)
    



class func saveSubscriptionWithIdentifier(identifier: String, options: CKSubscriptionOptions) 

    let sub = CKSubscription(recordType: "Message", predicate: NSPredicate(value: true), subscriptionID: identifier, options: options)
    sub.notificationInfo = CKNotificationInfo()

    let publicDatabase = CKContainer.defaultContainer().publicCloudDatabase
        publicDatabase.saveSubscription(sub)  (savedSubscription, error) -> Void in
        if error != nil 
            print("Error saving CloudKit subscription \(error)")
        
        else 
            print("Saved subscription to CloudKit", savedSubscription)
        
    

【问题讨论】:

【参考方案1】:

tvOS 和 ios 之间存在细微差别。在我的演示应用程序中,我这样处理它:

#if os(tvOS)
//This will only be called when your app is active. So this is what you should use on tvOS
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) 
    EVLog("Push received")
    EVCloudData.publicDB.didReceiveRemoteNotification(userInfo, executeIfNonQuery: 
        EVLog("Not a CloudKit Query notification.")
    , completed: 
        EVLog("All notifications are processed")
    )

#else
// Process al notifications even if we are in the background. tvOS will not have this event
// Make sure you enable background notifications in the app settings. (entitlements: pushnotifications and  backgrounds modes - notifications plus background fetch)
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) 
    EVLog("Push received")
    EVCloudData.publicDB.didReceiveRemoteNotification(userInfo, executeIfNonQuery: 
        EVLog("Not a CloudKit Query notification.")
    , completed: 
        EVLog("All notifications are processed")
        completionHandler(.NewData)
    )

#endif

欲了解更多信息,请参阅EVCloudKitDao

【讨论】:

我使用的是application:didReceiveRemoteNotification,而不是application:didReceiveRemoteNotification:fetchCompletionHandler。我查看了 EVCloudKitDao,似乎您正在删除所有订阅并在每次应用启动时重新订阅。我没有这样做,这可能是问题吗?有必要吗?因为我使用的是私有数据库而不是 CloudKit 中的公共数据库,这有什么不同吗?谢谢

以上是关于tvOS 中的 CloudKit 订阅的主要内容,如果未能解决你的问题,请参考以下文章

是否可以使用 CloudKit 从 iCloud 驱动器获取数据

私有数据库和订阅的 Cloudkit 问题?

如何更新 CloudKit 订阅

在 sharedDB cloudkit 中订阅记录更改

未收到来自 CloudKit 订阅的推送通知

如何找出 CloudKit 订阅何时被删除?