ios - 从 SyncTable 拉取更新核心数据对象,而不是调用 NSFeatchedResults 委托(delegate)方法

标签 ios swift core-data azure-mobile-services nsfetchedresultscontroller

我正在使用 NSFetchedResultsController 使用来自 coredata 实体的数据跟踪和加载具有两个部分(基于可用的 true 或 false)的 UITableView。 Coredata 实体由 azure syncTable pull 方法填充。我从 VC 中的 ViewDidLoad() 方法调用 fetchedDataController?.performFetch() 。 数据分为两部分 - 实体数据中第 1 部分 available 为假,第 2 部分 - avaliable 为真。

这是 NSFRC 初始化的代码片段:

lazy var fetchedDataController: NSFetchedResultsController<Product>? = {

        let req = NSFetchRequest<NSFetchRequestResult>(entityName: "Product")

        req.sortDescriptors = [NSSortDescriptor(key: "available", ascending: true),     NSSortDescriptor(key: "createdAt", ascending: false)]
        guard let dbContext = self.appDelegate?.managedObjectContext else { return nil }

        let controller = NSFetchedResultsController(fetchRequest: req, managedObjectContext: dbContext, sectionNameKeyPath: "available", cacheName: nil) as? NSFetchedResultsController<Product>

        controller?.delegate = self
        return controller
    }() 

问题: 1. 即使实体行数据有更新,FRC 委托(delegate)方法也不会自动触发。就像我在后端将 available 从 true 更改为 false 并执行了 SyncTable.pull,我可以看到 coredata 表已更新为最新数据(我打开了 .sql 文件并能够看到数据)

  1. 为了克服变通方法,我每次拉取时都会调用执行提取,在这种情况下,当我向下滚动到第 2 部分时,应用程序因索引错误而崩溃,这意味着它没有正确更新表部分和行。

委托(delegate)方法实现:

 func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {

   self.tableView.beginUpdates()
}

    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        self.tableView.endUpdates()
    }

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
        let sectionIndexSet = IndexSet(integer: sectionIndex)
        switch type {
            case .insert:
                self.tableView.insertSections(sectionIndexSet, with: .fade)
            case .update:
                self.tableView.reloadSections(sectionIndexSet, with: .fade)
            case .delete:
                self.tableView.deleteSections(sectionIndexSet, with: .fade)
            default: break
        }
    }


    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
        switch type {
            case .insert:
                if let newIndex = newIndexPath {
                    self.tableView.insertRows(at: [newIndex], with: .fade)
                }
            case .update:
                if let index = indexPath {
                    self.tableView.reloadRows(at: [index], with: .fade)
                }
            case .move:
                if let index = indexPath {
                    self.tableView.deleteRows(at: [index], with: .fade)
                    if let newIndex = newIndexPath {
                        self.tableView.insertRows(at: [newIndex], with: .fade)
                    }
                }
            case .delete:
                if let index = indexPath {
                    self.tableView.deleteRows(at: [index], with: .fade)
                }
            default: break
        }
    }

我深陷其中,不胜感激。

最佳答案

为 ManagedObjectContext 保存添加观察者可以解决此问题:

NotificationCenter.default.addObserver(self,选择器:#selector(refreshContent),名称:NSNotification.Name.NSManagedObjectContextDidSave,对象:nil)

func refreshContent(notif: 通知) { 自己。 fetchedDataController?.managedObjectContext.mergeChanges(fromContextDidSave: notifn)

关于ios - 从 SyncTable 拉取更新核心数据对象,而不是调用 NSFeatchedResults 委托(delegate)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44270528/

相关文章:

ios - 如何快速将阿拉伯数字转换为英文数字?

ios - 为什么核心数据不会持久保存到磁盘?

ios - 在 iOS 上更改主题

ios - subview 在 View 中垂直居中对齐,以编程方式使用自动布局约束

iphone - 如何就地交换 `NSMutableDictionary` 键和值?

swift - 实例化的可选变量在 Xcode 调试器中显示为 nil

ios - Xcode lldb 不存储属性

ios - 表格单元格很大

ios - 如何在 Core Data 中进行自定义验证(为了唯一性)?

ios - 如何用Core Data设计对象的 "ordering"