Store a UIImage in Core Data using a value transformer

At this point in time, you have learned about the types which can be used for Core Data attributes. If you want to store another type, you can use a value transformer.

.

In this post, we present a “Professors” example app. It is similar in some ways to the “CD Complete” example app, in that it offers a navigation-based style, with viewing and adding/editing of objects.

It also presents two new ideas to you:

  1. Value transformer
  2. Category

.

A value transformer is an object which packages, and un-packages, objects of a type that isn’t directly supported in a Core Data attribute. We will use a value transformer to store a professor photo.

A category enables you to extend a class by adding your own methods. We will use a category to add a method to UIImage that will scale an image to a desired size.
.

The “Professors” example app

This example app uses Core Data, and enables you to create a list of your professors. You then have fast access to their office number, photo, and website, and can send them an email message.

There are three new concepts shown in this application:

  1. Proper coding of a Cocoa “Category”
  2. The use of a Value Transformer, which enables us to store a UIImage in a Core Data store
  3. The ability to send email from within an application

.

Download the Professors example app from the downloads area.

The first row of screen shots shows the professor list, the “Add professor” screen that appears when you tap the + button, and a professor detail screen that appears when you tap on a row.

prof1small prof6small prof2small

.

The next row of screens shows the editing screen, the send-an-email screen, and the visit website screen.

prof3small prof4small prof5small

.

Value Transformer discussion

When you created your own Core Data model, you learned that the attribute types are somewhat limited. This fact is not unexpected, and is similar to the situation you face with other object and data stores.

Despite this, it is possible to store almost almost any type in a Core Data store. This is done by using a value transformer.

Value transformers are classes that can transform the value of an object in some manner. Cocoa includes a number of standard value transformers, and you can create your own custom value transformers.

All value transformers are subclasses of NSValueTransformer. This superclass provides a set of abstract methods, for which you must provide a concrete implementation. A value transformer can also support two-way transforms. A typical value transformer must implement four methods.

The Value Transformer Programming Guide will help introduce you to the task of “Writing a Custom Value Transformer”. Be sure to check out that section.

In our example today, we wish to store two UIImage objects in the Core Data store for each managed object. For both images, we will write a custom value transformer, that provides two-way transforms to-and-from UIImage and NSData. Then, we will specify that the attribute type is “Transformable”.

Where should the value transformer code be placed? Well, it can be placed in a separate code file (.h and .m pairing), or the code can be placed in an existing code file. Our code, in this example app, is located in the application delegate.

The code is a complete class definition and implementation. The interface looks like this:

@interface ImageToDataTransformer : NSValueTransformer { }
@end

.

As always, the class name is assigned by you. The class inherits from NSValueTransformer.

The implementation must implement two NSValueTransformer class methods, and two instance methods:

@implementation ImageToDataTransformer
+ (BOOL)allowsReverseTransformation { }
+ (Class)transformedValueClass { }
- (id)transformedValue:(id)value { }
- (id)reverseTransformedValue:(id)value { }
@end

.

We usually do not explicitly call these methods ourselves. They are called, in our example app automatically, by the Core Data object management methods, when we assign a value (like a UIImage object) to a managed object attribute, or extract a value from a managed object attribute, and use it as a UIImage.

Notice the definition for the “photo” attribute, in the “Professor” entity, shown below in the image. Its type is Transformable, and it names the value transformer ImageToDataTransformer, which (in this example app) is located in the app delegate.

.

Check the NSValueTransformer Class Reference documentation for more on these methods.

Check the code in the example app’s app delegate for comments that help you interpret the use of these methods.

.

Category discussion

A category is the term used in Objective-C and Cocoa, for a class-like code structure that enables you to add methods to a class, without having to subclass.

The Apple Cocoa Core Competencies document on Category does an excellent job of defining a category, and showing you how to implement a category. Please read the document before we continue.

Welcome back.

In our Professors example app, we have decided that we want to store a full-sized image, and a thumbnail-sized image. The thumbnail-sized image will be used in the table view that shows the list of professors.

The UIImage class does not have a built-in method to create a thumbnail. Therefore, we wish to “extend” UIImage, by adding a new method called scaleToSize:, and we can do this by adding a category.

The code for the scaleToSize: method, and the general approach, have been derived from a study of a number of Apple and other example apps. Study the UIImage+Resizing class for details; it has been generously commented. Its scaleToSize: method is called in the ProfEdit view controller, by the save method.

.


  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 47 other followers

%d bloggers like this: