'CoreData: How to achieve not null and unique constraint in one-to-one relationship?

Currently, I have the following one-to-one relationship

  1. An NSPlainNote must have at least a NSContent
  2. NSContent will inversely point to a NSPlainNote

Here's how I define their relationship

NSPlainNote Entity

enter image description here


NSContent Entity

enter image description here


Model class source code

extension NSPlainNote: PlainNoteable {
    @NSManaged public var content: NSContent
}

extension NSPlainNote {
    convenience init(context: NSManagedObjectContext, plainNote: PlainNote) {
        self.init(context: context)
        
        self.copyFrom(context: context, plainNote: plainNote)
    }

    func copyFrom(context: NSManagedObjectContext, plainNote: PlainNote) {   
        if self.content.plainNote == nil {
            // Create new record
            self.content = NSContent(context: context)
            self.content.body = body
            self.content.plainNote = self
        } else {
            // Update existing record
            self.content.body = body
        }
    }
}

extension NSContent {
    @NSManaged public var body: String?
    @NSManaged public var plainNote: NSPlainNote?
}

Code to perform create/ update

if let nsPlainNote = try backgroundContext.existingObject(with: nsManagedObjectID) as? NSPlainNote {
    // Update existing record
    nsPlainNote.copyFrom(
        context: backgroundContext,
        plainNote: plainNote
    )
} else {
    // Create new record
    nsPlainNote = NSPlainNote(
        context: backgroundContext,
        plainNote: plainNote
    )
}

What I wish to have is a safe mechanism to prevent me from

  1. NSContent table contains a NULL value NSPlainNote
  2. NSContent table contains a duplicated value NSPlainNote

When I exam the generated SQLite code. It is

CREATE TABLE ZNSCONTENT ( 
    Z_PK INTEGER PRIMARY KEY, 
    Z_ENT INTEGER, 
    Z_OPT INTEGER, 
    ZPLAINNOTE INTEGER, 
    ZBODY VARCHAR 
)

CREATE INDEX ZNSCONTENT_ZPLAINNOTE_INDEX ON ZNSCONTENT (ZPLAINNOTE)

There is no mechanism to prevent NULL or duplication of ZPLAINNOTE.


The reason I am having such concern is because during row updating, instead of executing correct logic

if self.content.plainNote == nil {
    // Create new record
    self.content = NSContent(context: context)
    self.content.body = body
    self.content.plainNote = self
} else {
    // Update existing record
    self.content.body = body
}

I accidentally execute

self.content = NSContent(context: context)
self.content.body = body
self.content.plainNote = self

This causes the NSContent old row's ZPLAINNOTE turned to NULL, and a new NSContent row is created.


I would like to have NOT NULL and UNIQUE constraint at the ZPLAINNOTE column of NSContent. May I know, how I can achieve so via CoreData editor?

Thanks.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source