Reputation: 1153
When I save the record to cloudkit it shows up on the tableview, but disappears when I reload the app or refresh the view. When I check cloud kit it shows that the record was saved to the public database.
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
}
Upvotes: 0
Views: 63
Reputation: 2855
Records written to a CloudKit database are not always immediately returned in queries (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.
Reference: CKQueryOperation
Although the record exists in the public database after you save it, the indexes (which are what the server uses to match records to your CKQuery) take some time to update. Thus, if your only method to obtain the records is a CKQuery, it won't return updated results immediately.
One option is to keep a local copy of all the records you've saved, and combine those with the results from the CKQuery for display. (You can detect and filter duplicates by comparing recordIDs.) At some later point, the CKQuery will start returning the records you've saved (whenever the indexes are updated), but when it does is not guaranteed.
Upvotes: 1