Introducing URLMock

Testing networking code is hard. The web service you’re connecting to can fail in myriad ways, from basic networking errors to malformed responses. All but the simplest APIs return a wide variety of data that your app has to handle correctly. Sometimes APIs can be so complex that it’s hard to verify that you’re calling things in the right order, much less sending appropriate parameters and handling responses correctly.

Continue reading “Introducing URLMock” »

Localizing with Plurals and Genders

You’ve just finished your latest application. Congrats! Even though you’re only releasing it in English, you’ve used NSLocalizedString to internationalize your user-facing strings. With strings that require dynamic quantities—“5 items” vs. “1 item”—you handled both the singular and plural cases. You shipped the app and moved on to your next project.

Suddenly your app is a hit… in Russia? You get a lot of feedback that your users want a Russian translation. Easy! You’ll just ship a Russian version of your strings file. Then you realize the problem: in English you can get away with that quick one/not-one check when pluralizing nouns; those are the only two plural categories in the language. Other languages aren’t so simple. Your Russian users have four different rules for pluralizing their nouns. Arabic speakers have six! Thankfully, there are a few tools to help you pluralize nouns for all of them.

Continue reading “Localizing with Plurals and Genders” »

Interactive Transitions

In my previous post, I explained how to create custom animated transitions. This time, I’m going to show how to make interactive transitions.

As a quick review from last time, there are three main roles involved in an animated transition: the from and to view controllers and the animation controller. In a non-interactive transition, the animation controller defines a duration and sets up the animations between the two views. Both views are placed inside of a container view during the transition.

Interactive transitions build on this structure by adding a fourth role: the interaction controller. This new role is played by an object that conforms to the UIViewControllerInteractiveTransitioning protocol.

Continue reading “Interactive Transitions” »

Better Debugging with Quick Look

Quick Look was introduced back in OS X 10.5 Leopard as a system-wide quick preview feature for documents and images. When Apple announced Xcode 5 at WWDC 2013, one of the new tools introduced was Quick Look for debugging. With this you could preview images, colors, and other common types while stepping through your application. All you have to do is hover over a supported variable and click on the Quick Look icon Quick Look or hit the space bar when the variable is selected in the Variables View.

Continue reading “Better Debugging with Quick Look” »

Custom Transitions on iOS

This article is the first in a series that shows how to customize view controller transitions on iOS. In part one, the focus is on creating custom animated (non-interactive) transitions.

When using typical iOS apps we navigate from screen to screen frequently. Previously, if you wanted to do anything other than the standard transition animations, you were on your own, but in iOS 7 Apple has provided a new API to let us customize these animations.

Continue reading “Custom Transitions on iOS” »

Sharing Utilities Using CocoaPods Subspecs

In mid-January, we published TWTToast, a project that collects various utility classes and categories we’ve written over the years. While it’s interesting and useful, we’ll save highlighting its modules for another day. In today’s post, we’re going to focus on how it’s packaged.

Continue reading “Sharing Utilities Using CocoaPods Subspecs” »

TWTSideMenuViewController for iOS 7

One of the most common implementations of menu views has been the “Side Drawer”, “basement”, or “Side Menu” made popular in apps such as Facebook and Path. When someone taps the infamous “Hamburger” to open a side menu the main screen slides to the right (or left in some implementations) to reveal another screen below. This works well in iOS 6 and earlier because the status bar exists in a 20pt tall area that is isolated from the rest of the application. In iOS 7, the status bar is overlaid on the screen below it. What does it mean for sidebars or “basement” views in iOS 7?

Soon after iOS 7 was announced at WWDC in June, many designers on Dribbble started playing around with a new approach for doing these menus. Many came to a similar approach where the main screen would scale down and to the right.

Working with the team at Luvocracy, we were inspired by this approach and with a few ideas of our own we created TWTSideMenuViewController.

TWTSideMenuViewController is a container view controller built to manage a menu view and a main view in a beautiful way.

With iOS 7, apps are encouraged to use the whole screen and not rely on the 20pt status bar to be outside of the main screen of your app. This breaks the existing side bar idea in that the status bar with a single style is overlaid on two views, the menu view and the main view.

With TWTSideMenuViewController we solve this by moving and scaling the main view down and away from the status bar. Inspired by iOS 7, we also improved the idea of this scaled down view approach to think of the menu and the main view as a single view with the menu and main view in the same visual plane. We merely change the viewport to focus on different aspects of the application. This can be seen in iOS 7 when you launch an app and zoom into it or when you use the new app switcher.

We think it is a clean approach that looks beautiful in iOS 7. Below is a video of it in action in the Luvocracy iOS app.

UIAppearance for fun and profit

Building custom user interfaces is something our iOS development team encounters on a daily basis. Anything you can do to make it faster to develop or make your reusable controls easily customizable is an easy victory. UIAppearance gives you this easy victory.

While UIAppearance isn’t a brand new topic, it seems to get less love than it should. UIAppearance is a protocol available since iOS 5 that allows a developer to quickly configure the appearance of user interface controls provided by Apple. The fact that that your custom controls can take part in UIAppearance is talked about even less. This post will cover the basics of using UIAppearance and will explore adding support to your custom interface components.

UIAppearance Basics

You’ll be glad to know that UIAppearance is a straightforward API with almost no learning curve. To use it you need only know three things.

  • Properties and methods exposed to UIAppearance are decorated with the UI_APPEARANCE_SELECTOR attribute.
  • The class method +[UIControl appearance] will set the UIAppearance system to apply the specified properties when the control is created.
  • The class method +[UIControl appearanceWhenContainedIn:] will set the UIAppearance system to apply the specified properties when the control is created, but only when it is created in the specified containers.

That is all there is to it. UI_APPEARANCE_SELECTOR, + appearance, + appearanceWhenContainedIn:

Adding some style to UINavigationBar

Let’s see how this works. Say you want to style your UINavigationBar to be something a little different than the standard iOS style. First, look at the header file for UINavigationBar (you can find this by right-clicking on the symbol and choosing ‘Jump to Definition’ on it in Xcode).

Search for UI_APPEARANCE_SELECTOR. You’ll see it attached to many of the properties and methods, but not all. This is your guide to what is available by UIAppearance. In our case, the first time we see the attribute is with:

@property(nonatomic,retain) UIColor *tintColor UI_APPEARANCE_SELECTOR;

This means that the tintColor property is available for UIAppearance. This means I can now apply a global style affecting the tint to all UINavigationBar objects by telling the appearance proxy:

[[UINavigationBar appearance] setTintColor:[UIColor redColor]];

Now, no matter where a UINavigationBar is displayed within my app, it will be tinted red. Classy.

You can make this even more specific by telling the style to only apply when it is inside your own YOURCustomViewController. Consider the code:

[[UINavigationBar appearanceWhenContainedIn:[YOURCustomViewController class], nil]
                               setTintColor:[UIColor redColor]];

You’ve now told it to only apply the red tint color when a UINavigationBar is displayed inside a YOURCustomViewController. However, if I add a UINavigationBar to another view controller, it will not be tinted red. Only in the case that an instance of a UINavigationBar is in the hierarchy below an instance of a YOURCustomViewController will it be tinted red. Still classy.

All of these appearance styles can be applied as early as you like in your application. For example, you can set all your styles in -[UIApplicationDelegate application:didFinishLaunchingWithOptions:].

Supporting different iOS versions

As can often occur when working with any API, certain versions of can provide different functionality. How can we build an application level style when the available methods and properties on Apple’s controls are changing?

Thankfully, Objective-C is a dynamic language that allows runtime introspection on your objects. In a similar style to how you would ask your object if it -respondsToSelector:, you can ask a class if it’s instances respond to a method as well.

Consider this sample:

if ([UINavigationBar instancesRespondToSelector:@selector(setShadowImage:)]) {
    [[UINavigationBar appearance] setShadowImage:awesomeShadow];
}

The shadowImage property is new to iOS 6. Using +[NSObject instancesRespondToSelector:, we can inspect whether any instance of an object of this type will respond to this selector. Since you’ll be using the class type to apply an appearance, not an instance, this class method will tell you if this property can be used.

Using UIAppearance in your custom UI views

As stated earlier, you too can take advantage of UIAppearance in your custom views. Following the same pattern as seen above, let’s create a UIButton subclass that provides a property through UIAppearance.

I want to expose the font of the label on a UIButton. After subclassing, I’ll create a property that is decorated with “UI_APPEARANCE_SELECTORcalledtitleFont`.

@interface TWTButton : UIButton

@property (nonatomic, strong) UIFont *titleFont UI_APPEARANCE_SELECTOR;

@end

Next, I create the setter implementation and set the title label’s font property.

#import "TWTButton.h"

@implementation TWTButton

- (void)setTitleFont:(UIFont *)titleFont
{
    if (_titleFont != titleFont) {
        _titleFont = titleFont;
        [self.titleLabel setFont:_titleFont];
    }
}

@end

Now, you can set its appearance as if it was always available via UIAppearance:

[[TWTButton appearance] setTitleFont:myFont];

For a more detailed example of this, check out TWTButton.

Be careful using NSNotificationCenter with Blocks

NSNotificationCenter is a long existing mechanism for broadcasting messages to zero or many listeners. Many of Apple’s frameworks work deeply by notifiying you via an NSNotification when a message is posted. Traditionally, the workflow has been to follow a pattern similar to this:

- (void)viewDidLoad 
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(someMethod:) 
                                                 name:kMyNotificationIdentifier 
                                               object:nil];
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)someMethod:(NSNotification *)note
{
    // Message received
}

Blocks!

As of iOS 4 and the introduction of blocks, Mac and iOS developers can now use blocks to subscribe to NSNotification broadcasts. This new method also allows you to specify an NSOperationQueue to perform the block action on.

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserverForName:kMyNotificationIdentifier 
                                                      object:nil 
                                                       queue:nil
                                                  usingBlock:^(NSNotification *note) {
        // message received
    }];
}

Wait, what?

Not so fast! Who is the observer? What removes this observer? What if you load several view controllers that do this? This block based method is not as simple as it appears. Reading the docs, we learn that addObserverForName:object:queue:usingBlock: actually returns an opaque observer that you are meant to retain, and subsequently -removeObserver with. Let’s take a look at what this looks like.

@implementation MyViewController
{
    id _notificationObserver;
}

// ...

- (void)viewDidLoad
{
    [super viewDidLoad];
    _notificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMyNotificationIdentifier 
                                                                              object:nil 
                                                                               queue:nil
                                                                          usingBlock:^(NSNotification *note) {
        // message received
    }];
}

// dealloc, or potentially a method popping this view from the stack
- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:_notificationObserver];
}

As you can see, you still need to track the observer of a notification and remove it. Similar to what you would do if you were using the selector-based notification listener. Oddly enough, this is an example of a block-based API not really improving things. For this API, the selector-based NSNotificationCenter listener is a much simpler option as you don’t have to maintain the observer seperately.