核心数据和 Xcode 11:请切换到使用“NSSecureUnarchiveFromData”或 NSSecureUnarchiveFromDataTransformer 的子类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/58053355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Core Data & Xcode 11: Please switch to using "NSSecureUnarchiveFromData" or a subclass of NSSecureUnarchiveFromDataTransformer
提问by user1107173
Just moved to Xcode 11 and getting the following crash at launch:
刚刚转移到 Xcode 11 并在启动时遇到以下崩溃:
CoreData: fault: One or more models in this application are using transformable properties with transformer names that are either unset, or set to NSKeyedUnarchiveFromDataTransformerName. Please switch to using "NSSecureUnarchiveFromData" or a subclass of NSSecureUnarchiveFromDataTransformer instead. At some point, Core Data will default to using "NSSecureUnarchiveFromData" when nil is specified, and transformable properties containing classes that do not support NSSecureCoding will become unreadable.
CoreData: warning: Property 'color' on Entity 'Group' is using nil or an insecure NSValueTransformer. Please switch to using "NSSecureUnarchiveFromData" or a subclass of NSSecureUnarchiveFromDataTransformer instead.
CoreData:故障:此应用程序中的一个或多个模型正在使用转换器名称未设置或设置为 NSKeyedUnarchiveFromDataTransformerName 的可转换属性。请改用“NSSecureUnarchiveFromData”或 NSSecureUnarchiveFromDataTransformer 的子类。在某些时候,Core Data 将在指定 nil 时默认使用“NSSecureUnarchiveFromData”,并且包含不支持 NSSecureCoding 的类的可转换属性将变得不可读。
CoreData:警告:实体“组”上的属性“颜色”正在使用 nil 或不安全的 NSValueTransformer。请改用“NSSecureUnarchiveFromData”或 NSSecureUnarchiveFromDataTransformer 的子类。
I'm creating an NSPersistentContainer
at launch using the code below:
我正在NSPersistentContainer
使用以下代码在启动时创建一个:
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
}()
Error occurs right after this line is executed:
执行此行后立即发生错误:
let container = NSPersistentContainer(name: "MyApp", managedObjectModel: MyAppModelVersion.current.managedObjectModel())
I also have a property called 'Colorin a
Group` entity that's transformable:
我还有一个名为“Color in a
Group”实体的可转换属性:
@NSManaged public var color: UIColor?
@NSManaged public var hexColorValue: String?
Below is how set the property:
下面是如何设置属性:
public var hexColor: String? {
get {
return self.hexColorValue
}
set {
self.hexColorValue = newValue
if let str = newValue {
self.color = UIColor(hex: str)
}
}
}
This is what the property looks like in Core Data:
这是属性在 Core Data 中的样子:
I am not sure how to recover from this crash. This was working fine with Xcode 10
我不知道如何从这次崩溃中恢复。这在 Xcode 10 上运行良好
采纳答案by vadian
A more feasible solution without transforming anything is to drop the color
attribute, save only the hex string and use a computed property to convert it to and from UIColor
. That's most likely more efficient than the archive dance.
一个更可行的解决方案是删除color
属性,只保存十六进制字符串并使用计算属性将其转换为UIColor
. 这很可能比归档舞蹈更有效率。
@NSManaged public var hexColor: String?
@NSManaged public var color: UIColor?
@NSManaged public var color: UIColor?
public var color: UIColor? {
get { return UIColor(hex: hexColor) }
set { hexColor = newValue.hex } // assuming `hex` is the API to convert UIColor to hex string.
}
回答by Ratneshwar Singh
Setting Transformer property to NSSecureUnarchiveFromDataTransformer solved the warning in my case. For this select the attribute & set its transformer type to NSSecureUnarchiveFromDataTransformer & run again by pressing commond+R.
将 Transformer 属性设置为 NSSecureUnarchiveFromDataTransformer 解决了我的情况下的警告。为此,选择属性并将其转换器类型设置为 NSSecureUnarchiveFromDataTransformer 并按 commond+R 再次运行。
Thanks, Ratneshwar
谢谢,拉特内什瓦尔
回答by Dale
I received the same warning messages when updating to Xcode 11, however in my case they are just warnings, but no crash.
更新到 Xcode 11 时,我收到了相同的警告消息,但在我的情况下,它们只是警告,但没有崩溃。
In order to work out the best solution, I tried creating a stripped down sample app with just a single entity containing a transformable attribute. But it seems that no matter what I tried I could not reproduce the problem. The I copied the model file from my main app to the demo app, and of course that failed.
为了找出最佳解决方案,我尝试创建一个精简的示例应用程序,其中仅包含一个包含可转换属性的实体。但似乎无论我尝试什么,我都无法重现该问题。我将模型文件从我的主应用程序复制到演示应用程序,当然失败了。
So I got to the point where I just had two model files and a simple unit test which does nothing more than open the model and create a persistent store container:
所以我到了我只有两个模型文件和一个简单的单元测试的地步,它只是打开模型并创建一个持久存储容器:
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)
}
The appmodel causes the error messsages but the sample model does not. Even when I stripped the appmodel down to a single Entity it continues to generate the errors.
appmodel 会导致错误消息,但示例模型不会。即使我将 appmodel 剥离为单个实体,它也会继续生成错误。
Comparing the contents of the samplemodel with the appmodel (show package contents in Finder), there is a hidden file called .xccurrentversion in the samplemodel but not in the appmodel. The file looks like this:
比较samplemodel和appmodel的内容(在Finder中显示包内容),samplemodel中有一个名为.xccurrentversion的隐藏文件,appmodel中没有。该文件如下所示:
<?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>
So I created a similar file for the appmodel and put it in the package folder. Surprisingly, that silences the warning messages! Conversely, deleting the .xccurrentversion file from the samplemodel causes the error messages to be generated. This will allow testing of the problem in isolation.
所以我为 appmodel 创建了一个类似的文件并将它放在包文件夹中。令人惊讶的是,这会使警告消息静音!相反,从示例模型中删除 .xccurrentversion 文件会导致生成错误消息。这将允许单独测试问题。
So this may be a short term fix. In the meantime, I need to work out how to migrate to secure coding.
所以这可能是一个短期的修复。与此同时,我需要研究如何迁移到安全编码。
回答by Angel Olvera
For the transformable attribute, you need to set its type in the Custom Class field.
对于可变形属性,您需要在自定义类字段中设置其类型。
For instance, I have a transformable field which stores an array of numbers and its Custom Class is declared as [Int16]
. This is most likely the cause of the crash. And as @vadian mentioned before, you don't need both fields.
例如,我有一个存储数字数组的可转换字段,其自定义类声明为[Int16]
. 这很可能是导致崩溃的原因。正如@vadian 之前提到的,您不需要这两个字段。
After your crash is fixed, you can get rid of the warning by setting the Transformer field to NSSecureUnarchiveFromData
(you simply type this into the field)
修复崩溃后,您可以通过将 Transformer 字段设置为NSSecureUnarchiveFromData
(您只需在该字段中键入)来消除警告