当我将记录保存到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
}
答案 0 :(得分:1)
写入CloudKit数据库的记录并不总是立即在查询中返回(CKQuery / CKQueryOperation)。
查询索引是异步更新的,因此无法保证它们是最新的。如果查询最近更改的记录并且没有足够的时间处理这些更改,则查询结果可能不正确。结果可能不包含正确的记录,记录可能不正常。
虽然保存后公共数据库中存在记录,但索引(服务器用来将记录与CKQuery匹配)需要一些时间来更新。因此,如果您获取记录的唯一方法是CKQuery,它将不会立即返回更新结果。
一个选项是保存您保存的所有记录的本地副本,并将这些记录与CKQuery的结果结合起来进行显示。 (您可以通过比较recordID来检测和过滤重复项。)稍后,CKQuery将开始返回您保存的记录(无论何时更新索引),但何时不能保证。