虽然项目正在保存在核心数据中,但在重新启动之前无法查看它们

Although items are being saved in core data, not able to view them until a relaunch

这是一个示例,其中 FetchedResultsControllerViewController 中使用,并且来自另一个 ViewController 的保存没有传递给它。

  1. MainVC.swift

    lazy var coreDataManager = CoreDataManager()
    
    // Initialize fetched request
    private var fetchRecordRequestController: NSFetchedResultsController = NSFetchedResultsController()
    
    override func viewDidLoad() {
    super.viewDidLoad()
    
    // Do any additional setup after loading the view.
    
    // Initialize managedObjectContext
    let mainManagedObjectContext = coreDataManager.managedObjectContext
    
    // Create Fetch Request
    let fetchRequest = NSFetchRequest(entityName: "Record")
    
    // Configure Fetch Request
    fetchRequest.sortDescriptors = [NSSortDescriptor(key: "date", ascending: false)]
    
    // Initialize Fetched Results Controller
    fetchRecordRequestController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: mainManagedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
    
    // Configure Fetched Results Controller
    fetchRecordRequestController.delegate = self
    
    // Fetch data from object
    do {
        try fetchRecordRequestController.performFetch()
    } catch let fetchError as NSError {
        print("(RootViewController)fetchError: \(fetchError), \(fetchError.userInfo)")
    }
    
    // Add observer in NSNotificationCenter for NSManagedObjectContextObjectsDidChange
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(managedObjectContextObjectsDidChange), name: NSManagedObjectContextObjectsDidChangeNotification, object: mainManagedObjectContext)
    
    override func viewWillDisappear(animated: Bool) {
    NSNotificationCenter.defaultCenter().removeObserver(self)
    }
    
    // MARK: - NSFetchedResultsController Delegate Methods
    
    func controllerWillChangeContent(controller: NSFetchedResultsController) {
        tableView.beginUpdates()
    }
    
    // Delete corresponding row in tableView
    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:
        tableView.reloadRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
    case .Move:
        tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
        tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
    }
    }
    
    func controllerDidChangeContent(controller: NSFetchedResultsController) {
    tableView.endUpdates()
    }
    
    func managedObjectContextObjectsDidChange(notification: NSNotification) {
    
    let mainManagedObjectContext = coreDataManager.managedObjectContext
    guard let userInfo = notification.userInfo else { return }
    
    if let inserts = userInfo[NSInsertedObjectsKey] as? Set<NSManagedObject> where inserts.count > 0 {
        print("--- INSERTS ---")
        print(inserts)
        print("+++++++++++++++")
        do {
            try mainManagedObjectContext.save()
        } catch let saveError as NSError {
            print("(RootViewController)saveError: \(saveError), \(saveError.userInfo)")
        }
    }
    
    if let updates = userInfo[NSUpdatedObjectsKey] as? Set<NSManagedObject> where updates.count > 0 {
        print("--- UPDATES ---")
        for update in updates {
            print(update.changedValues())
        }
        print("+++++++++++++++")
    }
    
    if let deletes = userInfo[NSDeletedObjectsKey] as? Set<NSManagedObject> where deletes.count > 0 {
        print("--- DELETES ---")
        print(deletes)
        print("+++++++++++++++")
    }
    }
    
  2. AddRecordVC.swift

    // Method to save the extracted values to CoreData Objects
    private func saveValues() {
    // Initializing
    let mainManagedObjectContext = coreDataManager.managedObjectContext
    // Initialize entity description
    let RecordDescription = NSEntityDescription.entityForName("Record",inManagedObjectContext:mainManagedObjectContext)
    let record = Record(entity: RecordDescription!, insertIntoManagedObjectContext: mainManagedObjectContext)
    // Set object values from temporary variables
    record.date = dateTemp!
    record.tareWeight = tareWeightTemp
    record.grossWeight = grossWeightTemp
    record.nettWeight = nettWeightTemp
    record.numberOfBags = numberOfBagsTemp
    record.weightOfBags = weightOfBagsTemp
    record.rivaju = rivajuTemp
    record.putti = puttiTemp
    record.rateOfPaddy = rateOfPaddyTemp
    record.amount = amountTemp
    // Save the object
    do {
        if mainManagedObjectContext.hasChanges {
            try mainManagedObjectContext.save()
        }
    } catch let saveError as NSError {
        print("(AddRecordViewController)saveError: \(saveError), \(saveError.userInfo)")
    }
    }
    

一旦 AddRuleVC 返回到 RootVC,视图就不会刷新。 但是应用程序退出并重新启动后,它确实显示了数据。单独的class用于CoreDataStack,如下所示。

  1. CoreDataManager.swift

    class CoreDataManager: NSObject {
    
    // MARK: - Core Data Stack
    
    lazy var managedObjectModel: NSManagedObjectModel = {
    let modelURL = NSBundle.mainBundle().URLForResource("App Name", withExtension: "momd")!
    return NSManagedObjectModel(contentsOfURL: modelURL)!
    }()
    
    lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
    // Create the coordinator and store
    let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
    let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
    var failureReason = "There was an error creating or loading the application's saved data."
    do {
        try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
    } catch {
        // Report any error we got.
        var dict = [String: AnyObject]()
        dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
        dict[NSLocalizedFailureReasonErrorKey] = failureReason
    
        dict[NSUnderlyingErrorKey] = error as NSError
        let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
        NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
        abort()
    }
    
    return coordinator
    }()
    
    lazy var managedObjectContext: NSManagedObjectContext = {
    let coordinator = self.persistentStoreCoordinator
    var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
    managedObjectContext.persistentStoreCoordinator = coordinator
    managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
    return managedObjectContext
    }()
    

    // 标记:- 辅助方法

    func saveContext () {
    if managedObjectContext.hasChanges {
        do {
            try managedObjectContext.save()
        } catch {
            let nserror = error as NSError
            NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
            abort()
        }
    }
    }
    
    lazy var applicationDocumentsDirectory: NSURL = {
    let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
    return urls[urls.count-1]
    }()
    }
    

您的 CoreDataManager class 正在 AddRecordVC 中生成一个新的托管对象上下文,与 MainVC 中的不同,因此当您保存第二个上下文时,持久存储将会更新,但更改不会反映在第一个上下文中,除非您合并更改。

这样不好,主线程只需要一个上下文。所以你应该做的是对托管对象上下文使用依赖注入。当您的应用程序启动时启动 CoreDataManager,然后将上下文注入 MainVC,然后当您转到 AddRecordVC 时,也只需将相同的上下文也传递到那里。

您需要在保存新项目后通过异步执行 tableview.reloadData() 来重新加载您的表格视图。