Today we're going to share a tip that will help you if you're working with Core Data. Core Data is an incredibly powerful API. There are, however, situations when you want a particular entity to have an attribute other than the ones available by default.
Enter Transformable attributes, which give you the ability to store something as NSData but retrieve as the actual object you intend to use in your application. This can be an NSArray, UIImage, JSON data, etc.
To demonstrate the use of Transformable attributes in a Core Data entity I've created a sample navigation-based project with an entity as shown below:
Notice (in the Data Model Inspector) that Attribute Type is set to Transformable and for name we've used NumbersArray. The name can be whatever you like, just remember it because you'll write a custom class in order to implement the transformable.
Having done this, select the Event entity and go to Editor > Create NSManagedObject Subclass…. Great, your custom subclass looks pretty standard. Notice how there's a property of type id called numbersArray, this is because you don't know what it's going to be, you determine this at runtime via an NSValueTransformer subclass. This is the declaration of our subclass inside Event.h:
@interface Event : NSManagedObject
@property (nonatomic, retain) NSDate * timeStamp;
@property (nonatomic, retain) id numbersArray;
@interface NumbersArray : NSValueTransformer
The NumbersArray class has the same name as the transformable you set in your entity and it subclasses NSValueTransformer. Now let's look at the Event.m file to see how the transformable is implemented:
return [NSArray class];
return [NSKeyedArchiver archivedDataWithRootObject:value];
return [NSKeyedUnarchiver unarchiveObjectWithData:value];
We implement some methods to specify the class we are transforming to, that we allow reverse transformation as well as the transformed value and reverse transformed value.
They key methods here are
That converts the NSArray into NSData using NSKeyedArchiver and
That converts NSData to an NSArray using NSKeyedUnarchiver.
After this I've just added some code to randomly generate five numbers and put them in an Event's array. This code goes inside MasterViewcontroller.m's insertNewObject: method:
NSMutableArray *numbersArray = [NSMutableArray array];
for (int i = 0; i < 5; i++)
[numbersArray addObject:[NSNumber numberWithInteger:arc4random_uniform(100)]];
event.numbersArray = [NSArray arrayWithArray:numbersArray];
Pretty standard code.
In DetailViewController.m's viewDidLoad method there's just an NSLog to print out the array and its values:
And with that, you have a custom object stored in a Core Data entity. You can use this to store encrypted values, images, music files, etc. Of course restrictions and suggestions apply just as if you were using in memory, SQLite or binary stores.
Here are the project files so you can check out the code and play around with your own transformable values.