I have a class conforming to NSManagedObject with three @NSManaged properties:
They have the following types Core Data Type : Swift Type:
String : StringBoolean : BoolTransformable : [NSColor]
With the following class:
public class MyClass: NSManagedObject {
@NSManaged private(set) var text: String
@NSManaged private(set) var myBool: Bool
@NSManaged private(set) var colors: [NSColor]
// ... other code ...
}
Currently I get the following warning:
CoreData: 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.
The error is raised in this part of the code:
func fetchPalettes() -> [MyClass] {
let fetchRequest = NSFetchRequest<MyClass>.init(entityName: "MyClass")
let result = try? self.moc.fetch(fetchRequest) // <<-------
return result ?? []
}
Obviously this problem is not a new one and I have looked at a few resources like these two.
But as far as I understand all the resources I stumbled upon, a class is required if an attribute wants to securely conform to the Core Data Transformable type.
If I understand it correctly one can do two things:
- Make the class conform to
NSSecureCodingby callingdecodeObject(of: Class, for: Key)during initialisation ininit?(coder: NSCoder)and implementingencode(with coder: NSCoder) - or implement an
NSSecureUnarchiveFromDataTransformer, which needs to overrideallowedTopLevelClasses: [AnyClass]in order to be called and thus also requires the object to be a class (returningArray<NSColor>.selfgives an error in Swift)
I want to prevent wrapping the NSColor property in a class because it would have other repercussions and I would consider it bloated code. I have tried the later of the two options listed above.
Shouldn't it be possible to use an array of NSSecureCoding conforming elements? Am I not seeing a solution? Is there any way to encode/decode [NSColor] securely?
(I have seen this and I don't think its related)
———————— EDIT ————————————————————
I will now kind of answer my own question, but since I am not 100% sure if this it is correct I will do this in the question.
I have tried using other types like [NSString] and [String] with core data in a different project and that seems to work flawlessly. I have also tried using NSColorList instead of [NSColor] but doing so I ran into the same kind of problem. It doesn't even work with NSColor. Even tho both (NSColor and NSColorList) are said to conform to NSSecureCoding (according to their documentation) both types seem not to implement this protocol correctly.
To answer my question:
Generally it seems that using an array of a type conforming to NSSecureCoding like [String] or [NSString] seems to work out of the box. (The properties needs to be of the core data type Transformable and Transformer needs to be set to NSSecureUnarchiveFromData in the Attribute Inspector for the given attribute)
Just in my personal case of NSColor, [NSColor] or NSColorList do not seem to conform to NSSecureCoding correctly. Correct me if I am wrong!
I have solved this by using [String] instead of [NSColor] as the @NSManaged property. I therefore save a hex representation string instead of the object. I use a computed var in order to make [NSColor] public.
Hope this helps someone at some point.