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?

0

There are 0 best solutions below