难以在Swift 3中配置NSFetchedResultsController

时间:2016-09-22 15:13:55

标签: ios swift core-data nsfetchedresultscontroller swift3

我正在重构从Swift 2到Swift 3的现有项目。在重构Core Data之前,一切都很简单。我能够创建托管对象并将其保留在managedObjectContext中,但我很难让NSFetchedResultsController工作。我看了一下this post,但它没有让我越过终点线。

从JSON导入记录后,我使用以下代码验证managedObjectContext中有对象:

func recordCount() -> Int {
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "MyEntity")
    let count = try! context.count(for: fetchRequest)
    return count
}

当我创建fetchedResultsController时,我遇到了麻烦。我的代码没有崩溃,但是尽管存在与我的搜索匹配的对象,但它不会返回NSManagedObjects

以下是我在NSFetchedResultsController中创建UIViewController的方式。

class MyViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate {
    // This is set on a prior viewController before segue.
    // I've verified it's not nil
    var selectedEquipmentString: String?

    let managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

    lazy var fetchedResultsController: NSFetchedResultsController<MyEntity> = {
        // I've tried altering the syntax of the fetchRequest
        // let fetchRequest: NSFetchRequest<MyEntity> = MyEntity.fetchRequest()
        let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "MyEntity")
        let sortDescriptor = NSSortDescriptor(key: "generalArea", ascending: true)
        fetchRequest.sortDescriptors = [sortDescriptor]
        fetchRequest.predicate = NSPredicate(format: "equipmentDescription == %@", self.selectedEquipmentString!)
        let frc: NSFetchedResultsController<MyEntity> = NSFetchedResultsController(fetchRequest: fetchRequest as! NSFetchRequest<MyEntity>, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: "generalArea", cacheName: nil)
        frc.delegate = self
        return frc
    }()

    // MARK: - View Lifecycle Methods (abbreviated)
    override func viewDidLoad() {
        super.viewDidLoad()
        // I've tried moving this call to viewWillAppear and viewDidAppear without success
        fetchObjectsFromManagedObjectContext()
    }

    // MARK: - Core Data Methods (abbreviated)
    func fetchObjectsFromManagedObjectContext() {
        do {
            try fetchedResultsController.performFetch()
        } catch {
            print("error: \(error)")
            return
        }
        print ("There are \(fetchedResultsController.fetchedObjects!.count) returned from fetchObjectsFromManagedObjectContext")
    }
}

此代码不会崩溃,但它不会从fetchRequest返回任何记录。我能够在谓词中使用拼写错误强制崩溃,但是没有拼写错误,尽管对象与谓词匹配,但没有返回任何对象。

我欢迎任何建议:我的错误在哪里。我放心,我知道这对我来说是一个令人吃惊的愚蠢疏忽。谢谢你的阅读。

2 个答案:

答案 0 :(得分:3)

您的NSFetchRequest应具有NSFetchRequest<MyEntity>类型,但您指定NSFetchRequest<NSFetchRequestResult>。尝试改变这一点,让我知道它是否有帮助

答案 1 :(得分:0)

请检查以下代码为NSFetchedResultsController swift 3 ..

 override func viewDidLoad() {
     super.viewDidLoad()
    do {
        try self.fetchedResultsController.performFetch()
    } catch {
        let fetchError = error as NSError
        print("Unable to Perform Fetch Request")
        print("\(fetchError), \(fetchError.localizedDescription)")
    }

}  // MARK: - NSFetchedResultsController

fileprivate lazy var fetchedResultsController: NSFetchedResultsController<UserExistenceOnXMPPCD> = {
    let fetchRequest = NSFetchRequest<UserExistenceOnXMPPCD>(entityName: "UserExistenceOnXMPPCD")
    fetchRequest.sortDescriptors = [
        NSSortDescriptor(key: "name", ascending: true)]

    let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext:CoreDataController.sharedInstance.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)

    try! fetchedResultsController.performFetch()
    fetchedResultsController.delegate = self
    if let quotes = fetchedResultsController.fetchedObjects {
        if quotes.count > 0 {
            print(quotes.count)
        }
    }
    return fetchedResultsController
}()


// MARK: - NSFetchedResultsController delegate methods
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>)  {
    tableView.beginUpdates()
}

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