As we prepare to increment our NSDate Components -year by 1 , it’s time once again for NSHipster end-of-the-year Reader Submissions! Last year, we got some mind-blowing tips and tricks. With the release of iOS 7 & Mavericks, and a year’s worth of new developments in the Objective-C ecosystem, there was a ton of new stuff to write about.

Thanks to Arnaud Coomans, Cédric Luthi, David Grandinetti, Ell Neal, Eric Allam, Erik Kerber, Jim Kubicek, Joachim Bengtsson, Johannes Lund, Josh Avant, João Prado Maia, Justin R. Miller, Kamil Pyć, Matthew Teece, Maximilian Tagher, Nigel Timothy Barber, Nolan O’Brien, Pitiphong Phongpattranont, Steve Moser, Thomas Visser, Vadim Shpakovski, & @jurre for contributing their great tips.

GCC Code Block Evaluation C Extension

Let’s make this official: NSHipster’s Objective-C trend of 2013 is code block evaluation assignment. Recommended by both Jim Kubicek and Maximilian Tagher (citing this blog post by Dominik Wagner), this trick does wonders to make code cleaner, safer, and more concise.

Behind the magic is a GCC C extension, which causes a code block to return a value if enclosed within brackets and parentheses.

Watch, as it cuts through this view controller code like butter!

self . search Bar = ({ UISearch Bar * search Bar = [[ UISearch Bar alloc ] init With Frame :({ CGRect frame = self . table View . frame ; frame . size . height = 50 . 0 f ; frame ; })]; search Bar . delegate = self ; search Bar ; });

This not only segregates configuration details into initialization, but the additional scope allows generic variable names like frame , button , and view to be reused in subsequent initializations. No more login Button Frame = ... / signup Button Frame = ... !

If code craftsmanship is important to you, strongly consider making this standard practice in your work. It may look a bit weird at first, but this will very likely become common convention by the end of 2014.

Default Values with GNU-style Ternary ?:

The ternary operator, ? , is shorthand for if () {...} else {...} . However, because of how difficult it can be to understand statements with ternary operators at a glance, they are generally dispreferred by veteran coders.

Nonetheless, Maximilian Tagher offers a lesser-known (yet much-loved by those in-the-know) use of the ternary operator: ?: , which acts as a convenient way to specify a fallback value to return if the left-hand side is nil .

NSLog ( @"%@" , @"a" ?: @"b" ); // @"a" NSLog ( @"%@" , nil ?: @"b" ); // @"b"

This is especially convenient for providing default behavior when a property may not be set:

dispatch_async ( self . completion Queue ?: dispatch_get_main_queue (), ^ { … });

The main downside of this approach is that default Xcode project warning settings will raise a warning. You can get around this by wrapping the relevant code block in #pragma declarations, but the added LOC nullifies much of the brevity that this approach provides:

#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" self . name = name ?: @"Unknown" ; #pragma clang diagnostic pop

Vadim Shpakovski reminds us of one of the more obscure additions to LLVM 5.0, the @import keyword. No more are the days of Xcode ▹ Project ▹ TARGETS ▹ General ▹ Linked Frameworks and Libraries ▹ + . With @import , the Xcode will automatically link Map Kit , Core Data , or any other referenced framework as necessary. Even Prefix.pch benefits, sporting a svelte new physique:

@import UIKit ; @import Foundation ; @import Core Graphics ;

Customizing MKMapView Tiles

Justin R. Miller, of MapBox fame, brings to our attention what is perhaps the most important feature in iOS 7 mapping: custom tile overlays:

Relatively little-known feature of iOS 7: you can turn off Apple’s own maps now with MKTile Overlay , MKTile Overlay Renderer , and can Replace Map Content , unlike you could before with Apple or (pre-iOS 6) Google. And check out MBXMapKit if you’d like to do it in one line of code.

Thoughtbot’s Blog Post on MapKit Performance

Speaking of iOS maps, João Prado Maia cites an amazing blog post by thoughtbot, “How To Efficiently Display Large Amounts of Data on iOS Maps” by Theodore Calmes. Consider it a must-read if you plan to do any significant iCartography in 2014.

NSAttributedString + HTML in iOS 7

Shifting gears a little bit, Eric Allam remarks that NSAttributed String can do HTML now in iOS 7 with the new NSHTMLText Document Type document type attribute. Combine with MMMarkdown for ridiculously easy Markdown rendering in a UIText View .

Launch Arguments & User Defaults

Offering another tip, Vadim Shpakovski calls our attention to the relationship between launch arguments and NSUser Defaults :

The command line argument -Test Feature Enabled YES can be checked in code with [[NSUser Defaults standard User Defaults] bool For Key:@"Test Feature Enabled"] . This is useful for debugging development builds.

Woes of a Missing UIView Animation Curve Value

Thomas Visser bemoans his pick for least awesome Objective-C development in 2013:

In iOS7, the animation of the keyboard show/hide changed. Its duration and, most notably, its curve is different from previous iOS versions. As before, if you want to animate something with the keyboard, you can listen to UIKeyboard Will Show Notification / UIKeyboard Will Hide Notification and use the values from the user Info dictionary to coordinate your animations with the keyboard. The user Info dictionary contains the keyboard’s begin frame, end frame, animation curve and animation duration.

However, in iOS 7, the animation curve is an undefined value, meaning that it is not one of the 4 defined values of UIView Animation Curve . Instead, its value is 7 . This is a problem if you want to use the same curve in your own animation, because such a curve is not defined. The work-around, as discussed on the Apple forums, is to manually translate the UIView Animation Curve to a UIView Animation Options value. From the definition of UIView Animation Options , we learn that this translation is done by shifting the curve value 16 times to the left: option = curve << 16 . This works great, but shouldn’t be necessary. I hope Apple will add this mysterious 5th curve to the definitions in a future iOS update.

Injecting Analytics on Outgoing Links

David Grandinetti has a tip for apps that want to track outgoing links from within an app: override App Delegate -open URL: :

- ( BOOL ) open URL :( NSURL * ) url { if ([[ url scheme ] has Prefix : @"http" ]) { [[ GAI shared Instance ]. default Tracker send View :[ url absolute String ]]; } return [ super open URL : url ]; }

In this example, this information is being sent to Google Analytics, but one could easily adapt this approach for any analytics provider.

Reviving the Look-and-Feel of iOS 6 in Your App with One Weird Trick (UI Designers hate it!)

Still resisting the aesthetics of this year’s iOS makeover? Kamil Pyć shows us how to act as if iOS 7 never happened:

[[ NSUser Defaults standard User Defaults ] set Object : @YES for Key : @"UIUse Legacy UI" ]

And, of course, following up from a previous tip, since NSUser Defaults is tied to launch arguments, this can also be specified on launch. Keep this tucked in the back of your mind—this could make for a simple yet effective April Fool’s joke.

Detecting Category Method Collisions

Categories are great, but suffer from that same original sin of Objective-C: lack of name-spacing. Duplicate method declarations in categories interact in undefined ways, and may lead to difficult-to-debug behavior.

Fortunately, Cédric Luthi shows us how to tell if any category methods are getting up in one another’s business:

Set the OBJC_PRINT_REPLACED_METHODS environment variable to YES in order to automatically log all methods that are smashed by categories.

A .plist of Emoji, Grouped by Category

In an encore submission, Cédric brings us a .plist file of Emoji grouped by category (mirrored from CloudApp to Gist in order to be more searchable). 😄👍

Quickly Determining the Type of Image Data

Here’s a simple function from Nolan O’Brien that can be used to determine the type of image data based on the first couple bytes of the header:

static inline NSPUIImage Type NSPUIImage Type From Data ( NSData * image Data ) { if ( image Data . length > 4 ) { const unsigned char * bytes = [ image Data bytes ]; if ( bytes [ 0 ] == 0xff && bytes [ 1 ] == 0xd8 && bytes [ 2 ] == 0xff ) { return NSPUIImage Type_JPEG ; } if ( bytes [ 0 ] == 0x89 && bytes [ 1 ] == 0x50 && bytes [ 2 ] == 0x4e && bytes [ 3 ] == 0x47 ) { return NSPUIImage Type_PNG ; } } return NSPUIImage Type_Unknown ; }

Print KVO Context

Once again, showing off his unmatched knowledge of Objective-C internals, Cédric shares this extremely useful tip for debugging Key-Value Observing.

Print which context is passed to observe Value For Key Path:of Object:change:context: in lldb.

Say you have declared a context like this:

static const void * My Foo Context = & My Foo Context ;

…and you want to to know what context it is when you are inside

- ( void ) observe Value For Key Path :( NSString * ) key Path of Object :( id ) object change :( NSDictionary * ) change context :( void * ) context

You can do this:

(lldb) image lookup -a `context` Address: My App[0x00026258] (My App.__DATA.__data + 4) Summary: My Foo Context

Creating a KeyPath from Selectors

On the subject of Key-Value Coding, Pitiphong Phongpattranont offers this useful function that builds a keypath from a variable list of selectors:

Objective-C Objective-C inline NSString * PTPKey Path For Selectors ( SEL selector , ...) { if ( ! selector ) { return nil ; } NSMutable Array * selectors = [ NSMutable Array array ]; va_list args ; va_start ( args , selector ); SEL arg = selector ; do { [ selectors add Object : NSString From Selector ( arg )]; } while (( arg = va_arg ( args , SEL ))); va_end ( args ); return [ selectors components Joined By String : @"." ]; } NSString * key Path = PTPKey Path For Selectors ( @selector ( data ), @selector ( name ), nil ); // => @"data.name"

Nomad CLI Utilities

And finally, Matthew Teece gives a shout-out to Nomad, a world-class collection of command-line utilities—specifically, Houston, which can send and manage push notifications from the command line, or within your Ruby application.

$ apn push "<token>" -c /path/to/cert.pem -m "Hello!"

Thus concludes this year’s reader submissions. Thanks again to everyone for your submissions!

And thanks to you, dear reader, for sticking with NSHipster for another 52 weeks. Between the WWDC session and the book, 2013 has been a bellwether year for NSHipster. Thank you for your support and enthusiasm for the site—it really does mean the world to me.

We have a ton of great stuff planned for 2014, so keep your fixies primed and your artisanal espresso hot for another season of great iOS and OS X knowledge.