NSFetchedResultsController не может обновить tableView swift4 - PullRequest
0 голосов
/ 25 сентября 2018

Я пытаюсь заставить его работать последние пару дней и не могу заставить его работать.Это что-то крошечное, очевидно, я не могу найти.Не могли бы вы взглянуть и дать мне некоторое представление о моем коде?Я пытаюсь обновить logView с сохранением приложения в coredata.Вот весь код для ViewController и CoreData Handler.

/// fetch controller
lazy var fetchController: NSFetchedResultsController = { () -> NSFetchedResultsController<NSFetchRequestResult> in
    let entity = NSEntityDescription.entity(forEntityName: "Logs", in: CoreDataHandler.sharedInstance.backgroundManagedObjectContext)
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>()
    fetchRequest.entity = entity

    let nameDescriptor = NSSortDescriptor(key: "name", ascending: false)
    fetchRequest.sortDescriptors = [nameDescriptor]

    let fetchedController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: CoreDataHandler.sharedInstance.backgroundManagedObjectContext, sectionNameKeyPath: "duration", cacheName: nil)
    fetchedController.delegate = self as? NSFetchedResultsControllerDelegate
    return fetchedController
}()

override func viewDidLoad() {
    title = "Week Log"

    tableView.tableFooterView = UIView(frame: CGRect.zero)
    tableView.separatorColor = UIColor.black
    tableView.backgroundColor = UIColor.red

    refreshView()
    loadNormalState()
    loadCoreDataEntities()

}


/**
 Refresh the view, reload the tableView.
 */
func refreshView() {
    loadCoreDataEntities()
    tableView.reloadData()
}



/**
 Load history entities from core data. (I'm printing on the console and
 be able to see the the fetched data but I can't load it to tableView.)
 */

func loadCoreDataEntities() {

        do {
            try fetchController.performFetch()
        } catch {
            print("Error occurred while fetching")
        }
}

import Foundation
import CoreData

class CoreDataHandler: NSObject {

/**
 Creates a singleton object to be used across the whole app easier

 - returns: CoreDataHandler
 */
class var sharedInstance: CoreDataHandler {
    struct Static {
        static var instance: CoreDataHandler = CoreDataHandler()
}
    return Static.instance
}


lazy var backgroundManagedObjectContext: NSManagedObjectContext = {
    let backgroundManagedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
    let coordinator = self.persistentStoreCoordinator
    backgroundManagedObjectContext.persistentStoreCoordinator = coordinator
    return backgroundManagedObjectContext
}()

lazy var objectModel: NSManagedObjectModel = {
    let modelPath = Bundle.main.url(forResource: "Model", withExtension: "momd")
    let objectModel = NSManagedObjectModel(contentsOf: modelPath!)
    return objectModel!
}()

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
    let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.objectModel)

    // Get the paths to the SQLite file
    let storeURL = self.applicationDocumentsDirectory().appendingPathComponent("Model.sqlite")

    // Define the Core Data version migration options
    let options = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true]

    // Attempt to load the persistent store
    var error: NSError?

    var failureReason = "There was an error creating or loading the application's saved data."
    do {
        try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: options)
    } catch {
        // Report any error we got.
        var dict = [String: AnyObject]()
        dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" as AnyObject
        dict[NSLocalizedFailureReasonErrorKey] = failureReason as AnyObject

        dict[NSUnderlyingErrorKey] = error as NSError
        let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
        // Replace this 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.
        NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
        abort()
    }
    return persistentStoreCoordinator
}()

func applicationDocumentsDirectory() -> NSURL {
    return FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).last! as NSURL
}

func saveContext() {
    do {
        try backgroundManagedObjectContext.save()
    } catch {
        print("Error while saving the object context")
        // Error occured while deleting objects
    }
}

1 Ответ

0 голосов
/ 25 сентября 2018

У вас где-то есть делегат источника данных.Этот делегат источника данных сообщает табличному представлению о количестве элементов и их содержании.Откуда он знает, сколько предметов?Это должно храниться где-то.

Когда контроллер выборки успешен, он должен изменить данные, на которые так или иначе полагается делегат источника данных, и затем вызвать reloadData.Ты этим занимаешься?Делаете ли вы что-нибудь, что приводит к тому, что делегат источника данных изменяет количество элементов, о которых он сообщает?

И вызов loadCoreDataEntities, за которым сразу следует reloadData, - нонсенс.loadCoreDataEntities является асинхронным.К тому времени, когда вы вызываете reloadData, он еще не загрузил никаких сущностей.realodData вызывается после завершения loadCoreDataEntities.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...