iPhone iOS cómo serializar / save UIColor en JSON File?

Cuando necesito save un color para los datos centrales, simplemente utilizo NSKeyedArchiever y luego desfile cuando necesito cargar la entidad. Sin embargo, cuando bash serializar la entidad de datos del núcleo, el process falla porque no sabe cómo convertir los NSData del archivador con key en una cadena.

¿Cuál es la mejor manera de convertir un UIColor en una representación de cadena para el envío dentro del file JSON? Una solución es almacenar los valores r, g, b, a como flotantes. Una solución es savelo como una cadena hexadecimal. Ambos parecen complicar el process de restauración del color.

Me estoy perdiendo de algo ? ¿Hay una manera más fácil de serializar un UIColor dentro de JSON?

Qué hay sobre eso:

NSDictionary *colorData = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:100.f], @"Red", [NSNumber numberWithFloat:24.f], @"Green", [NSNumber numberWithFloat:23.f], @"Blue", [NSNumber numberWithFloat:1.f], @"Alpha", nil]; NSDictionary *color = [NSDictionary dictionaryWithObject:colorData forKey:@"Color"]; 

El resultado es algo como:

 {"Color":{"Green":24,"Alpha":1,"Blue":23,"Red":100}} 

Puede hacer fácilmente un método que tome UIColor como argumento y devuelva un NSDictionary, que se puede serializar directamente. El process inverso es el mismo.

Dado que no hay un estándar definido para poner un UIColor (y mucho less un "color" genérico) en JSON, tendrá que armar el suyo propio.

Yo sugeriría que el mejor método sería tener una categoría en UIColor que le brinde el código hexadecimal estándar para el color en el espacio de color RGB y que también tome ese código hexadecimal y escupe s UIColor . Luego transmite ese código hexadecimal en el JSON.

Sé que puede parecer una exageración, pero es, de lejos, la solución más portátil y compacta.

Se puede encontrar un ejemplo del método hex a UIColor en mi categoría UIColor de UIColor . Una UIColor similar que vaya de UIColor a valor hexadecimal no sería demasiado difícil de escribir, pero tenga en count primero que tener que getla en el espacio de color RGBA.

Esto depende de la libertad de tener un formatting "privado" para los colors. Algunos colors no reactjsn bien cuando se les solicita RGBA (por lo tanto, los methods get... devuelven un BOOL , no siempre tienen éxito), por lo que esta implementación incluye el tipo de color y los valores.

 @implementation UIColor (JSON) - (NSString *)json_stringValue { CGFloat r, g, b, a, h, s, w; if ([self getRed:&r green:&g blue:&b alpha:&a]) return [NSString stringWithFormat:@"rgba:%f,%f,%f,%f", r,g,b,a]; else if ([self getHue:&h saturation:&s brightness:&b alpha:&a]) return [NSString stringWithFormat:@"hsba:%f,%f,%f,%f", h,s,b,a]; else if ([self getWhite:&w alpha:&a]) return [NSString stringWithFormat:@"wa:%f,%f", w, a]; NSLog(@"WARNING: unable to serialize color %@", self); return nil; } @end @implementation NSString (JSON) - (UIColor *)json_color { NSArray *comps = [self componentsSeparatedByString:@":"]; NSArray *colors = [comps[1] componentsSeparatedByString:@","]; NSUInteger count = colors.count; CGFloat values[4] = {0,0,0,0}; for (NSUInteger i = 0; i < count; i++) values[i] = [colors[i] floatValue]; if ([comps[0] isEqualToString:@"rgba"]) return [UIColor colorWithRed:values[0] green:values[1] blue:values[2] alpha:values[3]]; else if ([comps[0] isEqualToString:@"hsba"]) return [UIColor colorWithHue:values[0] saturation:values[1] brightness:values[2] alpha:values[3]]; else if ([comps[0] isEqualToString:@"wa"]) return [UIColor colorWithWhite:values[0] alpha:values[1]]; NSLog(@"WARNING: unable to deserialize color %@", self); return nil; } @end 

Combinando los resultados de las dos respuestas en lo siguiente:

Ahorrar:

 #import "UIColor-HSVAdditions.h" #import "JSONKit.h" UIColor* color = textView.textColor; NSDictionary *colorData = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:color.hue], @"Hue", [NSNumber numberWithFloat:color.saturation], @"Saturation", [NSNumber numberWithFloat:color.brightness], @"Brightness", [NSNumber numberWithFloat:color.alpha], @"Alpha", nil]; NSString* jsonString = [colorData JSONString]; 

Cargar:

  NSDictionary* dictionary = [coreDataEntity.fontColor objectFromJSONString]; NSNumber* hue =[dictionary objectForKey:kHueKey]; NSNumber* saturation =[dictionary objectForKey:kSaturationKey]; NSNumber* brightness =[dictionary objectForKey:kBrightnessKey]; NSNumber* alpha =[dictionary objectForKey:kAlphaKey]; UIColor* color = [UIColor colorWithHue:hue.floatValue saturation:saturation.floatValue brightness:brightness.floatValue alpha:alpha.floatValue]; textView.textColor = color; 

La solución que encontré es crear CIColor desde UIColor y luego volver a convertir:

Convertir a cadena:

 CIColor(color: UIColor.blue).stringRepresentation 

Convertir a color:

 UIColor(ciColor: CIColor(string: databaseColorString))