Search code examples
ioscore-datansset

swift core data relationship one to many for own entity


Hi I'm building a newspaper database which have item relationship to itself (item can have many other item as child)

here is my NSmanageObjectSubclass

import Foundation
import CoreData
extension Item {

    @NSManaged var by: String?
    @NSManaged var dead: NSNumber?
    @NSManaged var descendants: NSNumber?
    @NSManaged var id: NSNumber?
    @NSManaged var isdeleted: NSNumber?
    @NSManaged var score: NSNumber?
    @NSManaged var text: String?
    @NSManaged var time: NSDate?
    @NSManaged var title: String?
    @NSManaged var type: String?
    @NSManaged var url: String?
    @NSManaged var kids: NSSet?
    @NSManaged var parent: Item?
    @NSManaged var parts: NSSet?

}

Problem is that how can i add item to property kids: NSSet the relationship define is one to many to its own with reverse. Any help is much appreciate. Thanks.

my coredata xcmodel enter image description here

enter image description here

enter image description here


Solution

  • First update your class Managed Object class to use Sets instead of NSSet

         import Foundation
            import CoreData
            extension Item {
    
                @NSManaged var by: String?
                @NSManaged var dead: NSNumber?
                @NSManaged var descendants: NSNumber?
                @NSManaged var id: NSNumber?
                @NSManaged var isdeleted: NSNumber?
                @NSManaged var score: NSNumber?
                @NSManaged var text: String?
                @NSManaged var time: NSDate?
                @NSManaged var title: String?
                @NSManaged var type: String?
                @NSManaged var url: String?
                @NSManaged var kids: Set<Item>
                @NSManaged var parent: Item?
                @NSManaged var parts: NSSet?
    
            }
    

    Secondly create a fetchRequest named getItemByID with expression id == $ID

    Third create a function to get item by id

        func getItemById(ID:String) -> Item?
        {
            let fetchRequest : NSFetchRequest = self.managedObjectModel.fetchRequestFromTemplateWithName("getItemByID", substitutionVariables: ["ID": ID])!
            do {
                let fetchedResult = try managedObjectContext!.executeFetchRequest(fetchRequest) as! [Item]
                if fetchedResult.count > 0 {
                    let result = fetchedResult[0]
                    return result
                }
            }
            catch {
                print("Could not fetch \(error)")
            }
            return nil
        }
    

    After that you have many options to set relations

    a) you create relation after adding parent & child to coreData

    func addChildToParent(childID:String,parentID:String)
        {
            if let childItem = getItemById(childID)
            {
               if let parentItem = getItemById(parentID)
               {
                  parentItem.kids.insert(menuItemCatering)
                  childItem.parent = parentItem
               }
            }
           saveContext()
        }