实施基本CloudKit订阅

时间:2016-02-27 00:28:43

标签: ios swift cloudkit

我有一个用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()
    }
}

2 个答案:

答案 0 :(得分:1)

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

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")
        }
    }
}

}

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

您也可以在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)")
}

这里可能还有几行代码并不是严格需要的;我从我工作的一个项目中删除了这个。

此代码将启动您;除了打印之外,我几乎没有努力去查看通过发送的通知。你需要解析它并查看你感兴趣的位。

实施KVO或NSNotifications的第三个挑战,甚至是代表,从此处获取消息到代码中的其他类;所以从app委托给你的视图控制器!

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

答案 1 :(得分:1)

您可以使用CloudKit订阅来保存此字符串,但是如果您只是想要一种简单的方法来保存在单个iCloud用户的设备上保留的字符串,我肯定会建议使用NSUbiquitousKeyValueStore,这有效比如NSUserDefaults,但是在所有iCloud用户的设备上。要打开此商店,只需转到项目设置的“功能”部分。启用iCloud并选中“键值存储”框。

使用此代码的代码非常简单:

NSUbiquitousKeyValueStore.defaultStore().setObject("the user's string", forKey: "userString")

let userString = NSUbiquitousKeyValueStore.defaultStore().objectForKey("userString") as? String

如果您希望获得关键值存储更改时的实时通知,请听取NSUbiquitousKeyValueStoreDidChangeExternallyNotification