CloudKit-不会更新 (Swift)
CloudKit-Won't update (Swift)
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)
}
}
当我的 table 应该在我 post 更新时,它没有做任何事情。我不知道我是否只是写了一个严重的错误或其他什么。 posts 出现在云工具包 iCloud 在线但不在我的 table 中,即使在我刷新它之后也是如此。
虽然您使用的是 CKDatabase
.performQuery
便捷方法,但您可能遇到了 CKQueryOperation
.recordFetchedBlock
中的警告所描述的相同情况:
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.
来源:CKQueryOperation Class Reference
this answer to another question:
中描述了解决方法
If you're using a CKQuery to back a view you'll want to keep a side table of records that have been modified locally and stitch those into the view until the query starts returning that record.
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)
}
}
当我的 table 应该在我 post 更新时,它没有做任何事情。我不知道我是否只是写了一个严重的错误或其他什么。 posts 出现在云工具包 iCloud 在线但不在我的 table 中,即使在我刷新它之后也是如此。
虽然您使用的是 CKDatabase
.performQuery
便捷方法,但您可能遇到了 CKQueryOperation
.recordFetchedBlock
中的警告所描述的相同情况:
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.
来源:CKQueryOperation Class Reference
this answer to another question:
中描述了解决方法If you're using a CKQuery to back a view you'll want to keep a side table of records that have been modified locally and stitch those into the view until the query starts returning that record.