刷新或重新启动后,Feed会丢失所有数据

时间:2016-08-18 16:27:16

标签: ios swift refresh cloudkit ckrecord

我正在使用cloudkit来创建像twitter这样的应用程序,一切正常,直到我刷新或重新启动应用程序。没有错误,但Feed变空并丢失所有数据。我没有试过看多个人使用该应用程序时会发生什么。

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

您可能需要调查使用CKSubscription / CKQuerySubscription(iOS 10+)在数据库发生更改时接收通知。