Thread 1: "-[entity_name relation_name]: unrecognized selector sent to instance 0x600003812bc0"

I'm finding this issue after making sure I create an entity with the correspondent attribute. This issue comes from a relation between 2 entities: GroupData and TopicData. Their relations are like shown in the screenshots.

Then, I get the context from a function like the next one. Every time I need to use the context, I call this function.


import CoreData





class DataController: ObservableObject {

    let container = NSPersistentContainer(name: "vocabul-R")



    init() {

        container.loadPersistentStores { description, error in

                if let error = error {

                    print("CoreData failed to load: \(error.localizedDescription)")

                }

        }

        container.viewContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump

        container.viewContext.retainsRegisteredObjects = true



    }

}

I first create the objects from data I get from csv files. By debugging I've made sure that the objects created have the correspondent values for each attribute and the correct objects in relations.


    guard let filepath = Bundle.main.path(forResource: data_file, ofType: "csv") else {
        return
    }

    let dataController = DataController()

    let context = dataController.container.viewContext
    do {
        try context.save()
        }
    catch {
    }

    var data = ""
    do {
        data = try String(contentsOfFile: filepath)
    } catch {
        return
    }

    var rows = data.components(separatedBy: "\n")

    rows.remove(at: 0)

    for row in rows {

        let columns = row.components(separatedBy: ",")

        let name = columns[0]

        let activation_level = (columns[1] as NSString).integerValue

        let activated: Bool = false

        let last_opened_group: Int16 = 0

        let current_level: Int16 = 0

        let topic = TopicData(context: context)

        topic.name = name

        topic.activated = activated

        topic.activationLevel = Int16(activation_level)

        topic.last_opened_group = last_opened_group

        topic.current_level = current_level

        do {
            try context.save()
            }
        catch {
            print("Context not saved")
        }
    }
}

func parseCSV_groups (data_file: String, topic_name: String) {
    guard let filepath = Bundle.main.path(forResource: data_file, ofType: "csv") else {
        return
    }
    var data = ""
    do {
        data = try String(contentsOfFile: filepath)
    } catch {
        return
    }

    var rows = data.components(separatedBy: "\n")

    rows.remove(at: 0)

    let dataController = DataController()

    let context = dataController.container.viewContext

    let topic = TopicData.getTopicFromName(name: topic_name, context: context)

    let train_list = Train_list(context: context)

    let test_list = Test_list(context: context)

    train_list.train_list = "train_list"

    test_list.test_list = "test_list"

    for row in rows {
        let columns = row.components(separatedBy: ",")
        let index_group = (columns[0] as NSString).integerValue
        let mean_level = (columns[1] as NSString).integerValue
        let cleared_words: Int16 = 0
        let group = GroupData(context: context)
        group.index_group = Int16(index_group)
        group.mean_level = Int16(mean_level)
        group.cleared_words = cleared_words
        //group.topic = topic
        topic.addToGroup(group)
        do {
            try context.save()
            }
        catch {
            print("Context not saved")
        }
    }
}

I have created objects from both entities with relations. I have other functions with relations between these and other entities seem to work fine. But now I need to get all the groups that one TopicData object has. For that, I first get a topic from its name.


        let fetchRequest = NSFetchRequest<TopicData>(entityName: "TopicData")

        fetchRequest.predicate = NSPredicate(format: "name = %@", name)

        let topics = (try? context.fetch(fetchRequest)) ?? []

        let topic = topics.first ?? TopicData()

        return topic

    }

This seems to work fine as I can print the topic name and the object type (which is TopicData). But then I try to get the groups that it has.

I've also tried to get the groups with a fetchRequest


    /fetchRequest.predicate = NSPredicate(format: "topic = %@", topic)

     let groups = (try? context.fetch(fetchRequest)) ?? []

And when I try to get one of the attributes (activated) of one of these topics, I also get an error.

I thought this could be happening because every time I use a topic to update it and save it on context again, a new topic is created which may not be related to GroupData. But I added a constraint in TopicData for name and I still get the same error. Another thing I thought is that relations could be disappearing, since I saw some people had this problem and the issue was that. But I added the retainsRegisteredObjects line in DataController and it didn't work. The full error I get is: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[TopicData group]: unrecognized selector sent to instance 0x600003812bc0' terminating with uncaught exception of type NSException

I think that is all about the problem. Any idea of what could be happening? I think I added everything relevant for the problem, but let me know if there is some other code I should add. Thank you!

It seems I didn't add a part of the code. It's just how I would get the groups for a topic: let groups = topic.group

I've seen that when using the function where I create groups, topic.group work. It is after using another function in which I update some objects where it changes. `func parseCSV_words (data_file: String, topic_name: String) {

    

    guard let filepath = Bundle.main.path(forResource: data_file, ofType: "csv") else {

        return

    }

    

    var data = ""

    do {

        data = try String(contentsOfFile: filepath)

    } catch {

        return

    }

    

    var rows = data.components(separatedBy: "\n")

    rows.remove(at: 0)

    let dataController = DataController()

    let context = dataController.container.viewContext

    

    let topic = TopicData.getTopicFromName(name: topic_name, context: context)

    

    

    for row in rows {

        let columns = row.components(separatedBy: ",")

        

        let name = columns[0]

        let translation = columns[1]

        let group_index = (columns[2] as NSString).integerValue

        let previous_guessed: Bool = false

        let character: Character = "?"

        

        let group = GroupData.getGroupFromIndexAndTopic(index: Int16(group_index), topic: topic, context: context)

        

        

        var already_shown: Bool = false

        

        if translation.contains(character) {

            already_shown = true

        }

        let word = Word(context: context)

        word.namew = name

        word.translation = translation

        word.previous_guessed = previous_guessed

        //word.group = group

        

        group.addToWordg(word)

        word.already_shown = already_shown

        

        do {

            try context.save()

            }

        catch {

            print("Context not saved")

        }

    }

}

`

This is another function I think could be relevant. The function where I create the groups works fine and I can do topic.group after using it. It's after using another function when I can't do topic.group anymore. Function:


    

    guard let filepath = Bundle.main.path(forResource: data_file, ofType: "csv") else {

        return

    }

    

    var data = ""

    do {

        data = try String(contentsOfFile: filepath)

    } catch {

        return

    }

    

    var rows = data.components(separatedBy: "\n")

    rows.remove(at: 0)

    let dataController = DataController()

    let context = dataController.container.viewContext

    

    let topic = TopicData.getTopicFromName(name: topic_name, context: context)

    

    

    for row in rows {

        let columns = row.components(separatedBy: ",")

        

        let name = columns[0]

        let translation = columns[1]

        let group_index = (columns[2] as NSString).integerValue

        let previous_guessed: Bool = false

        let character: Character = "?"

        

        let group = GroupData.getGroupFromIndexAndTopic(index: Int16(group_index), topic: topic, context: context)

        

        

        var already_shown: Bool = false

        

        if translation.contains(character) {

            already_shown = true

        }

        let word = Word(context: context)

        word.namew = name

        word.translation = translation

        word.previous_guessed = previous_guessed

        //word.group = group

        

        group.addToWord(word)

        word.already_shown = already_shown

        

        do {

            try context.save()

            }

        catch {

            print("Context not saved")

        }

    }

}




And the function that gets Group:

static func getGroupFromIndexAndTopic(index: Int16, topic: TopicData, context:NSManagedObjectContext) -> GroupData {

        let fetchRequest = NSFetchRequest<GroupData>(entityName: "GroupData")

        

        fetchRequest.predicate = NSPredicate(format: "index_group = %d AND topic = %@", index, topic)



        let groups = (try? context.fetch(fetchRequest)) ?? []

        let group = groups.first!

        return group

    }
Thread 1: "-[entity_name relation_name]: unrecognized selector sent to instance 0x600003812bc0"
 
 
Q