Storing UIColor object in Core Data

前端 未结 4 2051
感情败类
感情败类 2020-12-01 14:18

I want to store a UIColor object as an attribute on a Core Data entity, then retrieve it and use it in the same fashion that I do the other attributes on that entity.

<
相关标签:
4条回答
  • 2020-12-01 15:04

    Another option available, Swift 3

    extension UIColor {
        class func color(withData data:Data) -> UIColor {
             return NSKeyedUnarchiver.unarchiveObject(with: data) as! UIColor
        }
    
        func encode() -> Data {
             return NSKeyedArchiver.archivedData(withRootObject: self)
        }
    }
    

    Usage

    var myColor = UIColor.green
    // Encoding the color to data
    let myColorData = myColor.encode() // This can be saved into coredata/UserDefaulrs
    let newColor = UIColor.color(withData: myColorData) // Converting back to UIColor from Data
    
    0 讨论(0)
  • 2020-12-01 15:12

    In order to save a UIColor to core data you need to separate the red, blue, and green values. Then, within your creation code, fetch the RGB values and create a UIColor object with the fetched results. This is way easier than it sounds, and you don't have to provide any work around with NSKeyArchiver/Unarchiver or NSUserDefaults.

    In your data model, within your color entity, create three attributes: red, green, and blue of type float. Then subclass NSManagedObject for the color entity. (if you've worked with core data before this should sound familiar.) But, this isn't a question on how to use core data, so I'm gonna get to it.

    For the sake of the argument we are going to generate a random color and persist it to core data (you can set the RGB values to whatever color you wish).

    First create three properties of type float in the implementation file of whichever class you are going to be using it.

    @property (nonatomic) float randomRedColor;
    @property (nonatomic) float randomBlueColor;
    @property (nonatomic) float randomGreenColor;
    

    Set up your method for saving to core data with at minimum, 3 parameters of type float for each RGB value. Remember, that entity attributes must be an object and not of a primitive type, so wrap your float values in an NSNumber when setting the value for key.

    -(void) withColors:(float)redColor withBlue:(float)blueColor withGreen:(float)greenColor{
    
    //set up NSManagedObjectContext/EntityDescription/ManagedObject (core data)
    
    self.randomRedColor = redColor;
    self.randomBlueColor = blueColor;
    self.randomGreenColor = greenColor;
    
    [newCategory setValue:[NSNumber numberWithFloat:redColor] forKey:@"red"];
    [newCategory setValue:[NSNumber numberWithFloat:blueColor] forKey:@"blue"];
    [newCategory setValue:[NSNumber numberWithFloat:greenColor] forKey:@"green"];
    
    //save new objects (core data)
    

    Wherever you plan on calling this method, you'll create three floats with random values, and pass them in: (I like to do all of this set up in a data source, so don't worry about my sharedInstance. If you aren't familiar with the singleton pattern, don't worry, I'm simply just calling the method and passing in the randomly generated values as our arguments.)

    float red = (arc4random()%256/256.0);
    float blue = (arc4random()%256/256.0);
    float green = (arc4random()%256/256.0);
    
    [[DataSource sharedInstance] withColors:red withBlue:blue withGreen:green];
    

    Now simply import your Color NSManagedObject's header file and create your Color NSManagedObject property in this case we will call it *color:

    @property (nonatomic, strong) Color *color 
    

    Assuming anybody reading this knows how to perform a fetch request, we'll now use our *red *blue and *green attributes that have been provided when we subclassed our Color entity.

    float red = [self.category.red floatValue];
    float green = [self.category.green floatValue];
    float blue = [self.category.blue floatValue];
    

    all that is left is to store the retrieved values in UIColor object:

    UIColor *randomRGBColor = [[UIColor alloc] initWithRed:red green:green blue:blue alpha:1.0]; 
    

    Now you're done. You have successfully stored the UIColor object. I hope this helps!

    0 讨论(0)
  • 2020-12-01 15:16

    The above answers pointed me in the right direction but the requirements have moved on. Search 'Saving UIColor and Array in CoreData Using Transformable' to see more information.

    I was able to add transformable fields to core data and get it to sync via iCloud using the above answers and the article I found outwith stack overflow.

    0 讨论(0)
  • 2020-12-01 15:24

    Your attribute should be of the type Transformable. The default value transformer (NSKeyedUnarchiveFromDataTransformerName) can transform any object that conforms to NSCoding.

    1. Mark the attribute as type "Tranformable".
    2. Optional: Set the Value Transformer Name to "NSKeyedUnarchiveFromDataTransformerName". If you do not, it will default to this anyway.

    Like so

    You do not have to do anything else. Keep in mind you will not be able to match transformable attribute with a predicate or sort by them. They are pretty much just storage - the value transformer transforms the object value into NSData, which is what gets persisted in the store. When the attribute fault fires Core Data uses the transformer in the other direction to go from NSData to your object type.

    0 讨论(0)
提交回复
热议问题