Различия в работе saveContext () в зависимости от мгновенного представления viewController.CoreData Enigma - PullRequest
0 голосов
/ 27 апреля 2020

Проект имеет минимальный c стек CoreData.

У меня есть один подкласс UIViewController "AddOrChangeEntityV C" для создания NSManagedObject, изменения его свойств и записи данных в БД.

Перечисленные функции работают нормально, если "AddOrChangeEntityViewController" был создан из MyFirstV C, MySecondV C, ... и MyNinthV C любого другого контроллера представления, кроме одного BadV C. В этом случае делается попытка записать сущность в БД со всеми свойствами = nil.

И я вижу эту ошибку.

Error Domain=NSCocoaErrorDomain Code=1560 "Multiple validation errors occurred."

И для каждого обязательного свойства что-то вроде

"Error Domain=NSCocoaErrorDomain Code=1570 \"firstProperty is a required value.\
UserInfo={NSValidationErrorObject=<APP.Entity: 0x600006917e80> (entity: Entity; id: 0x600000f152a0 <x-coredata:///Entity/t72AEC6D7-A854-40A3-BA9D-5830DFADC8AF2>; data: {\n    firstProperty = nil;\n    secondProperty = nil;\n}), NSValidationErrorKey = firstValue, NSLocalizedDescription=firstValue is a required value"
"Error Domain=NSCocoaErrorDomain Code=1570 \"secondProperty is a required value.\"

Следует отметить, что перед вызовом saveContext () все свойства проверяются.

AddOrChangeEntityVC: UIViewController {
var entity: Entity?

func saveEntity() -> Bool {
        //validating data

        if !validateData() {
            return false
        }
        //creating passenger
        if entity == nil {

            entity = Entity()
        }
        //saving entity
        if let entity = entity {


            //saving
            entity.firstProperty    = firstPropertyTextfield.text!
            entity.secondProperty   = secondPropertyTextfield.text!
            ...
        CoreDataStack.shared.saveContext()
        return true
    }
 }
Entity: NSManaged

class Entity: NSManagedObject {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Entity> {
        return NSFetchRequest<Entity>(entityName: "Entity")
    }

    @NSManaged public var firstProperty:        String
    @NSManaged public var secondProperty:       String

    convenience init() {
        let entity = NSEntityDescription.entity(forEntityName: "Entity",
         in: CoreDataStack.shared.persistentContainer.viewContext)!
        self.init(entity: entity, insertInto: CoreDataStack.shared.persistentContainer.viewContext)
            } 
}

CoreData Manager

    class CoreDataStack {

    static var shared = CoreDataStack() 
    lazy var persistentContainer: NSPersistentContainer = {
    let container = NSPersistentContainer(name: "APP")
    container.loadPersistentStores { storeDesription, error in
          guard error == nil else {
              fatalError("Unresolved error \(error!)")
          }
      }

      // Merge the changes from other contexts automatically. useв for Another Entity
    enter code here
      container.viewContext.automaticallyMergesChangesFromParent = true
      container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
      container.viewContext.shouldDeleteInaccessibleFaults = true
      return container
  }()

    func saveContext() {
        let context = persistentContainer.viewContext
        guard context.hasChanges else { return }
        do {
            try context.save()
        } catch let error as NSError{
            print("Error: \(error), \(error.userInfo)")
        }
    }    
}

Переход от anyV C к AddOrChangeEntityV C

        guard let entityVC = self.storyboard?.instantiateViewController(withIdentifier: "addEntityVC") as? AddOrChangeEntityVC else {return}
        self.navigationController?.pushViewController(entityVC, animated: true)
    ```

1 Ответ

0 голосов
/ 27 апреля 2020

Ну, Core Data загадочна и даже мрачна.

Я сделал эти простые шаги. 1) в AddOrChangeEntityV C я добавил

var context: NSManagedObjectContext = CoreDataStack.shared.persistentContainer.newBackGroundContext()

2) при инициализации Entity: NSManaged (если нам нужно его создать)

if entity == nil {
    entity = Entity(context: context)
    }

3) неожиданно столкнулся с этим после некоторого сохранение в NSFetchingResultController результаты добавили новую загадочную сущность со всеми свойствами == nil я отфильтровал результаты в tableView (_ tableView: UITableView, numberOfRowsInSection раздел: Int) -> метод Int и tableView (_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewlle удалив из fetchedResultsController.fetchedObjects? элементы с некоторыми свойствами == ноль.

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  return fetchedResultsController.fetchedObjects?.filter({!$0.firstProperty.isEmpty}).count ?? 0 
}

и

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   if fetchedResultsController.object(at: indexPath).isValid {
        let entity = fetchedResultsController.object(at: indexPath)
        let cell = UITableViewCell()update(with: entity)
    ....
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...