Search code examples
swiftcore-datarelationshipnsmanagedobjectentities

When loading an NSManagedObject from Core Data, do I get it's children for free?


I'm attempting to learn how to use this fancy new pattern of Relationships in Core Data to emulate a String array. I have an Alarm entity and a NotificationUuid entity. Alarm is NotificationUuid's parent entity, because an Alarm can have many NotificationUuids, and a NotificationUuid can only have one parent Alarm. I have all this set up in my .xcdatamodeld file.

My question is this: When I fetch the parent Alarm object like this:

private func loadAlarms() {

    os_log("loadAlarms() called", log: OSLog.default, type: .debug)
    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
            return
    }
    let managedContext = appDelegate.persistentContainer.viewContext
    let fetchRequest = NSFetchRequest<AlarmMO>(entityName: "Alarm")

    do {
        if self.alarms.count == 0 {
            self.alarms = try managedContext.fetch(fetchRequest)
            os_log("Loading %d alarms", log: OSLog.default, type: .debug, self.alarms.count)
        } else {
            os_log("Didn't need to load alarms", log: OSLog.default, type: .debug)
        }
    } catch let error as NSError {
        print("Could not fetch alarms. \(error), \(error.userInfo)")
    }

}

do I get the AlarmMO (Alarm Managed Object) object's children, the NotificationUuid objects, for free? Or do I now have to set up a fetch request for them too? How does this whole fancy parent/child relationship work, and how do I set/load stuff from these entities?

Thanks

Here's how I've defined AlarmMO:

import CoreData

@objc(AlarmMO)
public class AlarmMO: NSManagedObject {

    @NSManaged public var alarmNumber: Int64
    @NSManaged public var alarmTime: NSDate?
    @NSManaged public var endTimeInterval: Double
    @NSManaged public var recurrence: Int64
    @NSManaged public var startTimeInterval: Double
    @NSManaged public var notificationUuidChildren: NSSet?


}

// MARK: Generated accessors for notificationUuidChildren
extension AlarmMO {

    @objc(addNotificationUuidChildrenObject:)
    @NSManaged public func addToNotificationUuidChildren(_ value: NotificationUuidMO)

    @objc(removeNotificationUuidChildrenObject:)
    @NSManaged public func removeFromNotificationUuidChildren(_ value: NotificationUuidMO)

    @objc(addNotificationUuidChildren:)
    @NSManaged public func addToNotificationUuidChildren(_ values: NSSet)

    @objc(removeNotificationUuidChildren:)
    @NSManaged public func removeFromNotificationUuidChildren(_ values: NSSet)

}

and NotificationUuidMO:

import CoreData

@objc(NotificationUuid)
public class NotificationUuidMO: AlarmMO {

    @NSManaged public var notificationUuid: String
    @NSManaged public var alarmParent: AlarmMO

}

Solution

  • When seeing your AlarmMO model, you can just fetch your AlarmMO model which will hold the list of NotificationUuidMO in notificationUuidChildren Set. So there is no need to fetch NotificationUuidMO separately.

    And AlarmMO to NotificationUuidMO is one to many relationship. So you can get notificationUuidChildren from AlarmMO and alarmParent from NotificationUuidMO.

    To add NotificationUuidMO to notificationUuidChildren Set, you can use Core-Data generated accessors given in extension AlarmMO.

    Example:

    let notificationUuid = NotificationUuidMO....
    let alarmMO = AlarmMO....
    
    alarmMO.addToNotificationUuidChildren(notificationUuid)//Here your notificationUuid will be added to `notificationUuidChildren` Set and `alarmParent` of your `notificationUuid` will be automatically assigned to `alarmMO`.