Tableview记录从视图中消失

时间:2016-09-06 18:16:59

标签: ios swift uitableview refresh cloudkit

当我将记录保存到cloudkit时,它会显示在tableview上,但在我重新加载应用程序或刷新视图时会消失。当我检查云套件时,它显示记录已保存到公共数据库。

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
    }

1 个答案:

答案 0 :(得分:1)

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

  

查询索引是异步更新的,因此无法保证它们是最新的。如果查询最近更改的记录并且没有足够的时间处理这些更改,则查询结果可能不正确。结果可能不包含正确的记录,记录可能不正常。

参考:CKQueryOperation

虽然保存后公共数据库中存在记录,但索引(服务器用来将记录与CKQuery匹配)需要一些时间来更新。因此,如果您获取记录的唯一方法是CKQuery,它将不会立即返回更新结果。

一个选项是保存您保存的所有记录的本地副本,并将这些记录与CKQuery的结果结合起来进行显示。 (您可以通过比较recordID来检测和过滤重复项。)稍后,CKQuery将开始返回您保存的记录(无论何时更新索引),但何时不能保证。