2010-02-21 6 views

Respuesta

16

Lo que probablemente desee es un atributo transformable. Dele a la sección "Non-standard Persistent Attributes" en la Guía de programación de datos básicos otra lectura. Un atributo transformable es, debajo de las carátulas, un atributo de datos binarios, pero Core Data usará automáticamente el NSValueTransformer de su especificación para serializar y deserializar el valor del atributo lógico por usted. Para valores que cumplen con NSCoding, el NSKeyedUnarchiveFromDataTransformerName (que es el transformador predeterminado) hará el truco.

Por supuesto, Core Data no puede indexar o, para un SQLite backend, consulta contra este valor transformable.

20

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.

+1

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

+13

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

3

¿Es posible almacenar el UIColor como un String como un HEX (FFFFFF u otros colores seguros para web) y luego cuando llegue a leer el color, convierta el hilo en un formato que UIColor pueda entender?

3

Después de especificar el atributo de color como transformable con el nombre ColorToDataTransformer. Podemos generar simplemente MangatedObjectSubclass y escribir código de transformador en su interior

//SampleEntity.h

#import <Foundation/Foundation.h> 
#import <CoreData/CoreData.h> 
@interface SampleEntity : NSManagedObject 
@property (nonatomic, retain) UIColor *color; 
@end 

@interface ColorToDataTransformer : NSValueTransformer 
@end 

//SampleEntity.m

#import "SampleEntity.h" 

@implementation SampleEntity 

@dynamic color; 

@end 

@implementation ColorToDataTransformer 

+ (BOOL)allowsReverseTransformation { 
    return YES; 
} 

+ (Class)transformedValueClass { 
    return [NSData class]; 
} 


- (id)transformedValue:(id)value { 
    UIColor *color = (UIColor *)value; 
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:color]; 
    return data; 
} 

- (id)reverseTransformedValue:(id)value { 
    NSData *data = (NSData *)value; 
    UIColor *color = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 
    return color; 
} 

@end 
Cuestiones relacionadas