An Introduction to Categories (Part 1 of 2)

pie

Overview

Have you ever wished that you could add one, or a couple, additional functions to an Objective-C core class?
Well Apple has thought of this, and they provide a way without extended the class! The way to do this is called a category. A category is a way to enhance an existing class, by adding additional functions to it. The difference between this and extending a class is that when you extend a class, you can add additional functions, as well as variables. In a category, you can only add additional functions. The benefit of a category though is that you don’t have to use the extended class to get the benefits of the added additional functions. All you have to do is include the header file of the category, and the additional functions of that class are available to you.

A Simple NSDate example

Say we have an NSDate object, and we know that we want it to always be formatted a certain way. You can create an NSDate category, with an additional function called getFormattedString, that will always return an NSString * with the current date formatted a certain way.

How it’s Made

We will start with a simple view based project, that includes two UITextField’s, that we will use to output our dates. I will leave it up to you to create this on your own, or download the entire project from github.

Categories typically have the convention of ClassName+OurText.m, so we create a new file of subclass NSObject, called NSDate+FormatString.m, make sure to check “Also create NSDate+FormatString.h”. After creating those files, we need to make some minor changes to them to actually have them be treated as categories. In the header file, change

@interface NSDate_FormatString : NSObject {

}
@end

to

@interface NSDate (FormatString)

@end

making sure to remove the brackets, in the header file. The reason for this is that a category can not add variables, only functions.

In the implementation file, change

@implementation NSDate_FormatString

to

@implementation NSDate (FormatString)

We have now created a category! This of course doesn’t do anything yet, so lets add some meat to it.

// In NSDate+FormatString.h, after @interface add
- (NSString *)getFormattedString;

// And in NSDate+FormatString.m, after @implementation add
- (NSString *)getFormattedString {
	NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
	[formatter setDateFormat:@"MM/dd/yyyy h:mm a"];
	NSString *returnDate = [formatter stringFromDate:self];
	[formatter release];
	return returnDate;
}

Now to use this category, all we have to do is add

#import "NSDate+FormatString.h"

to any file where we have an NSDate, and we will be able to call

NSDate *today = [NSDate date]; //get the current date
NSLog(@"The current date is: %@", [today getFormattedString]);

This will print out today’s date all nicely formatted for you!

We use this to output a formatted date to our textfield

- (IBAction)dateButtonClicked:(id)sender {
	NSDate *today = [NSDate date];
	originalDateField.text = [today description];
	formattedDateField.text = [today getFormattedString];
}

Of course this is just a very basic example of using a Category. On my next installment I will cover using Categories to add functions to generated Core Data Model classes, and more fun things!

Get this project on github!

Leave a Reply

Your email address will not be published. Required fields are marked *