Software often eludes analogy. It’s written in code, compiled into assembly, translated into CPU instructions, run on a kernel, and finally executed on invisibly tiny transistors. Such a complex beast is hard to map onto the real world.

The analogy we’ve settled on for the creation of software is the architect/builder separation. The designer is the architect: he provides a specification for the product. The programmer is the builder: she implements it. However, this formulation is functionally a myth, and understanding why it’s wrong will help explain why software is delivered late, low-quality, and over-budget.

This koan on the Codeless Code is an interesting one. In addition to being cute and snarky, it makes a very strong case that the civil engineer and the software engineer do very different things. We know that the designer is not doing the building; if programmer is also not doing the building, how is software turning from idea into reality?

What is happening is that the designer presents the software as very high-level blueprints to the programmer. The programmer then takes those and creates a lower-level set of blueprints for the compiler.

(Incidentally, the compiler is producing an even lower-level blueprint, called the Intermediate Representation, which is translated in to a final set of blueprints, the specific instructions for different CPUs. It’s blueprints all the way down.)

The compiler takes the programmer’s blueprints and arranges them (nearly instantly!) into their final form. The actual “construction” phase of software engineering is effectively free. To understand how fundamentally strange that is, imagine a machine that accepts blueprints for a bridge and instantly produces the whole bridge. The completed bridge takes up practically no space so we can produce as many copies of it as we want. In addition, our machine can produce other physical constructs to poke and prod the bridge to make sure it works as expected. That would be a very weird world for civil engineers indeed!

This new analogy helps explain two things about our industry. First, it helps explain why requirements change all the time. People have seen how powerful code is, and how quickly it can be changed. It’s also hard to explain in advance why some changes are much more difficult to make than others, so requirements will change in the process of creating the blueprints. Nothing is final until the “Submit to App Store” button is pressed.

The other thing that this analogy helps explain is the “mythical man month”. Bringing on another programmer paradoxically slows the project down. You can add extra builders to a bridge to build it faster, just as you can add extra clock cycles or cores to a CPU to make it compile faster. But nobody has ever suggested that architects are fungible. Smaller teams produce higher quality code for this reason. The “architects” aren’t isolated, given a rote task, and managed in a top-down fashion. Designing software architecture takes omnidirectional communication, which gets costly as teams grow.

What else can we learn here? Because the designer’s “blueprints” are interpreted by a human, any inconsistencies can be smoothed out. The programmer’s blueprints have to be much more detailed, since they will be interpreted literally and unambiguously by a CPU. It pays to have more explicit blueprints earlier in the pipeline, because the programmer will have to do less interpolation to fill those gaps. Creating those specifications will result in better software, and can help with reducing requirement creep.

Because computers only emulate the real world for convenience’s sake, it can be hard to remember how many layers of abstraction lie between the code you write and the actual silicon that runs it. In Structure and Interpretation of Computer Programs, Abelson and Sussman say:

A computational process is indeed much like a sorcerer’s idea of a spirit. It cannot be seen or touched. It is not composed of matter at all. However, it is very real. It can perform intellectual work. It can answer questions. It can affect the world by disbursing money at a bank or by controlling a robot arm in a factory. The programs we use to conjure processes are like a sorcerer’s spells.

It’s not valuable to think of software as a bridge; it’s too weird for that.

View controllers become gargantuan because they’re doing too many things. Keyboard management, user input, data transformation, view allocation — which of these is really the purview of the view controller? Which should be delegated to other objects? In this post, we’ll explore isolating each of these responsiblities into its own object. This will help us sequester bits of complex code, and make our code more readable.

In a view controller, these responsibilities might be grouped into #pragma mark sections. When that happens, it’s usually time to start thinking about breaking it apart into smaller components.

Data Source

The Data Source Pattern is a way of isolating the logic around which objects live behind what index paths. Particularly in complicated table views, it can be useful to remove all of the logic of “Which cells are visible under these conditions?” from your view controller. If you’ve ever written a table view where you’re constantly comparing integers of rows and sections, a data source object is for you.

Data source objects can literally conform to the UITableViewDataSource protocol, but I’ve found that configuring cells with those objects is a different role than managing index paths, so I like to keep these two objects separate.

A simple example of a data source might handle sectioning logic for you.

@implementation SKSectionedDataSource : NSObject

- (instancetype)initWithObjects:(NSArray *)objects sectioningKey:(NSString *)sectioningKey {
    self = [super init];
    if (!self) return nil;

    [self sectionObjects:objects withKey:sectioningKey];

    return self;
}

- (void)sectionObjects:(NSArray *)objects withKey:(NSString *)sectioningKey {
    self.sectionedObjects = //section the objects array
}

- (NSUInteger)numberOfSections {
    return self.sectionedObjects.count;
}

- (NSUInteger)numberOfObjectsInSection:(NSUInteger)section {
    return [self.sectionedObjects[section] count];
}

- (id)objectAtIndexPath:(NSIndexPath *)indexPath {
    return self.sectionedObjects[indexPath.section][indexPath.row];
}

@end

While this data source is designed to be abstract and reusable, don’t be afraid to make a data source that’s used in only one place in your app. Separating index path management logic from your view controller is a noble goal in itself. Especially for highly dynamic table views, it’s good to have an object that notifies the view controller with messages like “Hey, I have a new object at this index path”; the view controller can then pass that along to the table view in the form of an animation.

This pattern can also encapsulate your retrieval logic. A remote data source can fetch a collection of objects from an API. UIViewController is a UI object, and this is a great way to get networking code out of your view controller.

If the interface to all your data sources is stable (with a protocol for example), you can write a special data source that is composed of an arbitrary number of other data sources. Each sub-data-source becomes its own section in the multi data source. Using this logic to combine data sources is a great way to avoid having to write dreadful index comparison code. The data source will manage it all for you!

Standard Composition

View controllers can be composed using the View Controller Containment APIs introduced in iOS 5. If your view controller is composed of several logical units that could each be their own view controller, consider using Composition to break them apart. A practical application of this litmus test is a screen with multiple table views or collection views.

On a screen with a header and a grid view, we could lazy load our two view controllers, and lay them out properly when prompted by the system.

- (SKHeaderViewController *)headerViewController {
    if (!_headerViewController) {
        SKHeaderViewController *headerViewController = [[SKHeaderViewController alloc] init];

        [self addChildViewController:headerViewController];
        [headerViewController didMoveToParentViewController:self];

        [self.view addSubview:headerViewController.view];

        self.headerViewController = headerViewController;
    }
    return _headerViewController;
}

- (SKGridViewController *)gridViewController {
    if (!_gridViewController) {
        SKGridViewController *gridViewController = [[SKGridViewController alloc] init];

        [self addChildViewController:gridViewController];
        [gridViewController didMoveToParentViewController:self];

        [self.view addSubview:gridViewController.view];

        self.gridViewController = gridViewController;
    }
    return _gridViewController;
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    CGRect workingRect = self.view.bounds;

    CGRect headerRect = CGRectZero, gridRect = CGRectZero;
    CGRectDivide(workingRect, &headerRect, &gridRect, 44, CGRectMinYEdge);

    self.headerViewController.view.frame = tagHeaderRect;
    self.gridViewController.view.frame = gridRect;
}

The resulting sub-view controllers, each with their own collection view, handle one uniform type of data. They are much smaller and easier to understand and change because of it.

Smarter Views

If you’re allocating all of your view controller’s subviews inside of the view controller’s class, you may consider using a Smarter View. UIViewController defaults to using UIView for its view property, but you can override it with your own view. You can use -loadView as the access point for this, as long as you set self.view in that method.

@implementation SKProfileViewController

- (void)loadView {
    self.view = [SKProfileView new];
}

//...

@end

@implementation SKProfileView : NSObject

- (UILabel *)nameLabel {
    if (!_nameLabel) {
        UILabel *nameLabel = [UILabel new];
        //configure font, color, etc
        [self addSubview:nameLabel];
        self.nameLabel = nameLabel;
    }
    return _nameLabel;
}

- (UIImageView *)avatarImageView {
    if (!_avatarImageView) {
        UIImageView * avatarImageView = [UIImageView new];
        [self addSubview:avatarImageView];
        self.avatarImageView = avatarImageView;
    }
    return _avatarImageView
}

- (void)layoutSubviews {
    //perform layout
}

@end

You can simply redeclare @property (nonatomic) SKProfileView *view, and because it is a more specific type than UIView, the analyzer will do the right thing and assume self.view is an SKProfileView. This is called a covariant return type and is very useful for this pattern. (The compiler needs to know that your class is a subclass of UIView, so make sure you import the .h file instead of doing an @class forward declaration! Update: In Xcode 6.3, you also have to declare the property as dynamic, by including the code @dynamic view; in your implementation block.)

Presenter

The Presenter Pattern wraps a model object, transforms its properties for display, and exposes messages for those transformed properties. It is also known in other contexts as Presentation Model, the Exhibit pattern, and ViewModel.

@implementation SKUserPresenter : NSObject

- (instancetype)initWithUser:(SKUser *)user {
    self = [super init];
    if (!self) return nil;
    _user = user;
    return self;
}

- (NSString *)name {
    return self.user.name;
}

- (NSString *)followerCountString {
    if (self.user.followerCount == 0) {
        return @"";
    }
    return [NSString stringWithFormat:@"%@ followers", [NSNumberFormatter localizedStringFromNumber:@(_user.followerCount) numberStyle:NSNumberFormatterDecimalStyle]];
}

- (NSString *)followersString {
    NSMutableString *followersString = [@"Followed by " mutableCopy];
    [followersString appendString:[self.class.arrayFormatter stringFromArray:[self.user.topFollowers valueForKey:@"name"]];
    return followersString;
}

+ (TTTArrayFormatter*) arrayFormatter {
    static TTTArrayFormatter *_arrayFormatter;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _arrayFormatter = [[TTTArrayFormatter alloc] init];
        _arrayFormatter.usesAbbreviatedConjunction = YES;
    });
    return _arrayFormatter;
}

@end

Crucially, the model object itself is not exposed. The Presenter serves as the gatekeeper to the model. This ensures that the view controller can’t sidestep the presenter and directly access the model. Architecture like this limits your dependency graph, and since the SKUser model touches fewer classes, changing it will causes fewer effects in your app.

Binding pattern

In method form, this might be called -configureView. The Binding Pattern updates a view with model data as it changes. Cocoa is a natural place to use this because KVO can observe the model, and KVC can read from the model and “write” to the view. Cocoa Bindings are the AppKit version of this pattern. Third-party libraries like Reactive Cocoa are also effective for this pattern, but may be overkill.

This pattern works really well in conjunction with the Presenter Pattern, using one object to transform values, and another to apply them to your view.

@implementation SKProfileBinding : NSObject

- (instancetype)initWithView:(SKProfileView *)view presenter:(SKUserPresenter *)presenter {
    self = [super init];
    if (!self) return nil;
    _view = view;
    _presenter = presenter;
    return self;
}

- (NSDictionary *)bindings {
    return @{
              @"name": @"nameLabel.text",
              @"followerCountString": @"followerCountLabel.text",
            };
}

- (void)updateView {
    [self.bindings enumerateKeysAndObjectsUsingBlock:^(id presenterKeyPath, id viewKeyPath, BOOL *stop) {
        id newValue = [self.presenter valueForKeyPath:presenterKeyPath];
        [self.view setObject:newvalue forKeyPath:viewKeyPath];
    }];
}

@end

(Note that our simple presenter from above isn’t necessarily KVO-able, but it could be made to be so.)

As with all of these patterns, you don’t have to figure out the perfect abstraction on your first attempt. Don’t be afraid to make an object that is only usable in one specific case. The goal is not to eliminate code reuse, it’s to simplify our classes so that they’re easier to maneuver through and understand.

Interaction pattern

The ease of typing actionSheet.delegate = self is part of the reason that view controllers become too big to fail. In Smaltalk, the entire role of the Controller object was for accepting user input and updating the views and models. Interactions today are more complex, and they cause bulky code in the view controller.

Interactions often include an initial user input (like a button press), optional additional user input (“Are you sure you want to X?”), and then some activity, like a network request or state change. The entire lifecycle of that operation can be wrapped up inside the Interaction Object. The example below creates the interaction object when the button is tapped, but adding the Interaction Object as the target of an action, like [button addTarget:self.followUserInteraction action:@selector(follow)] is also good.

@implementation SKProfileViewController

- (void)followButtonTapped:(id)sender {
    self.followUserInteraction = [[SKFollowUserInteraction alloc] initWithUserToFollow:self.user delegate:self];
    [self.followUserInteraction follow];
}

- (void)interactionCompleted:(SKFollowUserInteraction *)interaction {
    [self.binding updateView];
}

//...

@end

@implementation SKFollowUserInteraction : NSObject <UIAlertViewDelegate>

- (instancetype)initWithUserToFollow:user delegate:(id<InteractionDelegate>)delegate {
    self = [super init];
    if !(self) return nil;
    _user = user;
    _delegate = delegate;
    return self;
}

- (void)follow {
    [[[UIAlertView alloc] initWithTitle:nil
                                message:@"Are you sure you want to follow this user?"
                               delegate:self
                      cancelButtonTitle:@"Cancel"
                      otherButtonTitles:@"Follow", nil] show];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if  ([alertView buttonTitleAtIndex:buttonIndex] isEqual:@"Follow"]) {
        [self.user.APIGateway followWithCompletionBlock:^{
            [self.delegate interactionCompleted:self];
        }];
    }
}

@end

The old style of alert view and action sheet delegates make this pattern more apparent, but it works just as well with the new iOS 8 UIAlertController APIs.

Keyboard Manager

Updating the view after the keyboard state changes is another concern that is classically stuck in the view controller, but this responsibility can easily be shifted in a Keyboard Manager. There are implementations of this pattern designed to work in every case, but again, if that’s overkill, don’t be afraid to write your own quick version of this.

@implementation SKNewPostKeyboardManager : NSObject

- (instancetype)initWithTableView:(UITableView *)tableView {
    self = [super init];
    if (!self) return nil;
    _tableView = tableView;
    return self;
}

- (void)beginObservingKeyboard {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
}

- (void)endObservingKeyboard {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidHideNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
}

- (void)keyboardWillShow:(NSNotification *)note {
    CGRect keyboardRect = [[note.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(self.tableView.contentInset.top, 0.0f, CGRectGetHeight(keyboardRect), 0.0f);
    self.tableView.contentInset = contentInsets;
    self.tableView.scrollIndicatorInsets = contentInsets;
}

- (void)keyboardDidHide:(NSNotification *)note {
    UIEdgeInsets contentInset = UIEdgeInsetsMake(self.tableView.contentInset.top, 0.0f, self.oldBottomContentInset, 0.0f);
    self.tableView.contentInset = contentInset;
    self.tableView.scrollIndicatorInsets = contentInset;
}

@end

You can call -beginObservingKeyboard and -endObservingKeyboard from -viewDidAppear and -viewWillDisappear or wherever’s appropriate.

Navigator

Navigating from screen to screen is normally done with a call to -pushViewController:animated:. As these transitions get more complicated, you can delegate this task to a Navigator object. Especially in a universal iPhone/iPad app, navigation needs to change depending on what size class your app is currently running in.

@protocol SKUserNavigator <NSObject>

- (void)navigateToFollowersForUser:(SKUser *)user;

@end

@implementation SKiPhoneUserNavigator : NSObject<SKUserNavigator>

- (instancetype)initWithNavigationController:(UINavigationController *)navigationController {
    self = [super init];
    if (!self) return nil;
    _navigationController = navigationController;
    return self;
}

- (void)navigateToFollowersForUser:(SKUser *)user {
    SKFollowerListViewController *followerList = [[SKFollowerListViewController alloc] initWithUser:user];
    [self.navigationController pushViewController:followerList animated:YES];
}

@end

@implementation SKiPadUserNavigator : NSObject<SKUserNavigator>

- (instancetype)initWithUserViewController:(SKUserViewController *)userViewController {
    self = [super init];
    if (!self) return nil;
    _userViewController = userViewController;
    return self;
}

- (void)navigateToFollowersForUser:(SKUser *)user {
    SKFollowerListViewController *followerList = [[SKFollowerListViewController alloc] initWithUser:user];
    self.userViewController.supplementalViewController = followerList;
}

This highlights one of the benefits to using lots of small objects instead of one big object. They can be changed, rewritten, and replaced very quickly. Instead of shameful conditional code all over your view controller, you can just set self.navigator to [SKiPadUserNavigator new] when on the iPad, and it will respond to the same -navigateToFollowersForUser: method. Tell, don’t ask!

Wrapping up

Historically, Apple’s SDKs only contain the bare minimum of components, and those APIs push you towards Massive View Controller. By tracking down the responsibilities of your view controllers, separating the abstractions out, and creating true single-responsibility objects, we can begin to reign those gnarly classes in and make them managable again.

Sites like Stack Overflow naturally fall into the groove of giving quick answers to common problems. Take, for example, this question, with answers containing code snippets removed from any method, or worse, answers with code injected right into the app delegate. This code shows you how to do the thing you’re trying to do, but doesn’t show you the bigger picture. Where does this stuff go? How does it talk to other components?

In this post, I hope to describe how a common subsystem of an app, such as push notifications, might be architected. It’s an object-oriented architecture, and we will talk about interfaces more and implementations less.

Our requirements are pretty straightforward:

  • Handle token registration

  • Forward push notifications recieved while backgrounded to a router object, so that the app can configure its screens properly

  • Show a toast notification for notifications received while the app is foregrounded

  • Allow any object (such as a conversation view controller) to supress the toast notification

  • Allow any object to be informed when a push notification is received, so it can execute any releveant code, such as animating in new messages

The App Delegate

Ah, my old nemesis, the app delegate. Apple uses this pattern as a central point to get information into our app. Notably, methods like - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken encourage developers to put the code right into the app delegate, quickly bloating it. We should dispatch to another object immediately. This will separate our intent from our implementation, and make the resulting code easier to read.

The Push Center

We need a central object to store state (such as which objects want to be able to suppress notifications) and to make decisions about how to handle push notifications. That object, RGPushCenter, will be a singleton. Singletons are bad, and if our object were only accessed from the app delegate, it could easily just be a property on the app delegate. However, it also needs to be accessed from elsewhere in the app (other objects need to tell it to suppress notifications), so global access is required.

There are a few things we can do to mitigate the damage a singleton can do. Primarily, our singleton will have only one point of access, which is the +sharedCenter class method. Having lots of class methods makes it hard to have state in your object, which makes it hard to refactor.

The push center is the home for code like push notification registration. If you’re tempted to just leave this code (it’s only one line!) in the app delegate, consider the complexity that might be added. For example, while I was writing this code, I learned that iOS 8 handles push notification registration differently. Because the code was hidden in the push center, I was able to easily change it, leaving the app delegate none the wiser.

- (void)registerForRemoteNotifications {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
    {
        [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
    else
#endif
    {
        UIRemoteNotificationType types = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert;
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:types];
    }
}

This way, the code behaves correctly for iOS 7 and 8, in Xcodes 5 and 6. Adding this to the app delegate would only serve to confuse the reader (“What is this #define for?”, “What happened in iOS 8?”, etc). Hiding things at the right level of abstraction makes it easier to understand then code when you read it later.

We should always be dispatching immediately to our push center object, like so:

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken {
    [[RGPushCenter sharedCenter] didRegisterForRemoteNotificationsWithToken:deviceToken];
}  

Inside this method, we have to convert our NSData object to an NSString, and then register it to the API. You might be tempted to use a C function to convert the data to a string, but let’s initialize a special object for it.

The Push Token

RGPushToken *pushToken = [[RGPushToken alloc] initWithTokenData:token];  

It might seem like overkill to allocate memory for a whole object for our push token, but allocation is pretty cheap, all things considered. Further, once we have an object, it’s very easy to add a simple message like [pushToken registerWithAPI] to perform the API call to the server. The RGPushToken class now nicely encapsulates the NSData to NSString conversion as well as the network request, leaving the push center dumber and better off for it.

Inside the push token class, we can make a one line call to our HTTP session manager:

- (void)registerWithGeniusAPI {
    [[RGAPI manager] POST:@"/account/devices" parameters:self.POSTParameters success:nil failure:nil];
}

Because this is its own class, the -POSTparameters can be wrapped up into their own method as well. At each layer of abstraction, we push down the complexity into another abstraction until the thing is so simple that it can be understood by glancing at it.

The Push Notification

In some cases, we don’t want to dispatch immediately to the push center, but make a decision first. When receiving a push notification when the app is running, we need to make a decision based on whether or not it’s backgrounded.

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    if (application.applicationState == UIApplicationStateActive) {
        [[RGPushCenter sharedCenter] presentToastWithUserInfo:userInfo];
    } else {
        [[RGPushCenter sharedCenter] performRoutingForNotificationWithUserInfo:userInfo];
    }
}

This is the right place for this decision for a number of reasons. We don’t want the push center to have to know about different ways that the same data comes in; in fact, if it were up to me, this would probably be two delegate methods. We also already have access to the application object, and we can quickly query it’s state to send more intelligible messages to the push center, leaving it much cleaner.

What do we do with the notification dictionary once it comes into our push center? If you guessed “make an object!”, you’d be correct.

RGPushNotification *notification = [[RGPushNotification alloc] initWithDictionary:userInfo];  

Object-oriented programming is all about encapsulation. What are we encapsulating here? Whether or not the push notification is silent, the type of notification (“new message!”, “update the unread count!”), and where the app should go when the notification is activated, which is stored in the routing URL. This also gives us the flexiblity to transform or expose more as needed in the future, and localize those changes to only this class. Once we have our notification object, we can grab its routing URL and pass it a router object that handles configuring our view controllers:

[[RGNavigationManager sharedManager] handleOpenURL:notification.routingURL];  

This code could access the raw data from the userInfo dictionary, but we’d end up with stringly-typed NSURL conversion in our push center. [NSURL urlWithString:userInfo[@"genius"][@"url"]] is a lot less elegant and truthfully, we just don’t care where the URL string is or how it’s converted into an NSURL. Offload that responsibility to another class!

The Delegates

The only complex component remaining is the preventing the toast from being shown if any other objects wish to suppress it. We need to be able to ask other objects that care whether they want to prevent the toast from happening, but we don’t want to be too tightly coupled to the other objects. Of the common communication patterns, most of them (NSNotifications, KVO, target-action) can’t return data. Blocks are an interesting solution, but would require some kind of complex token-based system to deregister a block, so we will use delegates for simplicity.

Having just one delegate can be dangerous with a singleton, since another object can be take away your delegateness at any point without telling you. For safety’s sake, let’s keep multiple delegates. Order doesn’t matter, so we can use a set-like construct, but we want to it to hold a weak (not strong or unsafe) reference to each of the items in it. Forunately, the Foundation SDK gives us [NSHashTable weakObjectsHashTable], which is essentially a set with weak references, exactly what we’re interested in.

From there, we need a way to register and deregister objects as delegates.

- (void)addDelegate:(id)delegate;  
- (void)removeDelegate:(id)delegate;  

We can now write a method to check if any of the delegates want to suppress the notification.

- (BOOL)shouldSuppressNotification:(RGPushNotification *)notification {
    for (id<RGPushCenterDelegate> delegate in self.delegates) {
        if ([delegate pushCenter:self shouldSuppressNotification:notification]) {
            return YES;
        }
    }
    return NO;
}

Finally, we’ll create an NSNotification called RGPushNotificationWasReceived, which observers can listen to and perform their own actions. We already have delegates, why include a separate communication pattern here? The reason is simple. We want to keep the concept of suppressing a notification separate and decoupled from the concept of listening for notifications. Some objects will just need to know that a notification is recieved (such as the conversation list, which needs to update, but not suppress the toast). Notifications also don’t really require any knowledge of the push center class, only the push notification object, which is another reason to keep them separate.

This writeup doesn’t provide code that you can copy and paste into your own project, but it’s not particularly complex either (the actual push center is only 130 lines of code). I hope that it provides you with a framework for thinking about how to architect features like this in future.

I’m reading Kent Beck’s Smalltalk Best Practice Patterns and learning a lot about how control structures work in what’s probably the purest object-oriented language. For example, if isn’t used to manage conditionals. In Smalltalk, since all things are objects, including booleans, you can just send the message -ifTrue: and -ifFalse:, with blocks, to the True object.

Let’s try that out with Objective-C:

@implementation NSNumber (IfTrue)

- (BOOL)isBoolean {  
	return [@([self objCType]) isEqualToString:@(@encode(BOOL))];  
}

- (id)ifTrue:(void (^)())onTrue {  
	if ([self isBoolean]) {  
		if ([self boolValue]) {  
			if (onTrue) onTrue();  
		} else {  
			return self;  
		}  
	}  
	return nil;  
}

- (id)ifFalse:(void (^)())onFalse {  
	if ([self isBoolean]) {  
		if ([self boolValue]) {  
			return self;  
		} else {  
			if (onFalse) onFalse();  
		}  
	}  
	return nil;  
}

@end  

When the case is not satisfied (i.e., the NSNumber is @YES, but we messaged -ifFalse: ), we return self, so that the messages can be chained, like so:

[[@YES ifTrue:^{  
	NSLog(@"this code block is entered!");  
}] ifFalse:^{  
	NSLog(@"this one is not");  
}];  

Pretty elegant! Smalltalk also allows us to ask an object to execute block if it’s nil. Hm. This actually presents a problem for us, since nil in Objective-C eats all messages and returns nil again. Our message would be swallowed and our block wouldn’t get executed. Fortunately, the runtime is here to save us! Let’s #import <objc/runtime.h>. Grab the whiskey.

Bill Bumgarner teaches us how to create our own nil object and tell the runtime that we’d like to use it instead of the built in nil. First, let’s make STNil. It eats all messages, just like good old regular nil :

@implementation STNil

+ (BOOL)resolveClassMethod:(SEL)sel { return NO; }

+ (BOOL)resolveInstanceMethod:(SEL)sel { return NO; }

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {  
	return [NSObject instanceMethodSignatureForSelector: @selector(description)];  
}

- (void)forwardInvocation:(NSInvocation *)anInvocation { }

- (void)ifNil:(void (^)())onNil {  
	if (onNil) onNil();  
}

@end  

And let’s add the -ifNil: message to NSObject as a category and make it a no-op:

@implementation NSObject (IfNil)

- (void)ifNil:(void (^)())onNil { }

@end  

And then lets use _objc_setNilReceiver (which is private!) to set STNil as the nil receiver;

extern id _objc_setNilReceiver(id newNilReceiver);

int main(int argc, const char **argv) {  
	@autoreleasepool {  
		id smalltalkyNil = [STNil new];  
		_objc_setNilReceiver(smalltalkyNil);
		
		NSString *nilString = nil;
		
		[nilString ifNil:^{  
			NSLog(@"this object is nil");  
		}];
		
		_objc_setNilReceiver(nil);
		
	}  
	return 0;  
}  

This works! We can now message nil as easily as any other object.

Let’s take it even further. In Ruby on Rails, objects support something called presence. Presence makes truthiness behave in a more useful and consistent way. Nil, empty strings, and empty collections are “not present” (or “blank”), so you can call myArray.blank instead of the more convoluted myArray.count == 0. Let’s bring that stuff over to this new block based model as well.

Let’s put some more stuff on NSObject :

@implementation NSObject (Presence)

- (BOOL)present {  
	return YES;  
}

- (BOOL)blank {  
	return !self.present;  
}

- (void)ifPresent:(void (^)())onPresent {  
	if (self.present && onPresent) onPresent();  
}

- (void)ifBlank:(void (^)())onBlank {  
	if (self.blank && onBlank) onBlank();  
}

@end  

And then, all we have to do create a category on NSArray that overrides present (and optionally forward -ifEmpty: to -ifBlank: ):

@implementation NSArray (Presence)

- (BOOL)present {  
	return !!self.count;  
}

- (void)ifEmpty:(void (^)())onEmpty {  
	[self ifBlank:onEmpty];  
}

@end  

Now, we can call -ifEmpty: exactly as we’d expect to:

[@[] ifEmpty:^{  
	NSLog(@"this array is empty!");  
}];  

Who knew Smalltalk could be so much fun?

Cells can exist because their membranes define what is in and out and determine what can pass.

Love this analogy of objects from Domain-Driven Design.

Update: This post was written in May 2014, before the release of Swift. Swift adds enumerations that can have functions called on them, making the techniques in this post unnecessary when working in Swift. The titular “enumerations” refer to C style enumerations, which are nothing more than some type sugar around primitive integers. If you’re still working in Objective-C, and you want enumerations that can hold data and respond to messages, read on.

In the last post, we talked about wrapping simple Foundation types in their own class, so that the type checker can let you know that you’re passing the wrong kind of string to a method. We can extend this idea of value objects further.

I’m quickly falling in love with this pattern: replacing enumerations with polymorphic objects. In the last post, it was important to wrap a value, but here, there’s no value, just a kind. Normally, to represent a kind of thing, we create an enumeration, which is just an integer with a little bit of type sugar.

Where do enumerations fall short? Let’s look at some terrible code I wrote for an old app.

+ (NSString*) stringForType:(PodcastListType)listType {
    if (listType == unplayedType) {
        return @"Unplayed";
    } else if (listType == favoriteType) {
        return @"Favorites";
    } else if (listType == archiveType) {
        return @"Archive";
    } else if (listType == trashType) {
        return @"Trash";
    } else if (listType == downloadsType) {
        return @"Downloads";
    } else if (listType == recentlyAddedType) {
        return @"Recents";
    }
    return @"";
}

+ (PodcastListType) listTypeForString:(NSString*)name {
    if ([name isEqualToString:@"Unplayed"]) {
        return unplayedType;
    } else if ([name isEqualToString:@"Favorites"]) {
        return favoriteType;
    } else if ([name isEqualToString:@"Archive"]) {
        return archiveType;
    } else if ([name isEqualToString:@"Downloaded"]) {
        return downloadsType;
    } else if ([name isEqualToString:@"Recently Posted"]) {
        return recentlyAddedType;
    }
    return unplayedType;
}

This code is bad for several reasons.

  1. The enumeration can’t be messaged, so any code or behavior that should live with the enumeration now hangs out wherever the code needs to be used.

  2. Everything in iOS revolves around the view controller, so the “easy” place to put this code is in a class method on the view controller (which is what I did!). This makes your view controller longer and cruftier. The reader of the view controller class doesn’t care how list types are converted into display strings.

  3. It’s not immediately obvious if cases aren’t covered, especially as the number of cases increases. The astute reader will note that +listTypeForString: doesn’t include the “Trash” case, which was an actual mistake I made writing this code. (Creating C functions can be a solution to the view controller problem, but the cases are still easy to miss.)

  4. I can call [MyClass stringForType:2] with no compiler warning. The compiler will warn if I send a different typedef, but not if I send a plain old integer.

It’s not called Enumerative-C! Let’s make some objects.

SKPodcastListType.h:

@interface SKPodcastListType : NSObject <NSCopying>

- (instancetype)initWithString:(NSString*)string; //probably from the server

@property (nonatomic, readonly) NSString *displayName;

@end

@interface SKUnplayedPodcastListType : SKPodcastListType @end

@interface SKFavoritesPodcastListType : SKPodcastListType @end

//...

And SKPodcastListType.m :

@implementation SKPodcastListType

- (instancetype)initWithString:(NSString *)string {
    if ([string isEqualToString:@"unplayed"]) {
        return [SKUnplayedPodcastListType new];
    }
    if ([string isEqualToString:@"favorites"]) {
        return [SKFavoritesPodcastListType new];
    }
    return nil;
}

- (NSString *)displayName {
    return @"";
}

- (NSUInteger)hash {
    return [NSStringFromClass(self.class) hash];
}

- (BOOL)isEqual:(id)object {
    return [self isMemberOfClass:[object class]];
}

- (id)copyWithZone:(NSZone *)zone {
    return self;
}

@end

@implementation SKUnplayedPodcastListType

- (NSString *)displayName {
    return @"Unplayed";
}

@end

@implementation SKFavoritesPodcastListType

- (NSString *)displayName {
    return @"Favorites";
}

@end

//...

Now, while this is more lines of code, the code is now out of the way. It now lives in the right place. My view controller no longer knows the possible types of podcast lists and is shorter and simpler for it. Any additional behavior can be put right on these classes, instead of adding more class methods, and if you make a new PodcastListType, it’ll be immediately obvious if you haven’t implemented the right methods.

The compiler will also now check our work to make sure we’re passing around SKPodcastListType objects, instead of accidentally passing around numbers for enumerations.

Note that it doesn’t matter which SKUnplayedPodcastListType object you have. It doesn’t hold any data except for its type. This means our -isEqual: method just checks to make sure the classes are the same. And -copyWithZone: can just return itself, since it’s immutable, which feels very elegant. You can get even more crazy and make each subtype be its own singleton, so you could just compare firstListType == secondListType. You could metaprogram the -displayName message to take the class name and remove the “SK” and the “PodcastListType”. The possibilities are limitless.

Value Objects are my new favorite thing. We’re all familiar with Entities. Entities are objects that have an important sense of identity. Like entities, value objects also live in the model layer, but, unlike entities, they don’t have that same sense of identity. A very practical way of looking at it is that value objects don’t get their own row in a database, they usually get represented in a single field of some other object’s row.

Why are value objects so awesome? Two big reasons: first, they have a distinct type; and second, they can give a home to behavior that doesn’t otherwise have a place. Let’s go in a little deeper.

Types

In my last blog post, Tests and Types, I talk about how useful it is to have the computer checking that the right objects are going to the right places. This is a simple extension of that. Darren Hobbs calls it Tiny Types, and it’s a simple class that lets you wrap some existing type (usually a Foundation type like NSString or NSDate) in a class that has its own type. That way, you can never put a FirstName object into a slot for a LastName type.

I made a quick gist with an implementation for Objective-C that implements -isEqual:, -description, -compare:, -hash, and NSCopying, which you can find here: https://gist.github.com/khanlou/170cb132c90c86f68e72. From, there, it’s trivial to make subclasses for your value objects. For example:

SKFirstName.h :

@interface SKFirstName : SKValueObject

- (instancetype)initWithString:(NSString*)firstName;

@property (nonatomic, readonly) NSString *firstName;

@end

SKFirstName.m :

@implementation SKFirstName

- (instancetype)initWithString:(NSString *)firstName {
    return [self initWithBackingObject:firstName];
}

- (NSString *)firstName {
    return self.backingObject;
}

@end  

That’s all the code you need for a new tiny type! Now a FirstName object will never accidentally go into the slot made for a ServerHostname.

Behavior

The other great thing is that behavior around this name now has a great home. Instead of doing validation on the Person entity, we can just add it as a method here, optionally returning nil in the initializer if we get malformed input.

- (BOOL)isValid {  
	return [self.firstName matchesRegex:@"^[A-Z][a-zA-Z]+$"]; //this is a terrible regex for a name  
}  

Coupling behavior with state is the whole point of Object-Oriented Programming!

- (NSString *)slug {  
	return [self.firstName lowercaseString]; //probably also want to convert spaces and apostrophes to hyphens  
}  

In the next post, I’ll talk about how we can use the same concept to make way better enumerations.

The programs we write are complex beasts. Even the smallest changes can have ripple effects into unexpected parts of our apps. And of course since we’re programmers, we’ve worked towards programmatic solutions to this problem. To help us analyze the effects of changes to our code, we write a second program to check our first program. This second program makes assertions and checks expectations about the state of the program at any given point.

If you’re checking the state of the first program while its running, you’re talking about executing a test suite.

If you’re checking the state of the source code of the first program, you’re talking about static type checking.

A static type system is one where each object is given a type. The type has information about what messages objects of that type can respond to. Those messages, in turn, have slots in them for parameters. These slots are have the shape of other types, so that only objects of those types can fit in those slots. They let you set an expectation. “I am a method. I want these kinds of objects, which will in turn respond to these messages. When I’m done, I’m going to return this kind of object.”

Of course, you can circumvent this whole system by using prodigious casting or by using the id type for everything. Using a so-called “untyped” system, like Ruby or the id subset in Objective-C, is purposefully crippling yourself. Instead of pretending that there are no types in such a system, we need to realize that we’re actually shoehorning every semantic type into one.

Types are useful, because the computer, dozens of times per minute, can assert that your code is meeting the expectations of the code around it. There’s a reason we call it type safety. You can also get this with a comprehensive test suite, but that means painstakingly writing hundreds of tests while you write code. The beauty of types when compared with tests is that, as long as you’re using semantic types to model your app’s universe, you’re going to get all of that type-checking for $free.99.

I’m not saying that tests aren’t tremendously valuable. Type-checking, generally speaking, can’t verify the behavior of your methods. But the rote tests in your system, the boring ones, the ones you hate writing, these should be automatically checked by the computer, with no input from you. To get even more benefit out of type checking, wrap even the simplest value objects (like NSString ) in a type: this pattern is called Tiny Types.

Tests and types reveal their similarities in other ways too. A Massive View Controller is completely untestable and doesn’t gain much from type checking either. A better architecture, which generally involves more objects (and more types!) with less logic each, will be both way more testable and way more type-checkable.

We write tests because programs never stay the same. Requirements change, new features are added, and old code must be updated to more closely match the domain. We use refactoring to make sure our domain and our code stay aligned. We don’t write tests to assure that our code works right now, we write them to assert our that our new code is isomorphic to our old code.

Types are useful in the exact same way. The moment you change a method’s signature, the compiler immediately points out where you were using the old methods’s name, and lets you fix it. As long as you’re refactoring in small composable chunks, you’ll immediately know what you’ve broken. Type checking isn’t a panacea: an app that compiles with no warnings isn’t a necessarily going to behave perfectly, but that’s true of a project with all tests passing as well.

Types and tests are very similar, both leveraging the power of computers to do lots of mechanical tasks quickly. If you’re not taking advantage of both tests and types to wrote stronger, safer code, you’ll never know what bugs you’re leaving in your wake.

I’m slowly starting to appreciate the role of metaprogramming in Objective-C and how to do it in a compiler-safe manner. With dynamic methods, there are are two cases: you can either send a message that the receiver doesn’t necessarily know about at compile-time, or you can receive a message that the sender might know about at compile time.

Dynamic Method Resolution

Receiving a message that you didn’t publicize at compile-time is called dynamic method resolution. Rails uses this to great effect with dynamic finders. They let you call User.find_by_email('soroush@khanlou.com'). That message will be caught at run-time in the User class and dynamically return the result of User.find_by('email', 'soroush@khanlou.com'). This would automatically work for every property you have on your model object. Strictly speaking, this is possible in Objective-C (I show how exactly in an article about dynamic Objective-C on the Rap Genius tech blog). However, there are a number of things in Objective-C that prevent us from writing code like this, including

  1. ARC, which requires the method signature of every method to be known at compile-time, so that clang can insert retains and releases at the right time

  2. compiler warnings, which assure that the methods we are calling are actually publicized (in a header) and that the methods that we publicize actually exist

Dynamic Message Construction

On the other hand, you can have a method that the sender builds at run-time but the receiver has already defined at compile-time. This is called dynamic message construction, and, crucially, the compiler won’t stand in our way for this technique.

You can see dynamic message construction at play in Core Data’s validators. Core Data will dynamically check for and call methods of the form validate:error:. For example, if you had a “name” property, Core Data would dynamically call -(BOOL)validateName:(id *)ioValue error:(NSError **)outError, giving you the power to validate it, return an error describing why it’s not valid, or even change the pointer to the object its asking you to validate. This could all be rolled up into one big method called -validateValue:forKey:withError:, but that could grow to be a pretty big method! You’d probably want to separate each of the validations like so:

- (void)validateValue:(id *)value forKey:(NSString *)key withError:(NSError *)error {        
    if ([key isEqualToString:@"name"]) {
       [self validateName:value error:outError]
    }
    if ([key isEqualToString:@"email"]) {
        [self validateEmail:value error:outError]
    }
}

A new refactoring

To that end, I present a new refactoring strategy: Replace Conditional With Message Construction.

Martin Fowler’s book, Refactoring, in addition to outlining the intention behind refactoring and the methodology for doing it safely, also includes a catalog of refactoring strategies (including Replace Conditional With Polymorphism, which is what inspired this blog post).

Core Data shows us how this is used in the model layer, but let’s look at an example in the view layer as well.

In the Rap Genius app, we use -configureCell:atIndexPath: when setting up cells to separate the creation of the cell from its configuration. If a table view has many types of objects represented in its rows, we want to break down our configuration method even further:

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    id object = [dataSource objectAtIndexPath:indexPath];

    if ([object isKindOfClass:[RGArtist class]]) {
        [self configureCell:cell withArtist:object];
    } else if ([object isKindOfClass:[RGSong class]]) {
        [self configureCell:cell withSong:object];
    }
}

As this gets more and more complex, it is a ripe place to use this refactoring.

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    id object = [dataSource objectAtIndexPath:indexPath];
    SEL configurationSelector = [inflector selectorWithPrefix:@"configureCell:with" propertyName:[[object class] modelName] suffix:@":"];

    if ([self respondsToSelector:configurationSelector]) {
        [self performSelector:configurationSelector withObject:cell withObject:object];
    } else {
        [self configureCell:cell withObject:object];
    }
}

This code will now dynamically get the modelName of your model (such as “Song”), and call configureCell:withSong: or configureCell:withArtist: as appropriate.

The great thing about this pattern is that it helps separate your code into very logical units without having to include a giant conditional that is brittle and prone to change. It truly shines in a framework, where you may not know what objects are going to be represented in your table view, and it becomes crucial to call their configuration methods dynamically.