web-dev-qa-db-fra.com

Core Data & Xcode 11: veuillez passer à l'utilisation de "NSSecureUnarchiveFromData" ou d'une sous-classe de NSSecureUnarchiveFromDataTransformer

Nous venons de passer à Xcode 11 et d'obtenir le crash suivant au lancement:

CoreData: fault: un ou plusieurs modèles de cette application utilisent des propriétés transformables avec des noms de transformateur non définis ou définis sur NSKeyedUnarchiveFromDataTransformerName. Veuillez basculer vers l'utilisation de "NSSecureUnarchiveFromData" ou d'une sous-classe de NSSecureUnarchiveFromDataTransformer à la place. À un certain point, Core Data utilisera par défaut "NSSecureUnarchiveFromData" lorsque nil est spécifié et les propriétés transformables contenant des classes qui ne prennent pas en charge NSSecureCoding deviendront illisibles.

CoreData: avertissement: la propriété 'color' sur l'entité 'Group' utilise nil ou un NSValueTransformer non sécurisé. Veuillez basculer vers l'utilisation de "NSSecureUnarchiveFromData" ou d'une sous-classe de NSSecureUnarchiveFromDataTransformer à la place.

Je crée un NSPersistentContainer au lancement en utilisant le code ci-dessous:

private let container: NSPersistentContainer = {
    let container = NSPersistentContainer(name: "MyApp", managedObjectModel: MyAppModelVersion.current.managedObjectModel())
    let storeDescription = NSPersistentStoreDescription(url: getStoreURLWithUserName())
    storeDescription.shouldMigrateStoreAutomatically = true
    storeDescription.shouldInferMappingModelAutomatically = true
    container.persistentStoreDescriptions = [storeDescription]
    return container
}()

Une erreur se produit juste après l'exécution de cette ligne:

let container = NSPersistentContainer(name: "MyApp", managedObjectModel: MyAppModelVersion.current.managedObjectModel())

J'ai également une propriété appelée entité 'Color in a Group` qui est transformable:

@NSManaged public var color: UIColor?
@NSManaged public var hexColorValue: String?

Voici comment définir la propriété:

public var hexColor: String? {
    get {
        return self.hexColorValue
    }
    set {
        self.hexColorValue = newValue
        if let str = newValue {
            self.color = UIColor(hex: str)
        }
    }
}

Voici à quoi ressemble la propriété dans Core Data:

enter image description here

Je ne sais pas comment récupérer de cet accident. Cela fonctionnait bien avec Xcode 10

9
user1107173

J'ai reçu les mêmes messages d'avertissement lors de la mise à jour vers Xcode 11, mais dans mon cas, ce ne sont que des avertissements, mais pas de plantage.

Afin de trouver la meilleure solution, j'ai essayé de créer un exemple d'application dépouillée avec une seule entité contenant un attribut transformable. Mais il semble que peu importe ce que j'ai essayé, je n'ai pas pu reproduire le problème. J'ai copié le fichier modèle de mon application principale vers l'application de démonstration, et bien sûr, cela a échoué.

Je suis donc arrivé au point où je venais d'avoir deux fichiers de modèle et un simple test unitaire qui ne fait rien de plus qu'ouvrir le modèle et créer un conteneur de stockage persistant:

 func testDataModels() {
     openDataModel(named: "samplemodel")
     openDataModel(named: "appmodel")
 }

 func openDataModel(named name: String) {
    print("Opening \(name)")
     guard let url = findFile(forResource: name, withExtension: "momd"),
           let managedObjectModel = NSManagedObjectModel(contentsOf: url)
     else {
         XCTFail("Unable to find \(name) data model")
         return
     }
    print(url)
     _ = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel)
 }

 func findFile(forResource name: String, withExtension ext: String) -> URL? {
     if let url = Bundle(for: type(of: self)).url(forResource: name, withExtension: ext) {
         return url
     }
     return Bundle.main.url(forResource: name, withExtension: ext)
 }

Le modèle d'application provoque les messages d'erreur, mais pas l'exemple de modèle. Même lorsque j'ai supprimé le modèle d'application en une seule entité, il continue de générer des erreurs.

En comparant le contenu du modèle d'échantillonnage avec le modèle d'application (afficher le contenu du package dans le Finder), il existe un fichier caché appelé .xccurrentversion dans le modèle d'échantillonnage mais pas dans le modèle d'application. Le fichier ressemble à ceci:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.Apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>_XCCurrentVersionName</key>
    <string>samplemodel.xcdatamodel</string>
</dict>
</plist>

J'ai donc créé un fichier similaire pour le modèle d'application et l'ai mis dans le dossier du package. Étonnamment, cela fait taire les messages d'avertissement! Inversement, la suppression du fichier .xccurrentversion du modèle d'échantillonnage entraîne la génération des messages d'erreur. Cela permettra de tester le problème isolément.

Cela peut donc être une solution à court terme. En attendant, j'ai besoin de savoir comment migrer vers un codage sécurisé.

1
Dale

La définition de la propriété Transformer sur NSSecureUnarchiveFromDataTransformer a résolu l'avertissement dans mon cas. Pour cela, sélectionnez l'attribut et définissez son type de transformateur sur NSSecureUnarchiveFromDataTransformer et exécutez à nouveau en appuyant sur commond + R.

Merci, Ratneshwar

1
Ratneshwar Singh

Pour l'attribut transformable, vous devez définir son type dans le champ Classe personnalisée.

Par exemple, j'ai un champ transformable qui stocke un tableau de nombres et sa classe personnalisée est déclarée comme [Int16]. C'est probablement la cause de l'accident. Et comme @vadian l'a mentionné précédemment, vous n'avez pas besoin des deux champs.

Une fois votre crash corrigé, vous pouvez vous débarrasser de l'avertissement en définissant le champ Transformer sur NSSecureUnarchiveFromData (il vous suffit de le saisir dans le champ)

0
Angel Olvera