Канал теряет все данные после обновления или перезапуска

Я использую cloudkit для создания приложения, такого как твиттер, и все работает нормально, пока я не обновлю или не перезапущу приложение. Нет ошибки, но канал становится пустым и теряет все данные. Я не пытался увидеть, что происходит, когда приложение используют несколько человек.

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 ответ

Решение

Записи, записанные в базу данных CloudKit, не всегда сразу возвращаются в запросах (CKQuery/CKQueryOperation).

Индексы запросов обновляются асинхронно, поэтому они не гарантируют актуальность. Если вы запрашиваете записи, которые вы недавно изменили, и не предоставляете достаточно времени для обработки этих изменений, результаты запроса могут быть неверными. Результаты могут не содержать правильные записи, и записи могут быть не в порядке.

Ссылка: CKQueryOperation

Вы можете захотеть исследовать использование CKSubscription / CKQuerySubscription (iOS 10+) для получения уведомлений, когда происходят изменения в базе данных.

Другие вопросы по тегам