I'm using CoreData+CloudKit to store data, currently there are two Entities,AEntity and BEntity:
In AEntity, there is an attribute: content, used to store NSAttributedString, its Type is "Transformable", I set its "Transformer" to "AttributedStringValueTransformer" in the right menu of Xcode:
@implementation AttributedStringValueTransformer
+ (Class)transformedValueClass {
return [NSAttributedString class];
}
+ (BOOL)allowsReverseTransformation {
return YES;
}
- (NSData *)transformedValue:(NSAttributedString *)value {
if (!value) {
return nil;
}
if ([value isKindOfClass:[NSData class]]) {
return (NSData *)value;
}
NSData *stringAsData = [NSKeyedArchiver archivedDataWithRootObject:value];
return stringAsData;
}
- (NSAttributedString *)reverseTransformedValue:(NSData *)value {
NSAttributedString *attributedString = [NSKeyedUnarchiver unarchiveObjectWithData:value];
return attributedString;
}
@end
In BEntity, there is an Attribute: images, which is used to store image arrays (NSArray), and its Type is also "Transformable". I set its "Transformer" to "ArrayValueTransformer" in the right menu of Xcode:
@implementation ArrayValueTransformer
+ (Class)transformedValueClass {
return [NSArray class];
}
+ (BOOL)allowsReverseTransformation {
return YES;
}
- (NSData *)transformedValue:(NSAttributedString *)value {
if (!value) {
return nil;
}
if ([value isKindOfClass:[NSData class]]) {
return (NSData *)value;
}
return [NSKeyedArchiver archivedDataWithRootObject:value];;
}
- (NSAttributedString *)reverseTransformedValue:(NSData *)value {
return [NSKeyedUnarchiver unarchiveObjectWithData:value];
}
@end
When calling the loadPersistentStoresWithCompletionHandler: method:
+ (instancetype)containerWithName:(NSString *)name {
NSPersistentCloudKitContainer *persistentContainer = [[NSPersistentCloudKitContainer alloc] initWithName:name];
persistentContainer.viewContext.automaticallyMergesChangesFromParent = YES;
NSPersistentStoreDescription *description = [persistentContainer.persistentStoreDescriptions firstObject];
[description setOption:@(YES) forKey:NSPersistentHistoryTrackingKey];
[description setOption:@(YES) forKey:NSPersistentStoreRemoteChangeNotificationPostOptionKey];
description.shouldInferMappingModelAutomatically = YES;
description.shouldMigrateStoreAutomatically = YES;
persistentContainer.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
[persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) {
if (error != nil) {
NSLog(@"Unresolved error %@, %@", error, error.userInfo);
// abort();
}
}];
return persistentContainer;
}
The error information in the callback of loadPersistentStoresWithCompletionHandler is:
Error Domain=NSCocoaErrorDomain Code=134060 "A Core Data error occurred." UserInfo={NSLocalizedFailureReason=CloudKit integration requires that the value transformers for transformable attributes are available via +[NSValueTransformer valueTransformerForName:], return instances of NSData, and allow reverse transformation: AEntity: content - Claims to return instances of NSAttributedString BEntity: images - Claims to return instances of NSArray}
What is the reason for this? And how should this problem be solved?