web-dev-qa-db-fra.com

CoreData: annotation: échec du chargement du modèle optimisé sur le chemin (Xcode 11 -> iOS 12)

Lorsque je crée et exécute un projet Core Data (créé avec Xcode 10) à l'aide de Xcode 11 (beta 3) sur un appareil iOS 12, j'obtiens l'avertissement:

CoreData: annotation: impossible de charger le modèle optimisé dans le chemin '/var/containers/Bundle/Application/7908B3F7-66BC-4931-A578-6A740CBFB37D/TestOMO.app/TestOMO.momd/TestOMO.omo'

Il n'y a aucun avertissement si

  • Je le construis et l'exécute à l'aide de Xcode 10 sur un appareil iOS 12
  • Je le construis et l'exécute à l'aide de Xcode 11 sur un appareil iOS 13

Mon application semble fonctionner correctement et il n'y a pas de plantage, je ne sais donc pas comment prendre cet avertissement au sérieux. Néanmoins, je préférerais sûrement m'en débarrasser.

Il existe de nombreux messages liés à cette annotation Core Data, mais la plupart sont liés à Google Maps ou sont sans réponse.

J'ai créé un nouveau projet pour éliminer les autres causes du problème lié à mon propre projet et pour le rendre facile à reproduire comme suit:

  1. Créer un nouveau projet à l'aide de Xcode 10 (application à vue unique, utiliser les données de base)
  2. Dans AppDelegate.Swift, ajoutez print ("psc = (persistentContainer)") à l'application func (_, didFinishLaunchingWithOptions :) (juste pour forcer l'initialisation var paresseuse)
  3. Créez et exécutez sur un appareil iOS12: aucun problème
  4. Ouvrez le même projet dans Xcode 11, générez et exécutez sur un appareil iOS13: aucun problème
  5. Ajoutez Xcode 11, construisez et exécutez sur un appareil iOS12: vous obtiendrez l'avertissement cité ci-dessus

Le nettoyage du dossier de génération ou la suppression des données dérivées est inutile.

9
Lobo

J'ai pu résoudre le problème grâce à l'allusion dans le commentaire de @ ChaitanyaKhurana ci-dessus.

Voici le code Swift que j'ai implémenté, remplaçant la ligne unique d'origine

let container = NSPersistentContainer(name: "ModelName")

Une partie du code est nécessaire pour récupérer la chaîne de version du modèle (à partir du fichier .plist situé dans le package .momd) afin d'éviter d'avoir à mettre à jour le code à chaque nouvelle version du modèle.

Veuillez également noter que le code nouveau/alternatif s'exécute uniquement sur les versions iOS antérieures à 13.0 car il n'y a pas de problème sur iOS 13.

let modelName = "ModelName"

var container: NSPersistentContainer!

if #available(iOS 13.0, *) {
    container = NSPersistentContainer(name: modelName)
} else {
    var modelURL = Bundle(for: type(of: self)).url(forResource: modelName, withExtension: "momd")!
    let versionInfoURL = modelURL.appendingPathComponent("VersionInfo.plist")
    if let versionInfoNSDictionary = NSDictionary(contentsOf: versionInfoURL),
        let version = versionInfoNSDictionary.object(forKey: "NSManagedObjectModel_CurrentVersionName") as? String {
        modelURL.appendPathComponent("\(version).mom")
        let managedObjectModel = NSManagedObjectModel(contentsOf: modelURL)
        container = NSPersistentContainer(name: modelName, managedObjectModel: managedObjectModel!)
    } else {
        //fall back solution; runs fine despite "Failed to load optimized model" warning
        container = NSPersistentContainer(name: modelName)
    }
}
2
Lobo