Проверка вставки Core Data (validateForInsert) запускается слишком рано? - PullRequest
1 голос
/ 29 марта 2019

Я пытаюсь настроить проверку в основных данных на простую структуру управляемого объекта.

Существует Building и Floor и взаимосвязь один-ко-многим между ними (в Building естьмного этажей).

Валидатор в Floor выглядит так

// extension of auto generated managed object (Floor)
extension Floor {
    override public func validateForInsert() throws {
        try super.validateForInsert()
        if (self.building == nil) {
            throw ValidationError.missingBuilding("a floor requires a building")
        }
    }
}

И мой простой менеджер для тестирования:

import Foundation
import CoreData

class ObjectNodeManager {

    let persistentContainer: NSPersistentContainer!

    init(container: NSPersistentContainer) {
        self.persistentContainer = container
        self.persistentContainer.viewContext.automaticallyMergesChangesFromParent = true
    }

    lazy var backgroundContext: NSManagedObjectContext = {
        return self.persistentContainer.newBackgroundContext()
    }()

    func insertObjectNode(objectNode: ObjectNode) -> ObjectNode? {
        backgroundContext.insert(objectNode)
        return objectNode
    }

    func save() {
        if backgroundContext.hasChanges {
            do {
                try backgroundContext.save()
            } catch {
                fatalError("save error \(error)")
            }
        }
    }
}

Когда я пытаюсь создатьЗа исключением нового здания и этажа, я получаю исключение.

let building = Building(context: manager.backgroundContext)
let floor = Floor(context: manager.backgroundContext)
floor.building = building // VALIDATION EXCEPTION!

// a basic backgroundContext.save() (persistentContainer) in the manager
manager.save()

С validationForInsert невозможно вставить / сохранить управляемые объекты.В качестве альтернативы я мог бы использовать validationForUpdate, но это было бы слишком поздно, поскольку я не хочу хранить Floor без надлежащего отношения к Building.

. Любое предложение о том, как сохранить управляющий объект с требуемымотношения и проверка на вставке?

Спасибо.

Ответы [ 2 ]

1 голос
/ 01 апреля 2019

Контекст manager.background всегда возвращает новый контекст, ваши building и floor существуют в двух разных контекстах.

let backgroundContext = manager.backgroundContext
let building = Building(context: backgroundContext)
let floor = Floor(context: backgroundContext)
floor.building = building
manager.save()
0 голосов
/ 29 марта 2019

Когда я впервые начал использовать Core Data в 2009 году, я столкнулся с похожими ложными тревогами проблемами. Мое решение было и остается: Не использовать проверку основных данных в вашем верхнем уровне main контекст управляемого объекта . То есть не реализовывать validateForInsert(). Даже если Core Data правильно помечает тревогу true , как вы видели, это происходит во время сохранения, что слишком поздно, чтобы что-то делать с этим. Пользователи недовольны, когда их работа не может быть сохранена.

Возможно, вы захотите использовать проверку базовых данных в контексте child управляемого объекта. В этом случае вы, как правило, находитесь в контроллере представления, ошибка проверки обнаруживается сразу после того, как пользователь ввел его, и ваше немедленное представление ошибки будет иметь смысл для пользователя.

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