Objective-Shorthand is a set of categories on Foundation objects that make long things in Objective-C short.

What types of things can Objective-Shorthand help with?

There are many situations in Cocoa where doing a thing that should be simple is actually very involved. For example, checking if a string matches a regular expression is a 3 line process:

NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:regex options:0 error:nil];  
NSUInteger numberOfMatches = [regularExpression numberOfMatchesInString:self options:0 range:NSMakeRange(0, self.length)];  
BOOL doesMatch = numberOfMatches > 0;  

There are certainly lots of options and power in those lines, but 90% of the time, I just want to know if the string matches the regex:

BOOL doesMatch = [string matchesRegex:regex];  

This is what Objective-Shorthand does. A method to find the range of the first match for a given regex is also included:

- (NSRange) rangeOfFirstSubstringMatching:(NSString*)regex;  

JSON

Using NSJSONSerialization, you have convert your strings to NSData before deserializing them to arrays and dictionaries. Objective-Shorthand simplifies all that.

It provides the same interface as JSONKit, but it works with the built-in Apple JSON serializer behind the scenes. The Ruby community is very good at writing libraries with consistent interfaces, and this is something we need to steal as writers of Objective-C.

To convert from a JSON string to an NSArray or NSDictionary :

- (id) objectFromJSONString;  

And to convert from an array or dictionary to an NSString :

- (NSString *)JSONString;  

NSComparisonMethods

The OS X SDK has a weird API called NSComparisonMethods. Basically, this API provides a wrapper around compare: and uses it define the following methods:

- (BOOL)isEqualTo:(id)object;  
- (BOOL)isLessThanOrEqualTo:(id)object;  
- (BOOL)isLessThan:(id)object;  
- (BOOL)isGreaterThanOrEqualTo:(id)object;  
- (BOOL)isGreaterThan:(id)object;  
- (BOOL)isNotEqualTo:(id)object;  

For some reason, this never made it over to iOS, even though it’s tremendously useful. I like these methods because they’re way more semantic than the regular compare: method. [object isGreaterThan:otherObject] is way easier to understand than [object compare:otherObject] == NSOrderedDescending.

If the object in question doesn’t respond to compare:, an exception will be thrown.

Data Detection Convenience Methods

NSDataDetector can be a handful sometimes. Objective-Shorthand simplifies complex NSDataDetector that take a few complex lines of code:

NSDataDetector *dataDetector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeDate error:nil];   NSTextCheckingResult *firstMatch = [dataDetector firstMatchInString:self options:0 range:NSMakeRange(0, self.length)];   return firstMatch.range.location == 0 && firstMatch.range.length == self.length;  

and simple to one short method call:

- (BOOL) isDate;  

- (BOOL)isEmail, - (BOOL)isURL, - (BOOL)isPhoneNumber, and - (BOOL)isAddress are available, too.

NSArray Convenience Methods

Pulling out the unique elements of an array involves the ever-goofy [array valueForKeyPath:@"@distinctUnionOfObjects.self"]. This is wrapped up inside of the following method:

- (NSArray*) uniquedArray;  

You never have to remember how to type that string literal again! Autocomplete Rules Everything Around Me.

- (NSArray*)sortedArray and -reversedArray are also in Objective-Shorthand.

Functional Collection Operators

Finally, Objective-Shorthand provides categories on NSArray, NSDictionary, and NSSet that provide the normal functional collection operators, like map, select, and any, but with names that are both more semantic and more native to Objective-C. For me, this means I never have to look up what match: means, ever again.

each is already defined in Foundation, so it is not included.

- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block;  

Filtering by block with select (aka filter ) and reject can be bound:

- (NSArray*) arrayBySelectingObjectsPassingTest:(BOOL (^)(id object))test;  
- (NSArray*) arrayByRejectingObjectsPassingTest:(BOOL (^)(id object))test;  

map (aka collect ) and reduce (aka inject ) are available as well.

- (NSArray*) arrayByTransformingObjectsUsingBlock:(id (^)(id object))block;  
- (id) objectByReducingObjectsIntoAccumulator:(id)accumulator usingBlock:(id (^)(id accumulator, id object))block;  

sample and match are available.

- (id) firstObjectPassingTest:(BOOL (^)(id object))test;  
- (id) randomObject;  

And finally, some boolean operators:

- (BOOL) allObjectsPassTest:(BOOL (^)(id object))test;  
- (BOOL) anyObjectsPassTest:(BOOL (^)(id object))test;  
- (BOOL) noObjectsPassTest:(BOOL (^)(id object))test;  

All of the above methods with respective changes are also included for NSSet and NSDictionary.

Using Objective-Shorthand

Use Cocoapods to get Objective-Shorthand:

pod 'Objective-Shorthand', '~> 1.0'  

Find Objective-Shorthand on GitHub at https://github.com/khanlou/Objective-Shorthand/.

If you have questions, comments, or suggestions, please get in touch. You can find me on Twitter at @khanlou and email at soroush@khanlou.com.