Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing UIColor object in Core Data

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.

In my research, while the literature seems pretty sparse, I find this post saying that the attribute should be specified as "Transformable," and that the data should be manually converted going in using NSKeyedArchiver and coming out using NSKeyedUnarchiver.

But then, I find a more recent post saying that all that's necessary is to save the UIColor as a Transformable attribute in CD, generate a Managed Object subclass, and use just like other attributes.

The Apple docs themselves go into some detail on storing and retrieving NSColor objects, but not (that I could find) on UIColor. However, it makes it sound like the archiving/unarchiving is handled automatically within CD. Maybe. I was confused by this line:

If you are using the model editor in Xcode, select Transformable in the attribute’s Type popup and type the name in the Value Transformer Name text field.

I assume they're talking about the name of the attribute, but am not sure, especially since it warns about potential problems arising from specifying the transformer explicitly:

Important: Although the default transformer is the transformer specified by NSKeyedUnarchiveFromDataTransformerName, this transformer is actually used in reverse. If you specify the default transformer explicitly, Core Data would use it “in the wrong direction.”

I've gotten to the point where I have a new transformable attribute named "color," (did not name the transformer) and have generated a new subclass file containing the new "color" property (type id).

I'm just plain perplexed. Can someone please give me some definitive guidance on how to proceed from here?

I'm using MagicalRecord to interface with Core Data, if that matters.

Many thanks for helping!

like image 638
rattletrap99 Avatar asked May 23 '14 17:05

rattletrap99


People also ask

Where is Core Data stored?

The persistent store should be located in the AppData > Library > Application Support directory.

What is transformable in Core Data?

When you declare a property as Transformable Core Data converts your custom data type into binary Data when it is saved to the persistent store and converts it back to your custom data type when fetched from the store. It does this through a value transformer.

How does Core Data save data?

Use Core Data to save your application's permanent data for offline use, to cache temporary data, and to add undo functionality to your app on a single device. To sync data across multiple devices in a single iCloud account, Core Data automatically mirrors your schema to a CloudKit container.

Should I use Core Data?

The next time you need to store data, you should have a better idea of your options. Core Data is unnecessary for random pieces of unrelated data, but it's a perfect fit for a large, relational data set. The defaults system is ideal for small, random pieces of unrelated data, such as settings or the user's preferences.


2 Answers

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.

like image 72
quellish Avatar answered Oct 13 '22 00:10

quellish


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
like image 30
Anand Avatar answered Oct 12 '22 23:10

Anand