Hi,
In my Core Data schema, I have a 'transformable' attribute in an entity, which is using a custom NSValueTransformer, the purpose of which is to convert a UIImage into NSData with some compression (basically to save a small thumbnail from the image). From this attribute, I had recently started getting these warnings about using NSKeyedUnarchiveFromData:
So I read about this, and figured I'd need to change the NSValueTransformer to using NSSecureUnarchiveFromDataTransformer ... but after making the changes (as best as I understood them) I can't get it to work, and now the app crashes when the attribute is accessed.
This is the existing NSValueTransformer that I was using:
So I changed it to subclass from NSSecureUnarchiveFromDataTransformer instead, and added the following to the implementation:
Before the Core Data persistent store is accessed, I 'register' the transformer:
Now the app crashes when the image is read:
If I change the transformer back to NSValueTransformer, it works fine. So I'm not sure if I'm missing something from the implementation, or I have misunderstood the premise of 'NSSecureUnarchiveFromDataTransformer'. Would love to know what I can do to fix this.
In my Core Data schema, I have a 'transformable' attribute in an entity, which is using a custom NSValueTransformer, the purpose of which is to convert a UIImage into NSData with some compression (basically to save a small thumbnail from the image). From this attribute, I had recently started getting these warnings about using NSKeyedUnarchiveFromData:
'NSKeyedUnarchiveFromData' should not be used to for un-archiving and will be removed in a future release
So I read about this, and figured I'd need to change the NSValueTransformer to using NSSecureUnarchiveFromDataTransformer ... but after making the changes (as best as I understood them) I can't get it to work, and now the app crashes when the attribute is accessed.
This is the existing NSValueTransformer that I was using:
Code Block @interface ImageToDataTransformer : NSValueTransformer { } @implementation ImageToDataTransformer + (BOOL)allowsReverseTransformation { return YES; } + (Class)transformedValueClass { return [NSData class]; } - (id)transformedValue:(id)value { // for our smaller views this uses much less data and makes for faster syncing NSData *compressedData = UIImageJPEGRepresentation(value, 0.2); return compressedData; } - (id)reverseTransformedValue:(id)value { UIImage *uiImage = [[UIImage alloc] initWithData:value]; NSData *data = (NSData *) value; //NSLog(@"reverseTransformedValue: image size: %@", [NSByteCountFormatter stringFromByteCount:data.length countStyle:NSByteCountFormatterCountStyleFile]); return uiImage; }
So I changed it to subclass from NSSecureUnarchiveFromDataTransformer instead, and added the following to the implementation:
Code Block + (NSArray<Class> *)allowedTopLevelClasses { return @[[ImageToDataTransformer class]]; } + (void)setValueTransformer:(nullable NSValueTransformer *)transformer forName:(NSValueTransformerName)name { NSLog(@"ImageToDataTransfer: calling setValueTransformer"); [NSValueTransformer setValueTransformer:transformer forName:name]; } + (NSArray<NSValueTransformerName> *)valueTransformerNames { return @[@"ImageToDataTransformerName"]; }
Before the Core Data persistent store is accessed, I 'register' the transformer:
Code Block [ImageToDataTransformer setValueTransformer: [[ImageToDataTransformer alloc] init] forName:@"ImageToDataTransformerName"];
Now the app crashes when the image is read:
[__NSCFData _rasterizedImage]: unrecognized selector sent to instance 0x7ff53c108800
If I change the transformer back to NSValueTransformer, it works fine. So I'm not sure if I'm missing something from the implementation, or I have misunderstood the premise of 'NSSecureUnarchiveFromDataTransformer'. Would love to know what I can do to fix this.