Core Data Transformable Attributes

January 22, 2013

  • Felipe Laso Marsetti
  • 1
Tutorials

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.

writing essays for money

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:

Transformable Attribute

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:

[sourcecode lang=”objc”]
@interface Event : NSManagedObject

@property (nonatomic, retain) NSDate * timeStamp;
@property (nonatomic, retain) id numbersArray;

@end

@interface NumbersArray : NSValueTransformer

@end
[/sourcecode]

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:

[sourcecode lang=”objc”]
#import "Event.h"

@implementation Event

@dynamic timeStamp;
@dynamic numbersArray;

@end

@implementation NumbersArray

+ (Class)transformedValueClass
{
return [NSArray class];
}

+ (BOOL)allowsReverseTransformation
{
return YES;
}

– (id)transformedValue:(id)value
{
return [NSKeyedArchiver archivedDataWithRootObject:value];
}

– (id)reverseTransformedValue:(id)value
{
return [NSKeyedUnarchiver unarchiveObjectWithData:value];
}

@end
[/sourcecode]

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

transformedValue:

That converts the NSArray into NSData using NSKeyedArchiver and

reverseTransformedValue:

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:

[sourcecode lang=”objc”]
NSMutableArray *numbersArray = [NSMutableArray array];

for (int i = 0; i < 5; i++)
{
[numbersArray addObject:[NSNumber numberWithInteger:arc4random_uniform(100)]];
}

event.numbersArray = [NSArray arrayWithArray:numbersArray];
[/sourcecode]

Pretty standard code.

In DetailViewController.m's viewDidLoad method there's just an NSLog to print out the array and its values:

NSLog with Array numbers

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.

write my paper

Here are the project files so you can check out the code and play around with your own transformable values.

zp8497586rq
zp8497586rq