web-dev-qa-db-fra.com

Erreur de crash CoreData Xcode 11 Beta, IOS 13 Beta

Im essayant de construire mon application à partir de Xcode11 beta sur le téléphone IOS 13 Beta. J'ai un crash lors du chargement de l'application.

2019-07-22 13: 58: 12.910460 + 0300 GoodWine [3738: 792501] [error] 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: 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.

2019-07-22 13: 58: 12.910595 + 0300 GoodWine [3738: 792501] [erreur] CoreData: 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é 'value' sur l'entité 'SFMCKeyValueEntity' utilise nil ou un NSValueTransformer non sécurisé. Veuillez basculer vers l'utilisation de "NSSecureUnarchiveFromData" ou d'une sous-classe de NSSecureUnarchiveFromDataTransformer à la place.

J'ai trouvé cette solution. Les erreurs ont disparu et cela semble fonctionner. Je continue de tester.

Pour tous les attributs transformables, j'ai défini "Transformer" sur "NSSecureUnarchiveFromData" dans le panneau Inspecteur de modèle de données. (Image pour clarification)

ÉDITER:

Après quelques jours de test, j'ajoute quelque chose à ma solution précédente.

La solution précédente fonctionne si, après les modifications, l'application est supprimée. Sinon, le modèle de données n'est pas reconnu et est créé à partir de zéro, perdant toutes les informations historiques (et en production, cela n'est pas acceptable !!!).

La solution finale que j'ai adoptée était d'ajouter ces changements à un nouveau modèle (en suivant ce lien ) et en implémentant la migration (toujours décrite dans le lien).

Dans ce cas, l'avertissement n'apparaît qu'une seule fois après la mise à jour, puis disparaît.

25
SirOz

Ma solution était de rester avec les anciens transformateurs par défaut afin d'éviter tout problème de compatibilité. Les problèmes peuvent survenir puisque les transformateurs par défaut (nil) seront éventuellement remplacés par NSSecureUnarchiveFromData, je ne sais pas si les valeurs précédemment persistantes seront décodées correctement (elles ont été codées par le transformateur par défaut mais après la mise à jour, elles seront décodées par NSSecureUnarchiveFromDataTransformer). J'ai implémenté un transformateur par défaut explicite pour les champs de types de fondation NSDictionary, NSArray, NSSet qui sont conformes au NSCoding prêt à l'emploi:

@objc(DefaultTransformer)
class DefaultTransformer: ValueTransformer {
    override class func transformedValueClass() -> AnyClass {
        return NSData.self
    }

    override open func reverseTransformedValue(_ value: Any?) -> Any? {
        guard let value = value as? Data else {
            return nil
        }
        return NSKeyedUnarchiver.unarchiveObject(with: value)
    }

    override class func allowsReverseTransformation() -> Bool {
        return true
    }

    override func transformedValue(_ value: Any?) -> Any? {
        guard let value = value else {
            return nil
        }
        return NSKeyedArchiver.archivedData(withRootObject: value)
    }
}

Pour mes types de données spéciaux conformes au NSCoding, j'ai implémenté des transformateurs particuliers comme suit:

@objc(EmailTransformer)
class EmailTransformer: ValueTransformer {
    override class func transformedValueClass() -> AnyClass {
        return NSData.self
    }

    override open func reverseTransformedValue(_ value: Any?) -> Any? {
        guard let value = value as? Data else {
            return nil
        }
        return NSKeyedUnarchiver.unarchiveObject(with: value)
    }

    override class func allowsReverseTransformation() -> Bool {
        return true
    }

    override func transformedValue(_ value: Any?) -> Any? {
        guard let value = value as? [Email] else {
            return nil
        }
        return NSKeyedArchiver.archivedData(withRootObject: value)
    }
}

Après cela, j'ai défini ces transformateurs pour les champs transformables, j'ai donc opté explicitement pour la manière la plus sûre. Avantages de la solution: vous n'avez pas à vous soucier de la migration des données, implémentez simplement des transformateurs explicites et définissez-les sur n'importe quelle version de modèle de données que vous possédez déjà.

2
kas-kad