• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios - 实现基本 CloudKit 订阅

[复制链接]
菜鸟教程小白 发表于 2022-12-12 18:41:20 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我有一个用 Swift 编写的简单 iOS 应用程序,它使用 CloudKit 将字符串保存到云中。用户可以随时更新字符串(覆盖原始字符串)。这在我的代码中运行良好。如果用户在不同的设备上更改字符串,我希望应用程序自动更新(假设他们在 iPad 上更改了字符串,我希望他们的 iPhone 自动更新)。我试图找到一个基本的 CloudKit 订阅教程,但它们都处理更高级的实现。如何实现简单的 CloudKit 订阅?我的代码如下:

import UIKit
import CloudKit

class ViewController: UIViewController {

    // This the text field where the user inputs their string to save to the cloud
    @IBOutlet weak var userInput1: UITextField!

    // Save button
    // When the user taps save, their string is saved to the cloud
    @IBAction func saveButton(sender: AnyObject) {

        let container = CKContainer.defaultContainer()
        let privateDatabase = container.privateCloudDatabase

        let myRecordName = "1001"
        let recordID = CKRecordID(recordName: myRecordName)

        privateDatabase.fetchRecordWithID(recordID, completionHandler: { (record, error) in
            if error != nil {

            } else {
                record!.setObject(self.userInput1.text, forKey: "userInput1")

                privateDatabase.saveRecord(record!, completionHandler: { (savedRecord, saveError) in
                    if saveError != nil {
                        print("Error saving record.")
                    } else {
                        print("Successfully updated record!")
                    }
                })
            }
        })
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Auto populates app with cloud string
        let container = CKContainer.defaultContainer()
        let privateDatabase = container.privateCloudDatabase

        let myRecordName = "1001"
        let recordID = CKRecordID(recordName: myRecordName)

        privateDatabase.fetchRecordWithID(recordID, completionHandler: { (record, error) in

            if error != nil {
                // Nothing saved to cloud yet
                print(error)
            } else {
                // Display record
                dispatch_async(dispatch_get_main_queue()) {
                    self.userInput1.text = (record!["userInput1"]! as! String)
                }
            }
        })
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}



Best Answer-推荐答案


订阅有两个部分;第一个是保存订阅,第二个是保存订阅时要触发的代码。此代码使用自己的 CKRecordID 创建订阅,比它需要的要复杂一点。它还会在更新和删除时触发,还有第三种选择。创建。是的,它在公共(public)数据库中,您目前在私有(private)数据库中。所以你需要做出一些改变,这是一个挑战。

func subscribe4Cloud() {
let container = CKContainer(identifier: "iCloud.com")
let publicDB = container.publicCloudDatabase
let predicateY = NSPredicate(value: true)
let query = CKQuery(recordType: "Collections", predicate: predicateY)
publicDB.performQuery(query, inZoneWithID: nil) {
    records, error in
    if error != nil {
        print("twang this is broken \(error)")
    } else {
        if records!.count > 0 {
                subID = String(NSUUID().UUIDString)
                let predicateY = NSPredicate(value: true)
                let subscription = CKSubscription(recordType: "Collections", predicate: predicateY, subscriptionID: subID, options: [.FiresOnRecordUpdate, .FiresOnRecordDeletion])
                subscription.notificationInfo = CKNotificationInfo()

                publicDB.saveSubscription(subscription) {
                    subscription, error in
                    if error != nil {
                        print("ping sub failed, almost certainly cause it is already there \(theLink) \(error)")
                    } else {
                        print("bing subscription saved! \(subID) ")
                    }
                }
        } else {
            print("no records found")
        }
    }
}

}

这是第一部分。 Cavet:你可能会错过的一个关键点 [我做到了]。保存订阅后;你不需要再做一次;你只需要运行一次。

您也可以在 CloudKit 仪表板中执行此操作。第二部分是设置您的应用代理以获取订阅,您可以通过添加此方法来完成。

 func application(application: UIApplication,  didReceiveRemoteNotification userInfo: [NSObject : AnyObject],  fetchCompletionHandler completionHandler: () -> Void) {
    if application.applicationState == .Inactive {
        // Do nothing
    }
    let notification = CKQueryNotification(fromRemoteNotificationDictionary: userInfo as! [String : NSObject])
    let container = CKContainer(identifier: "iCloud.com")
    let publicDB = container.publicCloudDatabase

    if notification.notificationType == .Query {
        let queryNotification = notification as! CKQueryNotification
        if queryNotification.queryNotificationReason  == .RecordUpdated {
            print("queryNotification.recordID \(queryNotification.recordID)")
        }
    }
    print("userInfo \(userInfo)")
}

这里可能还有几行代码不是严格需要的;我从我从事的一个项目中剪切'n'paste。

这段代码会让你开始;除了打印它之外,我几乎没有努力查看通过发送的通知。您需要对其进行解析并查看您感兴趣的位。

实现 KVO 或 NSNotifications 甚至是委托(delegate)以从此处获取消息到代码中的其他类的第三个挑战;因此,在您的情况下,从应用程序委托(delegate)到您的 View Controller !

使用 cloudKit 并不容易,它是尝试和学习编码的好地方,它可能是一个真正的挑战,也是学习一些非常重要的编码原则、实践和技术的好方法。

关于ios - 实现基本 CloudKit 订阅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35664167/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap