Quantcast
Core Data Transformable Attributes | Lextech Global Services

Blog

News, tutorials, and analyses of all things related to enterprise mobile apps

Core Data Transformable Attributes


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:

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:

@interface Event : NSManagedObject

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

@end

@interface NumbersArray : NSValueTransformer

@end

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:

#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

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:

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:

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.

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

zp8497586rq
zp8497586rq

There are 2 comments .

Chris F —

Cool example. However, when I generated and NSManagedObject subclass from the Event entity, I did NOT get the NumbersArray interface definition inside the Event.h file. Should I just create this, and import Event.h file in it? I use Xcode 4.5.x

sivakrishna —

Thanks a lot. Its working.

Comments are closed

Copyright ©2013 Lextech Global Services. All Rights Reserved.