crunchytoast.com

What's better than toast? Crunchytoast!

crunchyt sez:

This is my first website ... after 15 years of making them for everyone else! Hope you enjoy it too.

The syntax for Enums in C are sooo cool! A lot of people must agree with this statement because they keep wanting to use them in Objective C code. Of course there are other benefits: code readability, they are defined in one block, lighter than passing around string constants, etc. However, being C syntax, they are not well supported inside the gates of Objective C land.

I decided that there must be some better solutions out there, and here are two approaches I have found. One is a good approach, and the other is even better and the one we use (from now on).

Typedef Enum With Matched C Array of NSStrings

[objc]
// Place this in your .h file, outside the @interface block
typedef enum {
JPG,
PNG,
GIF,
PVR
} kImageType;
NSString * const kImageTypeArray[];

// Place this in your .m file, outside the @implementation block
NSString * const kImageTypeArray[] = {
@"JPEG",
@"PNG",
@"GIF",
@"PowerVR"
};

// A method to convert an enum to string
-(NSString*) imageTypeEnumToString:(kImageType)enumVal
{
return kImageTypeArray[enumVal];
}

// A method to retrieve the int value from the C array of NSStrings
-(kImageType) imageTypeStringToEnum:(NSString*)strVal
{
int retVal;
for(int i=0; i < sizeof(kImageTypeArray)-1; i++)
{
if([(NSString*)kImageTypeArray[i] isEqual:strVal])
{
retVal = i;
break;
}
}
return (kImageType)retVal;
}[/objc]

Credit for this goes to Slava Bushtruk

Continuing the tradition of syntatic silliness that abounds in lower level languages, the enums must be declared in a different spot! This is a little counter intuitive and we can do better.

Typedef Enum With #Defined NSArray of NSStrings

[objc]
// Place this in your .h file, outside the @interface block
typedef enum {
JPG,
PNG,
GIF,
PVR
} kImageType;
#define kImageTypeArray @"JPEG", @"PNG", @"GIF", @"PowerVR", nil

// Place this in the .m file, inside the @implementation block
// A method to convert an enum to string
NSString* imageTypeStringToEnum( kImageType enumVal )
{
NSArray *imageTypeArray = [[NSArray alloc] initWithObjects:kImageTypeArray];
return [imageTypeArray objectAtIndex:enumVal];
}

// A method to retrieve the int value from the NSArray of NSStrings
kImageType imageTypeEnumToString(NSString* strVal)
{
NSArray *imageTypeArray = [[NSArray alloc] initWithObjects:kImageTypeArray];
NSUInteger n = [imageTypeArray indexOfObject:strVal];
if(n < 0) n = JPG;
return (kImageType) n;
}[/objc]

Credit goes to Peter N Lewis although it’s been modified it to work!

There you have it, all the declarations fit in the header, and two methods (similar to the first example), for converting between the enum and string representations.

Oh, one more thing. The original author of the second example code created a category for enum handling. Just the thing for adding to your very own NSArray class definition. Fantastic!

[objc]
@interface NSArray (EnumExtensions)

- (NSString*) stringWithEnum: (NSUInteger) enumVal;
- (NSUInteger) enumFromString: (NSString*) strVal default: (NSUInteger) def;
- (NSUInteger) enumFromString: (NSString*) strVal;

@end

@implementation NSArray (EnumExtensions)

- (NSString*) stringWithEnum: (NSUInteger) enumVal;
{
return [self objectAtIndex:enumVal];
}

- (NSUInteger) enumFromString: (NSString*) strVal default: (NSUInteger) def;
{
NSUInteger n = [self indexOfObject:strVal];
if(n < 0) n = def;
return n;
}

- (NSUInteger) enumFromString: (NSString*) strVal;
{
return [self enumFromString:strVal default:0];
}

@end
[/objc]

Credit for the category goes to Peter N Lewis on Stackoverflow.com

3 Responses to “Not So Nasty Enums in Objective-C”

  1. [...] This post was mentioned on Twitter by Crunchy T, Long Weekend. Long Weekend said: Not So Nasty Enums in Objective-C – http://su.pr/9VgiSH [...]

    Tweets that mention Not So Nasty Enums in Objective-C | Long Weekend - iPhone & iPad Apps You'll Love! -- Topsy.com

  2. Have I missed something or in Typedef Enum With Matched C Array of NSStrings should line #25 not read:

    return kImageTypeArray[enumVal];

    that or the parameter should be:

    theEnumValue

    Dave Anderson

  3. @Dave : thank you for the correction. You are correct, I have updated the example accordingly. :D

    Paul

Leave a Reply