Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
339 views
in Technique[技术] by (71.8m points)

iphone - Core Data data model: attribute type for UIColor

I'm just starting out with Core Data and right now I'm building my data model. I need a UIColor attribute for my entity, but the type dropdown for the attribute doesn't have an option for this. Do I set it to Undefined or what?

Thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'll paraphrase the definitve answer I found in More iPhone 3 Development by Dave Mark and Jeff LeMarche:

Usually we'd be able to leave the transformable attribute's transformer class as the default, NSKeyedUnarchiveFromData, and be done, but in this case we can't because UIColor doesn't conform to NSCoding and can't be archived using an NSKeyedArchiver. We have to manually write a value transformer to handle the transformation.

Add an attribute to your entity and call the attribute "color", or whatever name you wish. Set its type to Transformable. Set its "Value Transformer Name" to UIColorRGBValueTransformer. Note that the data model editor doesn't validate the Value Transformer Name: to make sure it's a valid class, so type carefully.

Create a new file, a subclass of NSObject, and name it UIColorRGBValueTransformer.m.

Click UIColorRGBValueTransformer.h and change the superclass from NSObject to NSValueTransformer. Also, change #import <Foundation/Foundation.h> to #import <UIKit/UIKit.h>, since UIColor is part of UIKit, not Foundation.

Now in UIColorRGBValueTransformer.m, we need to implement four methods that allow our value transformer class to convert instances of UIColor to NSData and vice versa. Include the following code in 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

Now in another file, you can include a line of code like:

[self.managedObject setValue:color forKey:self.keyPath];

without needing to import UIColorRGBValueTransformer.h in the file.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...