web-dev-qa-db-ja.com

CoreDataクラッシュエラーXcode 11 Beta、IOS 13 Beta

電話でXcode11ベータからアプリケーションをビルドしようとしていますIOS 13ベータ。アプリケーションのロード中にクラッシュしました。

2019-07-22 13:58:12.910460 + 0300 GoodWine [3738:792501] [エラー]障害:このアプリケーションの1つ以上のモデルが、トランスフォーマー名が設定されていないか、NSKeyedUnarchiveFromDataTransformerNameに設定されている変換可能なプロパティを使用しています。代わりに「NSSecureUnarchiveFromData」またはNSSecureUnarchiveFromDataTransformerのサブクラスを使用するように切り替えてください。 nilを指定すると、ある時点でCore Dataはデフォルトで「NSSecureUnarchiveFromData」を使用するようになり、NSSecureCodingをサポートしないクラスを含む変換可能なプロパティが読み取れなくなります。

CoreData:障害:このアプリケーションの1つ以上のモデルが、未設定またはNSKeyedUnarchiveFromDataTransformerNameに設定されているトランスフォーマー名を持つ変換可能なプロパティを使用しています。代わりに「NSSecureUnarchiveFromData」またはNSSecureUnarchiveFromDataTransformerのサブクラスを使用するように切り替えてください。 nilを指定すると、ある時点でCore Dataはデフォルトで「NSSecureUnarchiveFromData」を使用するようになり、NSSecureCodingをサポートしないクラスを含む変換可能なプロパティが読み取れなくなります。

2019-07-22 13:58:12.910595 + 0300 GoodWine [3738:792501] [エラー] CoreData:このアプリケーションの1つ以上のモデルは、トランスフォーマー名が設定されていないか、NSKeyedUnarchiveFromDataTransformerNameに設定されている変換可能なプロパティを使用しています。代わりに「NSSecureUnarchiveFromData」またはNSSecureUnarchiveFromDataTransformerのサブクラスを使用するように切り替えてください。 nilを指定すると、ある時点でCore Dataはデフォルトで「NSSecureUnarchiveFromData」を使用するようになり、NSSecureCodingをサポートしないクラスを含む変換可能なプロパティが読み取れなくなります。

CoreData:警告:エンティティ 'SFMCKeyValueEntity'のプロパティ 'value'はnilまたは安全でないNSValueTransformerを使用しています。代わりに「NSSecureUnarchiveFromData」またはNSSecureUnarchiveFromDataTransformerのサブクラスを使用するように切り替えてください。

私はこの解決策を見つけました。エラーはなくなり、動作するようです。私はテストを続けます。

すべての変換可能な属性について、データモデルインスペクターパネルで「Transformer」を「NSSecureUnarchiveFromData」に設定しました。 (説明のための画像)

編集:

数日テストした後、以前のソリューションに何かを追加します。

以前の解決策は、変更後にアプリケーションが削除された場合に機能します。そうでない場合、データモデルは認識されず、ゼロから作成され、すべての履歴情報が失われます(本番環境ではこれは許容されません!!!)。

私が採用した最後の解決策は、これらの変更を新しいモデルに追加し(これに従って link )、移行を実装することです(常にリンクで説明されています)。

この場合、警告は更新後に一度だけ表示され、その後表示されなくなります。

25
SirOz

私の解決策は、互換性の問題を回避するために、古いデフォルトのトランスフォーマーのままにすることでした。デフォルトの(nil)トランスフォーマーは最終的にNSSecureUnarchiveFromDataに置き換えられるため、問題が発生する可能性があります。以前に永続化された値が適切にデコードされるかどうかはわかりません(デフォルトのトランスフォーマーによってエンコードされましたが、更新後にNSSecureUnarchiveFromDataTransformerによってデコードされます)。私は、箱から出してすぐにNSCodingに準拠するNSDictionary、NSArray、NSSetファウンデーションタイプのフィールドに明示的なデフォルトトランスフォーマーを実装しました。

@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)
    }
}

NSCodingに準拠する特別なデータ型について、特定のトランスフォーマーを次のように実装しました。

@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)
    }
}

その後、これらのトランスフォーマーを変換可能なフィールドに設定し、最も安全な方法を明示的に選択しました。ソリューションの長所:データの移行に煩わされる必要はありません。明示的なトランスフォーマーを実装し、それらを既存のデータモデルバージョンに設定するだけです。

2
kas-kad