CloudKit-不会更新 (Swift)

Posted

技术标签:

【中文标题】CloudKit-不会更新 (Swift)【英文标题】:CloudKit-Won't update (Swift) 【发布时间】:2016-05-09 01:04:30 【问题描述】:
import UIKit
import CloudKit

class IdeaTableViewController: UITableViewController 

var posts = [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()


// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int 
    // #warning Incomplete implementation, return the number of sections
    return 1


override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    // #warning Incomplete implementation, return the number of rows
    return posts.count


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)

    if posts.count == 0
        return cell
        print("zero Posts")
    
    let post = posts[indexPath.row]

    if let postContent = post["content"] as? String
        let dateFormat = NSDateFormatter()
        dateFormat.dateFormat = "MM/dd/yyyy"
        let dateString = dateFormat.stringFromDate(post.creationDate!)
        print("trying to Write the Post...")
        cell.textLabel?.text = "\(postContent)"
        cell.detailTextLabel?.text = "\(dateString)"

    

    return cell


func loadData()
    posts = [CKRecord]()
    let publicData = CKContainer.defaultContainer().publicCloudDatabase
    let query = CKQuery(recordType: "Post", 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 posts = results
            self.posts = posts
            dispatch_async(dispatch_get_main_queue(),  () -> Void in
                self.tableView.reloadData()
                self.refresh.endRefreshing()
            )
        
    



@IBAction func add(sender: AnyObject) 
    let alert = UIAlertController(title: "New Idea", message: "Tell us what you're thinking.", preferredStyle: .Alert)
    alert.addTextFieldWithConfigurationHandler  (textField: UITextField) -> Void in
        textField.placeholder = "Idea"
    
    alert.addAction(UIAlertAction(title: "Post", style: .Default, handler:  (action: UIAlertAction) -> Void in

        let textField = alert.textFields!.first!

        if textField.text != ""

            let newPost = CKRecord(recordType: "Post")
            newPost["content"] = textField.text
            let publicData = CKContainer.defaultContainer().publicCloudDatabase
            publicData.saveRecord(newPost, completionHandler: (
                record:CKRecord?, error:NSError?) -> Void in
                if error == nil
                    print("Post Saved")
                    dispatch_async(dispatch_get_main_queue(), () -> Void in
                        self.tableView.beginUpdates()
                        self.posts.insert(newPost, atIndex: 0)
                        let indexPath = NSIndexPath(forRow: 0, inSection: 0)
                        self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Top)
                        self.tableView.endUpdates()
                    )
                else
                    print("Post ERROR")
                    print(ErrorType)
                
            )

        

    ))

    alert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))

    self.presentViewController(alert, animated: true, completion: nil)
  



当我发布某些内容时我的表格应该更新时,它不会做任何事情。我不知道我是否只是写了一个糟糕的错误或什么。这些帖子出现在云套件 iCloud 在线但不在我的表格中,即使在我刷新它之后也是如此。

【问题讨论】:

你做了什么调试?是否调用了saveRecord 的完成处理程序?是errornilself.tableView.insertRowsAtIndexPaths 的电话是否已接通? 所以我把它添加到表中,但是现在当我刷新它时它全部消失了。另外,如果我写的帖子不仅仅是一个字符,则会出现错误并且不会发布。 @rmaddy 【参考方案1】:

虽然您使用的是CKDatabase.performQuery 便捷方法,但您可能会遇到CKQueryOperation.recordFetchedBlock 中的警告所描述的相同情况:

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

来源:CKQueryOperation Class Reference

this answer to another question 中描述了一种解决方法:

如果您使用 CKQuery 来支持视图,您需要保留已在本地修改的记录的侧表,并将这些记录拼接到视图中,直到查询开始返回该记录。

【讨论】:

以上是关于CloudKit-不会更新 (Swift)的主要内容,如果未能解决你的问题,请参考以下文章

swift Swift - CloudKit:更新应用程序设置

SWIFT/CloudKit - 更新记录并将其保存回容器

Swift/Cloudkit:在拉取时处理用户更改

如何更新 CloudKit 订阅

未登录 iCloud 时的 Swift CloudKit 读取

CloudKit 仪表板未更新