When I need to save a color to core data, I simply use NSKeyedArchiever and then unarchieve color when I need to load the entity. However, when I try to serialize the core data entity, the process fails because it does not know how to convert the keyed archiever's NSData to a string.
What's the best way to convert a UIColor to a string representation for sending within JSON file? One solution is to store the r,g,b,a values as floats. One solution is to save it as a hex string. Both of these seem to complicate the process of color restoration
Am I missing something ? Is there an easier way to serialize a UIColor within JSON?
How about that:
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"];
The result is something like:
{"Color":{"Green":24,"Alpha":1,"Blue":23,"Red":100}}
You can easily make a method that takes UIColor
as an argument and return a NSDictionary, that can be serialized directly. The reverse process is the same.
Since there is no defined standard for putting a UIColor
(let alone a generic "colour") in JSON you are going to have to roll your own.
I would suggest that the nicest method would be to have a category on UIColor
that gives you the standard hex code for the colour in RGB colour-space and also takes in such a hex code and spits out s UIColor
. Then transmit that hex code in the JSON.
I know it might seem like overkill, but it's by far the most portable and compact solution.
An example of the hex to UIColor
method can be found in my MJGFoundation UIColor
category. A similar one to go from UIColor
to hex value wouldn't be too hard to write but be aware of having to get it in RGBA colour-space first.
This depends on the freedom of having a "private" format for the colors. Some colors do not react well to being asked for RGBA (hence why the get...
methods return a BOOL
-- they don't always succeed), so this implementation includes the color type as well as the values.
@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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With