Ben Scheirman

These fickle bits...

Menu

Handy Categories on NSString

In Objective-C there is a great feature called Categories. To .NET folk, this closely resembles extension methods, and it is a great way to achieve utility code re-use and in general heighten the level of the code that you’re working with. It’s also a great way to turn a very hairy method and section it off into very simple, coherent tasks.

In some cases this means adding methods that don’t necessarily belong on the class in question, but they make perfect sense in the context of your application.

In other cases, you can use Categories to add methods that ought to be there in the first place.

Here are a few handy categories on NSString that I carry around from project to project:

NSString+Common.h
1
2
3
4
5
6
7
8
9
@interface NSString (Common)

-(BOOL)isBlank;
-(BOOL)contains:(NSString *)string;
-(NSArray *)splitOnChar:(char)ch;
-(NSString *)substringFrom:(NSInteger)from to:(NSInteger)to;
-(NSString *)stringByStrippingWhitespace;

@end
NSString+Common.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#import "NSString+Common.h";
@implementation NSString (Common)
-(BOOL)isBlank {
  if([[self stringByStrippingWhitespace] isEqualToString:@""])
    return YES;
  return NO;
}

-(BOOL)contains:(NSString *)string {
        NSRange range = [self rangeOfString:string];
       return (range.location != NSNotFound);
}

-(NSString *)stringByStrippingWhitespace {
      return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

-(NSArray *)splitOnChar:(char)ch {
    NSMutableArray *results = [[NSMutableArray alloc] init];
   int start = 0;
     for(int i=0; i<[self length]; i++) {

           BOOL isAtSplitChar = [self characterAtIndex:i] == ch;
              BOOL isAtEnd = i == [self length] - 1;

           if(isAtSplitChar || isAtEnd) {
                     //take the substring &amp; add it to the array
                 NSRange range;
                     range.location = start;
                    range.length = i - start + 1;

                   if(isAtSplitChar)
                          range.length -= 1;

                   [results addObject:[self substringWithRange:range]];
                       start = i + 1;
             }

           //handle the case where the last character was the split char.  we need an empty trailing element in the array.
            if(isAtEnd && isAtSplitChar)
                       [results addObject:@""];
   }

   return [results autorelease];
}

-(NSString *)substringFrom:(NSInteger)from to:(NSInteger)to {
  NSString *rightPart = [self substringFromIndex:from];
  return [rightPart substringToIndex:to-from];
}

@end

To use these new functions, you simply reference the header file and access them as if they were built-in methods on NSString:

1
[@"foo.xml" splitOnChar:'.']; // returns NSArray with 2 elements: ["foo", "xml"]
1
[@"" isBlank]; // returns YES

I’m used to having access to higher level methods like these in C# and Ruby, however in Objective-C they seem to be oddly missing. Thankfully Categories can fill this gap for now.

Comments