菜鸟教程小白 发表于 2022-12-12 18:41:20

ios - 实现基本 CloudKit 订阅


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

<pre><code>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 = &#34;1001&#34;
      let recordID = CKRecordID(recordName: myRecordName)

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

            } else {
                record!.setObject(self.userInput1.text, forKey: &#34;userInput1&#34;)

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

    override func viewDidLoad() {
      super.viewDidLoad()

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

      let myRecordName = &#34;1001&#34;
      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![&#34;userInput1&#34;]! as! String)
                }
            }
      })
    }

    override func didReceiveMemoryWarning() {
      super.didReceiveMemoryWarning()
    }
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>订阅有两个部分;第一个是保存订阅,第二个是保存订阅时要触发的代码。此代码使用自己的 CKRecordID 创建订阅,比它需要的要复杂一点。它还会在更新和删除时触发,还有第三种选择。创建。是的,它在公共(public)数据库中,您目前在私有(private)数据库中。所以你需要做出一些改变,这是一个挑战。</p>

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

                publicDB.saveSubscription(subscription) {
                  subscription, error in
                  if error != nil {
                        print(&#34;ping sub failed, almost certainly cause it is already there \(theLink) \(error)&#34;)
                  } else {
                        print(&#34;bing subscription saved! \(subID) &#34;)
                  }
                }
      } else {
            print(&#34;no records found&#34;)
      }
    }
}
</code></pre>

<p>}</p>

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

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

<pre><code> func application(application: UIApplication,didReceiveRemoteNotification userInfo: ,fetchCompletionHandler completionHandler: () -&gt; Void) {
    if application.applicationState == .Inactive {
      // Do nothing
    }
    let notification = CKQueryNotification(fromRemoteNotificationDictionary: userInfo as! )
    let container = CKContainer(identifier: &#34;iCloud.com&#34;)
    let publicDB = container.publicCloudDatabase

    if notification.notificationType == .Query {
      let queryNotification = notification as! CKQueryNotification
      if queryNotification.queryNotificationReason== .RecordUpdated {
            print(&#34;queryNotification.recordID \(queryNotification.recordID)&#34;)
      }
    }
    print(&#34;userInfo \(userInfo)&#34;)
}
</code></pre>

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

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

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

<p>使用 cloudKit 并不容易,它是尝试和学习编码的好地方,它可能是一个真正的挑战,也是学习一些非常重要的编码原则、实践和技术的好方法。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 实现基本 CloudKit 订阅,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/35664167/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/35664167/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 实现基本 CloudKit 订阅