0

The goal of my app is to help users to learn the words of another language

I use for that two CoreData entities: WordEntity with attributes ru and eng. There are I want to save words in Russian and English.

And QuizEntity with attributes to, from and name. As I store words in

    var words: [WordEntity] = [],

I need to remember indexes for every quiz and name to show for user.

I have CoreDataManager class.

    class CoreDataManager{
        let context: NSManagedObjectContext
    
        private init(){
            let appDelegate = UIApplication.shared.delegate as! AppDelegate
            context = appDelegate.persistentContainer.viewContext
            fetchWords()
            fetchQuizzes()
        }
    
        static let shared = CoreDataManager()
    
        //MARK: - WordEntity
    
        var words: [WordEntity] = []
    
        //MARK: - QuizEntity
    
        var quizzes: [QuizEntity] = []

        func fetchWords(){
            let fetchRequest: NSFetchRequest<WordEntity> = WordEntity.fetchRequest()
        
           do {
                let words = try context.fetch(fetchRequest)
                self.words = words
            } catch let error as NSError {
                print(error.localizedDescription)
            }
        }

        func fetchQuizzes(){
            let fetchRequest: NSFetchRequest<QuizEntity> = QuizEntity.fetchRequest()
        
            do {
                let quizzes = try context.fetch(fetchRequest)
                self.quizzes = quizzes
            } catch let error as NSError {
                print(error.localizedDescription)
            }
        }

I want to implement function that allow user to add words to the quiz. To do that I tried to insert word into words[] and move index for quiz.to(is last index of words in this quiz).

Example(pseudocode):

    words = ["cat","audi","tesla","school"]
    quiz[0] ={
        .from = 0
        .to = 0
        name = "animals"
    }
    quiz[1] ={
        .from = 1
        .to = 2
        name = "cars"
    }
    quiz[2] ={
        .from = 3
        .to = 3
        name = "education"
    }
    For example I want to insert "bmw" to quiz2. words array will be something like -             ["cat","audi","tesla","bmw","school"] and quizzes will be: 
    quiz[1] ={
        .from = 1
        .to = 3
        name = "cars"
    }
    quiz[2] ={
        .from = 4
        .to = 5
        name = "education"
    }

I was trying three different ways. This is the best in my opinion:

    /*As i use tableViewController, I pass indexOfQuis where i want to add word.
    In the top example it is 1. dataWords is data that i want to insert,
    countOfWords means how much words I want to insert and From is index quiz[indexOfQuiz].to .*/
    func addWordsToQuiz(indexOfQuiz: Int,dataWordsRu: [String], dataWordsEng: [String], countOfWords: Int, from: Int){
        
            guard let entity = NSEntityDescription.entity(forEntityName: "WordEntity", in:     context) else { return }
            let taskObject = WordEntity(entity: entity, insertInto: context)
        
            taskObject.setValue(dataWordsRu[0], forKey: "ru")
            taskObject.eng = dataWordsEng[0]
            //insert Entity
            words.insert(taskObject, at: from + 1)    
            //Moving index for quiz.to(is last index of words in this quiz)
            for quiz in indexOfQuiz..<quizzes.count{
                if quiz == indexOfQuiz{
                    quizzes[quiz].to = Int64(quizzes[quiz].to + 1)
                }else{
                    quizzes[quiz].from = Int64(quizzes[quiz].from + 1)
                    quizzes[quiz].to = Int64(quizzes[quiz].to + 1)
                }
            }
        
            do {
                try context.save()
            } catch let error as NSError {
                print(error.localizedDescription)
            }
        
        }

Below I will show you words[index].ru before this function and after. And it works almost well, except ...

Optional("1")
Optional("2")
Optional("3")
Optional("4")
Optional("5")
Optional("6")
Optional("7")
Optional("8")
Optional("9")

This is array of words before inserting.

Optional("1")
Optional("2")
Optional("3")
Optional("4")
Optional("5")
Optional("6")
Optional("qwe")
Optional("7")
Optional("8")
Optional("9")

This is after. I inserted "qwe" word.

But if I restart my project or close and open app on simulator it looks like

Optional("1")
Optional("2")
Optional("3")
Optional("4")
Optional("5")
Optional("6")
Optional("7")
Optional("8")
Optional("9")
Optional("qwe")

I don't know why the position was changed and my question is how can I fix it?

2
  • 2
    CoreData isn’t ordered. You can use sort descriptors to add order/sort an array. You can add an index attribute to the object if you really need an index and sort from that. Commented Feb 8, 2023 at 13:39
  • @loremipsum "You can add an index attribute to the object if you really need an index and sort from that." I thought at the begging of project about it, but it was not necessary. Now it sound like a plan, but maybe somebody knows another solution, if not, I will do that. Thank you for answer. Commented Feb 8, 2023 at 13:55

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.