1

I changed my structure and made a migration (I created a new Model), the data is added and displayed, everything works fine, but when I reload the application, the core data is empty, what's the problem?

  static func saveToCoreData(_ words: Words?){

    DispatchQueue.main.async {

        coreDataResult(data: [words?.word, words?.translation], completion: { (result, taskObject, context) in
            do {
                let fetchedEntities = try context.fetch(result) as! [Favorite]
                if let _ = fetchedEntities.first?.word {
                    print("the element already have in coreData")
                } else {

                    taskObject?.setValue(words?.word, forKey: "word")
                    taskObject?.setValue(words?.translation, forKey: "translation")
                    taskObject?.setValue(words?.descript, forKey: "wordDesc")
                    taskObject?.setValue(words?.translDesc, forKey: "translDesc")

                    do {
                        try context.save()
                    } catch {
                        print(error)
                    }
                }
            } catch {}
        })

    }

}

static func coreDataResult(data: [[String?]?]?, completion: @escaping (NSFetchRequest<NSFetchRequestResult>, Favorite?, NSManagedObjectContext) -> ()){

    guard let w = data?.first, let word = w, let t = data?.last, let transl = t else { return }

    DispatchQueue.main.async {
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let context = appDelegate.persistentContainer.viewContext
        guard let entity = NSEntityDescription.entity(forEntityName: "Favorite", in: context) else { return }
        guard let taskObject = NSManagedObject(entity: entity, insertInto: context) as? Favorite else { return }

        let predicate = NSPredicate(format: "word == %@", word)
        let predicate2 = NSPredicate(format: "translation == %@", transl)
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Favorite")
        let andPredicate = NSCompoundPredicate(type: .and, subpredicates: [predicate, predicate2])

        fetchRequest.predicate = andPredicate
        completion(fetchRequest, taskObject, context)
    }

}

old attributes old Attributes

new Attributes new Attributes

new Model
new Model

Vasya2014
  • 203
  • 1
  • 5
  • 25
  • 2
    You changed the data type of the attribute "word" from String to Transformable. Lightweight migration cannot do this automatically. You need to do that manually. – MartinM Mar 13 '19 at 14:49
  • You would need to write a migration policy by the looks of it – Sean Lintern Mar 13 '19 at 14:55

1 Answers1

1

I decided it

this answer helped me - https://stackoverflow.com/a/40662940/8070211

  1. create Model (command + n -> Mapping Model -> select old model -> select new model -> add Name and create)enter image description here
  2. create subClass NSEntityMigrationPolicy

    class FavoriteEntityMigrationPolicy: NSEntityMigrationPolicy {
    
       @objc func typeFor(word:String) -> [String] {
           return [word]
       }
    
    }
    
  3. select Model -> select entity -> add subClass to custom Policyenter image description here

  4. select Model -> select entity -> select value expression -> add FUNCTION($entityPolicy, "typeForWord:" , $source.word) enter image description here

  5. it is ready
Vasya2014
  • 203
  • 1
  • 5
  • 25