Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone iOS how to serialize / save UIColor to JSON File?

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?

like image 842
Alex Stone Avatar asked May 20 '12 17:05

Alex Stone


3 Answers

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.

like image 55
graver Avatar answered Nov 08 '22 11:11

graver


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.

like image 22
mattjgalloway Avatar answered Nov 08 '22 10:11

mattjgalloway


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
like image 2
Kalle Avatar answered Nov 08 '22 10:11

Kalle