Voy a parafrasear la respuesta definitivos en que encontré en Más iPhone 3 Desarrollo por Dave Mark y Jeff LeMarche:
Por lo general, nos gustaría poder salir de la clase transformador del atributo transformable como predeterminado, NSKeyedUnarchiveFromData y listo, pero en este caso no podemos porque UIColor
no se ajusta a NSCoding
y no se puede archivar utilizando NSKeyedArchiver
. Tenemos que escribir manualmente un transformador de valor para manejar la transformación.
Agregue un atributo a su entidad y llame al atributo "color", o el nombre que desee. Establezca su tipo en Transformable. Establezca su "Nombre del transformador de valor" en UIColorRGBValueTransformer. Tenga en cuenta que el editor de modelos de datos no valida el Value Transformer Name: para asegurarse de que sea una clase válida, por lo que debe escribir con cuidado.
Cree un archivo nuevo, una subclase de NSObject
y llámelo UIColorRGBValueTransformer.m.
Haga clic en UIColorRGBValueTransformer.h y cambie la superclase de NSObject a NSValueTransformer. Además, cambie #import <Foundation/Foundation.h>
a #import <UIKit/UIKit.h>
, ya que UIColor
es parte de UIKit
, no Foundation
.
Ahora en UIColorRGBValueTransformer.m, tenemos que aplicar cuatro métodos que permiten a nuestra clase de valor transformador para convertir las instancias de UIColor
a NSData
y viceversa. Incluir el siguiente código en UIColorRGBValueTransformer.m:
#import "UIColorRGBValueTransformer.h"
@implementation UIColorRGBValueTransformer
// Here we override the method that returns the class of objects that this transformer can convert.
+ (Class)transformedValueClass {
return [NSData class];
}
// Here we indicate that our converter supports two-way conversions.
// That is, we need to convert UICOLOR to an instance of NSData and back from an instance of NSData to an instance of UIColor.
// Otherwise, we wouldn't be able to beth save and retrieve values from the persistent store.
+ (BOOL)allowsReversTransformation {
return YES;
}
// Takes a UIColor, returns an NSData
- (id)transfomedValue:(id)value {
UIColor *color = value;
const CGFloat *components = CGColorGetComponents(color.CGColor);
NSString *colorAsString = [NSString stringWithFormat:@"%f,%f,%f,%f", components[0], components[1], components[2], components[3]];
return [colorAsString dataUsingEncoding:NSUTF8StringEncoding];
}
// Takes an NSData, returns a UIColor
- (id)reverseTransformedValue:(id)value {
NSString *colorAsString = [[[NSString alloc] initWithData:value encoding:NSUTF8StringEncoding] autorelease];
NSArray *components = [colorAsString componentsSeparatedByString:@","];
CGFloat r = [[components objectAtIndex:0] floatValue];
CGFloat g = [[components objectAtIndex:1] floatValue];
CGFloat b = [[components objectAtIndex:2] floatValue];
CGFloat a = [[components objectAtIndex:3] floatValue];
return [UIColor colorWithRed:r green:g blue:b alpha:a];
}
@end
Ahora en otro archivo, se puede incluir una línea de código como:
[self.managedObject setValue:color forKey:self.keyPath];
sin necesidad de importar UIColorRGBValueTransformer.h en el archivo.
Esta respuesta es increíble, nunca se habría dado cuenta de esto . Una pequeña edición, "allowsReversTransformation" y "transfomedValue" están mal escritas, pero la reparación solo representa 2 de las 6 letras requeridas por ediciones. – rob5408
Aunque esto sí funcionó, se debe tener en cuenta que UIColor realmente se ajusta a NSCoding (al contrario de lo que se menciona arriba) y no se debe requerir un transformador especial. – rob5408