无法刷新核心数据并使用UIRefreshControl在tableview中显示它

问题描述:

我从博客提取json数据并将其存储在核心数据中。现在我想添加拉来刷新,以便如果博客上有任何更新,它们也反映在应用程序中。我发现类似的问题后,并建议增加该代码无法刷新核心数据并使用UIRefreshControl在tableview中显示它

override func viewDidLoad() { 
    refresher = UIRefreshControl() 
    refresher.attributedTitle = NSAttributedString(string: "Pull to Refresh") 
    refresher.addTarget(self, action: "refresh", forControlEvents: UIControlEvents.ValueChanged) 
    self.tableView.addSubview(refresher) 
} 

func refresh() { 
    NSFetchedResultsController.deleteCacheWithName("Master") 
    var error: NSError? = nil 
    self.fetchedResultsController.performFetch(&error) 
    self.tableView.reloadData() 
    println("refreshed") 

     } 

的问题既不是coredata也没有实现代码如下正在得到更新蒲凌列表刷新后。

,在核心数据获取并保存JSON数据的代码如下:

func animalSelected(animal: Animal) { 

var appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate 
var context: NSManagedObjectContext = appDel.managedObjectContext! 
let session = NSURLSession.sharedSession() 
var error : NSError? 

let task = session.dataTaskWithURL(animal.url!, completionHandler: {data, response, error -> Void in 

    if (error != nil){ 
     println(error) 

    }else{ 

     var request = NSFetchRequest(entityName: "MIBlog") 
     request.returnsObjectsAsFaults = false 
     var results = context.executeFetchRequest(request, error: nil) 

     for result in results! 
     { 
      context.deleteObject(result as NSManagedObject) 
      context.save(nil) 

     } 


     let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary 

     var posts = [[String:String]()] 

     var post:AnyObject 

     var authorDictionary:AnyObject 
     var newBlogItem:NSManagedObject 
     for var i = 0; i < jsonResult["posts"]!.count; i++ 
     { 
      posts.append([String:String]()) 
      post = jsonResult["posts"]![i] as NSDictionary 
      posts[i]["title"] = post["title"] as? NSString 
      posts[i]["publishedDate"] = post["date"] as? NSString 
      posts[i]["content"] = post["content"] as? NSString 
      authorDictionary = post["author"] as NSDictionary 
      posts[i]["author"] = post["name"] as? NSString 


      newBlogItem = NSEntityDescription.insertNewObjectForEntityForName("MIBlog", inManagedObjectContext: context) as NSManagedObject 
      newBlogItem.setValue(posts[i]["title"], forKey: "title") 
      newBlogItem.setValue(posts[i]["publishedDate"], forKey: "publishedDate") 
      newBlogItem.setValue(posts[i]["content"], forKey: "content") 
      newBlogItem.setValue(posts[i]["author"], forKey: "author") 

      context.save(nil) 

     } 
     request = NSFetchRequest(entityName: "MIBlog") 
     request.returnsObjectsAsFaults = false 
     results = context.executeFetchRequest(request, error: nil) 

    } 

}) 

task.resume() 

delegate?.collapseSidePanels?() 

} 

MY fetchResultController代码:

// MARK: - Fetched results controller 

var fetchedResultsController: NSFetchedResultsController { 
    if _fetchedResultsController != nil { 
     return _fetchedResultsController! 
     } 
     var appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate 
     self.managedObjectContext = appDel.managedObjectContext 

     let fetchRequest = NSFetchRequest() 
     // Edit the entity name as appropriate. 
     let entity = NSEntityDescription.entityForName("MIBlog", inManagedObjectContext: self.managedObjectContext!) 
     fetchRequest.entity = entity 

     // Set the batch size to a suitable number. 
     fetchRequest.fetchBatchSize = 20 

     // Edit the sort key as appropriate. 
     let sortDescriptor = NSSortDescriptor(key: "publishedDate", ascending: false) 
     let sortDescriptors = [sortDescriptor] 

     fetchRequest.sortDescriptors = [sortDescriptor] 

     // Edit the section name key path and cache name if appropriate. 
     // nil for section name key path means "no sections". 
     let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: nil, cacheName: "Master") 
     aFetchedResultsController.delegate = self 
     _fetchedResultsController = aFetchedResultsController 

     var error: NSError? = nil 
     if !_fetchedResultsController!.performFetch(&error) { 
      // Replace this implementation with code to handle the error appropriately. 
      // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
      //println("Unresolved error \(error), \(error.userInfo)") 
      abort() 
     } 

     return _fetchedResultsController! 
} 
var _fetchedResultsController: NSFetchedResultsController? = nil 

func controllerWillChangeContent(controller: NSFetchedResultsController) { 
    self.tableView.beginUpdates() 


} 

func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) { 
    switch type { 
    case .Insert: 
     self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade) 
    case .Delete: 
     self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade) 
    default: 
     return 
    } 
} 

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath) { 
    switch type { 
    case .Insert: 
     tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade) 
    case .Delete: 
     tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
    case .Update: 
     self.configureCell(tableView.cellForRowAtIndexPath(indexPath)!, atIndexPath: indexPath) 
    case .Move: 
     tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
     tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade) 
    default: 
     return 
    } 
     } 

func controllerDidChangeContent(controller: NSFetchedResultsController) { 
    self.tableView.endUpdates() 
      activityIndicator.stopAnimating() 
} 

我无法弄清楚我应该怎么更新核心数据同时刷新。

Plsss PLSS请求帮助。

由于您使用的是NSFetchedResultsController,您只需要正确实施NSFetchedResultsControllerDelegate方法即可。那么你所要做的就是保存。

context.save(nil) 

一些言论:

我认为这不是一个好主意,保存在循环中。插入所有对象后最好保存在最后。

删除所有内容并重新插入全部内容并没有多大意义。相反,你只应该改变那些有变化的对象。

当完成块返回时,变量results将被丢弃。目前还不清楚你想用这个获取结果完成什么。

如果你没有实施所取得的结果控制器委托,则需要再次调用performFetch,或者干脆获取的成果控制器设置为nil,让它懒洋洋地重新创建本身。然后,只需更新应该从获取的成果控制器

self.tableView.reloadData() 
+0

我新的iOS开发,并提出在Udemy的在线课程我已经实现的方法自动获取数据的UI。但是,你是否建议我在我的刷新函数中添加'context.save(nil)'? – 2015-02-12 18:01:39

+0

这就是'NSFetchedResultsControllerDelegate'的工作原理。使用您在创建新项目时查找的Xcode样板代码并检查“核心数据”。 – Mundi 2015-02-12 18:04:57

+0

是的,先生..我在创建项目时检查了核心数据。我已更新我的问题以显示'FetchedResultsController'。我想知道在Refresh函数中应该做些什么,以便核心数据和tableView都在拉动刷新时得到更新。 – 2015-02-12 18:13:40