Tableview 记录从视图中消失

Tableview records disappearing from view

当我将记录保存到 cloudkit 时,它显示在表格视图中,但在我重新加载应用程序或刷新视图时消失。当我检查云工具包时,它显示记录已保存到 public 数据库。

class SweetsTableViewController: UITableViewController {
    var sweets = [CKRecord]()
    var refresh: UIRefreshControl!
    override func viewDidLoad() {
        super.viewDidLoad()
        refresh = UIRefreshControl()
        refresh.attributedTitle = NSAttributedString(string: "Pull to Refresh")
        refresh.addTarget(self, action: "loadData", forControlEvents: .ValueChanged)
        self.tableView.addSubview(refresh)
        loadData()
    }
    func loadData()
    {
        sweets = [CKRecord]()
        let publicData = CKContainer.defaultContainer().publicCloudDatabase
        let query = CKQuery(recordType: "Beam", predicate: NSPredicate(format: "TRUEPREDICATE", argumentArray:nil))
        query.sortDescriptors = [NSSortDescriptor(key:"creationDate", ascending: false)]
        publicData.performQuery(query, inZoneWithID: nil) { (results: [CKRecord]?, error: NSError?) -> Void in
            if let sweets = results
            {
                self.sweets = sweets
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    self.tableView.reloadData()
                    self.refresh.endRefreshing()
                })
            }
        }
    }
    @IBAction func sendSweet(sender: AnyObject)
    {
        let alert = UIAlertController(title: "New Beam", message: "Type a Beam", preferredStyle: .Alert)
        alert.addTextFieldWithConfigurationHandler { (textField: UITextField) in
            textField.placeholder = "Your Beam"
        }
        alert.addAction(UIAlertAction(title: "Send", style: .Default, handler: {(action: UIAlertAction) -> Void in
            let textField = alert.textFields!.first!
            if textField.text != ""
            {
                let newBeam = CKRecord(recordType: "Beam")
                newBeam["content"] = textField.text
                let publicData = CKContainer.defaultContainer().publicCloudDatabase
                publicData.saveRecord(newBeam, completionHandler: {(record:CKRecord?, error: NSError?) -> Void in
                    if error == nil
                    {
                        dispatch_async(dispatch_get_main_queue(), {() -> Void in
                            print("Beam saved")
                            self.tableView.beginUpdates()
                            self.sweets.insert(newBeam, atIndex: 0)
                            let indexPath = NSIndexPath(forRow: 0, inSection: 0)
                            self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Top)
                            self.tableView.endUpdates()
                        })
                    }else{
                        print(error)
                    }
                })
            }
        }))
        alert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
        self.presentViewController(alert, animated: true, completion: nil)
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return sweets.count
    }
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
        if sweets.count == 0
        {
            return cell
        }
        let sweet = sweets[indexPath.row]
        if let sweetContent = sweet["content"] as? String
        {
            let dateFormat = NSDateFormatter()
            dateFormat.dateFormat = "MM/dd/yyyy"
            let dateString = dateFormat.stringFromDate(sweet.creationDate!)
            cell.textLabel?.text = sweetContent
            cell.detailTextLabel?.text = dateString
        }
        return cell
    }

写入 CloudKit 数据库的记录并不总是立即 return 在查询中编辑 (CKQuery/CKQueryOperation)。

Query indexes are updated asynchronously so they are not guaranteed to be current. If you query for records that you recently changed and not allow enough time for those changes to be processed, the query results may be incorrect. The results may not contain the correct records and the records may be out of order.

参考:CKQueryOperation

虽然保存后记录存在于 public 数据库中,但 indexes(服务器使用它来将记录与您的 CKQuery 匹配)需要一些是时候更新了。因此,如果您获取记录的唯一方法是 CKQuery,它不会 return 立即更新结果。

一种选择是保留您已保存的所有记录的本地副本,并将它们与 CKQuery 的结果结合起来以供显示。 (您可以通过比较记录 ID 来检测和过滤重复项。)稍后,CKQuery 将开始 returning 您保存的记录(每当索引更新时),但是 不能保证。