In my Core Data schema, I have a 'transformable' attribute in an entity, which is using a NSValueTransformer
, the purpose of which is to convert a UIImage into NSData with some compression. 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 (link) and figured I'd need to change the NSValueTransformer
to using NSSecureUnarchiveFromDataTransformer
... but after making the changes (as best as I understood them from the article) I can't get it to work, and now the app crashes when the attribute is accessed.
This is the existing NSValueTransformer
:
@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.4);
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:
+ (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"];
}
Then, before the Core Data persistent store is accessed, I 'register' the transformer:
[ImageToDataTransformer setValueTransformer: [[ImageToDataTransformer alloc] init] forName:@"ImageToDataTransformerName"];
Now the warning is gone, but 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.