May 20, 2015

Networking, more like not working

The question that vexes me the most in a new iOS project is the question of how to structure networking code.

Networking code is tough for three reasons. The first two reasons are related. First, it's singular. There's only one internet, you usually have one base URL for your API, and you want to deduplicate as many of the shared headers and URLs and access tokens as possible. Second, since you'll need to access the network from all over, your networking code will need to be globally available. It's just begging to be turned into a singleton.

The final problem is that making a request is a one-time process. It isn't easily represented well in a long-lived object. While a network request maps well to a method on an object, it doesn't easily graduate to a fully-fledged object.

Instant Cocoa itself faces this problem. It's currently built on AFNetworking, but as the Instant Cocoa progresses, using a dedicated library for networking seems more and more extraneous. Especially in a library that I hope other developers will use, I want to keep dependencies to a minimum.

There are a few different approaches that are commonly used, and I'll enumerate them from least elegant to most.

Raw Access

If you're accessing your AFHTTPRequestOperationManager directly, or using NSURLRequest and NSURLSession objects without any abstraction around them, this is what I'd call raw access.

[manager POST:@"https://api.khanlou.com/users/login" parameters:@{ @"username": username, @"password": password } success:^{ ... } failure:^{ ... }];

There's an advantage to the ease and directness of this method, but it comes with some cost. There's no way to name or categorize the API calls. The API is totallly untyped. You can't hide away an logic that needs to be associated with the request, such as saving an auth token or sending notifications to update the UI. You'll also be duplicating code for base URLs, common headers, and the like. Also, tying your code directly to AFNetworking will make it hard to change if you ever decide to move away from such a framework.

For early-stage projects this approach will work fine, but those projects usually level up to late-stage projects, and by that point, you're going to need some organization around your network requests.

Singletons

The next, slightly more abstract, slightly more indirect way to perform your network requests is with a singleton. The interface for such a pattern might look like:

[SKAPI loginWithUsername:username password:password success:^{ ... } failure:^{ ... }];

This is a little bit better than raw access. You can name your endpoints, you can assign types to their parameters, and you can couple logic with the request. It's a decent solution, but it's fundamentally not object-oriented. You'll notice that this is how the Swift version of AFNetworking, Alamofire, works:

Alamofire.request(.GET, "http://httpbin.org/get")

Here, Alamofire is more of a namespace around the request, same as SKAPI above. What you're essentially doing is accessing a global function via that namespace. It works, since API requests fundamentally are just functions (they're fired once, take parameters, return a result), but it still feels weird to try to shoehorn this into a class. There's no state and no sense of self. This is made obvious by the fact that it doesn't matter that I made these class methods rather than instance methods.

Resource-centric

REST tries to map each remote path to an object representation. For example, users/1234 represents a user, and users/1234/follow represents an action being done to that user. If you've got a local representation of that user in the form of a User model, it makes sense to send a message to that model and have it perform the action, like:

[user followWithCompletionBlock:^{ ... }];

This is nice because is slightly more object-oriented, in that you're sending a message to an entity. It maps to REST really nicely. It helps organize the requests in a nice way. You can also intuit things about the endpoint and parameters from innards of the model.

This is how Instant Cocoa's resource gateways work. It works sort of like Active Record (the pattern), but designed to work asynchronously.

There are flaws, though. It's only an interface; one of these other patterns has to actually perform the request. Also, the model probably shouldn't know about how it's connected to its remote representation, given that it probably already handles serialization, conversion for display, and validation logic. Finally, it can't represent singleton resources very well (like /search). Should singleton resources be singleton objects? It's not clear.

Enumerating requests

Ash Furrow's Moya library is another, Swiftier way of handling requests. I don't have a lot of experience with Swift, but I still wanted to take a look at it for this roundup.

enum GitHub {
    case Zen
    // ...
}

extension GitHub : MoyaPath {
    var path: String {
        switch self {
        case .Zen:
            return "/zen"
        }
        // ...
    }
}

extension GitHub : MoyaTarget {
    var baseURL: NSURL { return NSURL(string: "https://api.github.com") }
    // ...
}

You use it by creating a Swift enum with all of your requests, and then extending that enum with protocols that tell Moya what path to use, what base URL to use, and so on. Then you can pass your enum value into a MoyaProvider to perform a request, and it can get any values it needs from methods on the enumeration itself.

This approach is a laudable for a few reasons. It feels pretty idiomatic to Swift, each endpoint has its own type (which is good!), and each endpoint can have its own well-typed parameters, since enums in Swift can take parameters.

The flaws of Moya are mostly in the organization. Moya requires that all of your API paths be in the same big switch. Adding a new API endpoint requires creating a new option in the enumeration, and adding options to all of the switches that need data for that endpoint. While sometimes it can be useful to see all of your endpoints's paths in one place, I'd rather see all of the data related to one endpoint clumped together instead. In other words, I want something more like a struct for each endpoint rather than an enum for all of them.

One object per request

The last solution we're going to cover is making one object for every request. It can be initialized with whatever parameters it needs, knows how to fire itself, and has an internal state machine so that objects can know if the request is midflight or completed or any other state. AFNetworking's NSOperation objects function like this, though you usually don't have to interact with them directly.

[[SKLoginRequest alloc] initWithDelegate:self username:username password:password];

The primary problem with objects like this is that they have a very specific lifecycle. You can't discard them early, because the object will be deallocated and the request won't complete, and you can't keep them around after they're finished, since they're no good anymore (they're in the Completed state and can't — and shouldn't! — be reset). You have to trash them at just the right time, and that's annoying.

There's also a lot of boilerplate around them; you usually only need to vary the path and the parameters. You might be tempted to use inheritance with the Template Method pattern to add shared behavior to these request objects, but that temptation is worth resisting.

The sweet spot

Each of these approaches has its own flaws. Next week, I'll bring together some ideas from previous posts (Prefer Composition to Inheritance, Nestable, and Graduation) to propose something that's flexible, well-architected, and satisfactory from an object-oriented perspective.

May 12, 2015

Throw it all away

Louis CK came onto the scene a few years ago, and he’s been tearing it up ever since. There’s one particular bit of his that has a message that I’ve been feeling the last few months. He remembers being a shitty comedian for 15 years, and in a moment of crisis, he listens to a CD of George Carlin’s comedy:

On the CD they ask him, how do you write all this material? And he says, each year I decide I’d be working on that year’s special, then I’d do that special, then I would throw away that material and start again with nothing. And I thought, that’s crazy, how do you throw away? It took me fifteen years to build this shitty hour, and if I throw it away, I got nothing.

Your ideas feel precious to you when you have them. My ideas certainly have. And that can lead to a fear of publishing them, of acting on them. For me, I fear that if I let go of one idea or another, I’ll never have a new one again.

The ideas in Instant Cocoa have felt precious. Even though those ideas were intended to be open-sourced, it took a year and a half to do so. Most of Instant Cocoa was done by last spring. I’m not sure why it took so long to release. But if I had to guess, I’d say my fear of it ending overrided my desire to see it in the world.

The post ideas for this very blog have felt precious. I’ve got a list of potential blog post topics, and I worry: what am I gonna do when I run out? And I can’t even lean on performing the same material over and over again, like Louis CK. Once I publish something here, it’s out, and it wouldn’t make sense to publish it again.

I’ve been posting on this blog weekly all year, with the exception of March, when I was working on my Úll talk and releasing Instant Cocoa. I’ve published 15 posts since January. It feels like a breakneck speed. If you asked me last year how long I could sustain such a pace, I think I would have answered, “maybe 4 weeks?”.

But I’m still going. And, somehow, even though back in December the list of potential topics had as many items on it as I’ve posted already, it’s still more or less the same length. I can’t explain it.

The act of publishing solidifies the idea into being. Like the Zeigarnik effect, it frees up space in your brain to find the next thing. The next thing will be built on the previous thing, and it’ll be stronger for it. There’s a quote that I can never find about how “the act of writing shows us how bad our thinking is”. Once we start putting pen to paper, the flaws in our reasoning bubble to the top, and we’re forced to deal with them. Tending to those inconsistencies clarifies the missing parts of the idea and shows what ideas should come next.

And as for Instant Cocoa, far from feeling like I’ll never be able to come up with anything else new for it, it now feels like I’m on the verge of a greater thing. I don’t want to call it an MVP, because another metaphor is more appropriate. It feels like an EP, and now I want to spend the time to turn it into an LP.

More ideas will come. Tons of ink has been spilled about how only execution matters, and your ideas are worthless. But rather than using that fact to tear them down, I want to build them up. Your ideas might not be important, but your ability to generate them is. One idea will never change the world; a series of successive ideas built on each other will. You’ll get farther than anyone else, since by fulfilling your ideas you’ll gain access to new parts of knowledge that no one else can. Get your stuff out there.

May 4, 2015

Graduation

Everyone struggles with keeping classes small. Classes get big because they accumulate methods and their methods accumulate lines. Once a method gets too long, sometimes it has to graduate to its own class.

This move from method to object is sometimes awkward, since we’re translating from a verb to a noun. It’s necessary, though. This technique is a great one to hide complexity, and it can reveal abstractions that weren’t apparent before.

Now, the functional programming nerds have it easier here; any extraction of a function is just going to be another function, with more or less the same lines of code. This is one of the costs of OOP, but as we’ll see, this transition from method to object is very straightforward. We can do it in three simple steps.

Overcoming the hurdle of this translation will enable us to ruthlessly refactor, finding an elegance in our code that we couldn’t see before. We're trying to maximize two values here:

  1. Short methods are better than long methods, and
  2. Methods with fewer parameters are better than methods with more parameters.

As an example, we’ll take push notification token registration code. I’ve used some of the same code as my post Anatomy of a Feature: Push Notifications. Let’s start with our method:

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSString *trimmedString = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    tokenAsString = [trimmedString stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSDictionary *POSTParameters = @{@"device": @{
                                             @"token": tokenAsString,
                                             @"app_id": [[NSBundle mainBundle] bundleIdentifier],
                                             @"app_version": [[NSBundle mainBundle] bundleVersion],
                                             },
                                     };
    [SKRequestManager POST:@"/account/devices" parameters:POSTParameters success:nil failure:nil];
}

This is a messy and complex method, but at least everything has a good name. Let's try and move it to its own class. We need a name, even a bad one, for the class. Let's start with SKPushTokenSender.

We're ready to move to the first step of our refactoring: move the method wholesale into our new class. Do this without changing any code in the method. If we need anything from the outside world, we can pass it in as a parameter to our new method in the new class.

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    [[SKPushTokenSender new] sendToken:deviceToken];
}

@interface SKPushTokenSender

- (void)sendToken:(NSData *)deviceToken;

@end

@implementation SKPushTokenSender

- (void)sendToken:(NSData *)deviceToken {
    NSString *trimmedString = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    tokenAsString = [trimmedString stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSDictionary *POSTParameters = @{@"device": @{
                                             @"token": tokenAsString,
                                             @"app_id": [[NSBundle mainBundle] bundleIdentifier],
                                             @"app_version": [[NSBundle mainBundle] bundleVersion],
                                             },
                                     };
    [SKRequestManager POST:@"/account/devices" parameters:POSTParameters success:nil failure:nil];
}

@end

We can now verify that this does the same thing as before with our tests. This class is actually pretty good already! It does one thing, and it does a good job. It's still internally pretty ugly though, so let's continue to refactor it. We're transitioning from method to object, and we're in an unwieldy middle state.

To get out of this middle state, we perform the second step of this refactoring: method parameters become initializer parameters. Let's move the deviceToken to an initializer.

@interface SKPushTokenSender

- (instancetype)initWithDeviceToken:(NSData *)deviceToken

@property (nonatomic, readonly) NSData *deviceToken;

- (void)sendToken;

@end

@implementation SKPushTokenSender

- (instancetype)initWithDeviceToken:(NSData *)deviceToken {
    self = [super init];
    if (!self) return nil;
    _deviceToken = deviceToken;
    return self;
}

- (void)sendToken {
    NSString *trimmedString = [[self.deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    tokenAsString = [trimmedString stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSDictionary *POSTParameters = @{@"device": @{
                                             @"token": tokenAsString,
                                             @"app_id": [[NSBundle mainBundle] bundleIdentifier],
                                             @"app_version": [[NSBundle mainBundle] bundleVersion],
                                             },
                                     };
    [SKRequestManager POST:@"/account/devices" parameters:POSTParameters success:nil failure:nil];
}

@end

Changing the interface means we should go back and update the app delegate as well. Once we've done that, we can take a look at what we have. Our method is still messy, which brings us to the third and final step of this refactoring: local variables become instance methods. Let's do this first with tokenAsString:

@implementation SKPushTokenSender

- (instancetype)initWithDeviceToken:(NSData *)deviceToken {
    self = [super init];
    if (!self) return nil;
    _deviceToken = deviceToken;
    return self;
}

- (NSString *)tokenAsString {
    NSString *trimmedString = [[self.deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    return [trimmedString stringByReplacingOccurrencesOfString:@" " withString:@""];
}

- (void)sendToken {
    NSDictionary *POSTParameters = @{@"device": @{
                                             @"token": self.tokenAsString,
                                             @"app_id": [[NSBundle mainBundle] bundleIdentifier],
                                             @"app_version": [[NSBundle mainBundle] bundleVersion],
                                             },
                                     };
    [SKRequestManager POST:@"/account/devices" parameters:POSTParameters success:nil failure:nil];
}

@end

The local variable tokenAsString became a method on our object, and was replaced by self.tokenAsString. A language like Ruby makes this really easy. In Ruby, when inside the scope of an object, methods can be called without the self., meaning that the local variables and instance methods can look exactly the same. So as you move stuff out of your gnarly method, you don't even need to add a self. to make it work. (On the other hand, Ruby makes this really hard. There's no static type checking, so you have to run your code to see if your changes worked? Like an animal?)

We can do the same thing with POSTParameters, and even the characterSet and trimmedString, if we like.

@implementation SKPushTokenSender

- (instancetype)initWithDeviceToken:(NSData *)deviceToken {
    self = [super init];
    if (!self) return nil;
    _deviceToken = deviceToken;
    return self;
}

- (NSCharacterSet *)characterSet {
    return [NSCharacterSet characterSetWithCharactersInString:@"<>"];
}

- (NSString *)trimmedString {
    return [[self.deviceToken description] stringByTrimmingCharactersInSet:self.characterSet];
}

- (NSString *)tokenAsString {
    return [self.trimmedString stringByReplacingOccurrencesOfString:@" " withString:@""];
}

- (NSDictionary *)POSTParameters {
    return @{@"device": @{
                     @"token": self.tokenAsString,
                     @"app_id": [[NSBundle mainBundle] bundleIdentifier],
                     @"app_version": [[NSBundle mainBundle] bundleVersion],
                     },
             };
}

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

@end

We can keep extracting like this until we're satisfied. The class gets continually flattened and methods get continually shortened until it's sufficiently elegant. Any method inside here that's still too long and complex is subject to the same treatment of being hoisted from a method to a bona fide object.

Once we start seeing the final state of the class, we see what its true name should be. Sending is only a thing it does, but its identity is around the token itself. Once we rename the class to SKPushToken, we're done.

April 29, 2015

View Controllers in Cells

There comes a time in every iOS developer’s life when she wants to put a view controller inside of a table view cell. For all the ragging I do on view controllers, they’re a useful tool for wrangling complex views, and it’s easy to imagine cases where you would want to stack them on top of each other. Another common use case is putting collection views inside of table view cells. Ideally, that inner collection view will have its own controller, so that the outer table view controller isn’t polluted by the binding of view and data for each collection view cell.

Because UIKit has lots of little hooks in it, where components talk to other components behind-the-scenes, we need to make sure we use the UIViewController containment APIs for our child view controllers. Things will silently fail or act weird if we don’t.

I’ll be talking mostly about table view and their cells in this post, but everything is generalizable to collection views as well.

To keep things simple, the view controller should be the only content inside the cell. Trying to manage regular views next to a view controller’s view will result in needless complexity. With one view controller and only one view controller in each cell, layout (at the cell level) is as simple as

self.viewController.view.frame = self.contentView.bounds;

And the view controller can handle any layout internal to itself. We can also push height calculations down to the view controller.

There are two approaches: we can either a) have each table cell hold on to a view controller or b) hold the view controllers at the controller level.

A controller for each cell

If we put a view controller in each cell, then we might lazy load it inside the cell.

- (SKContentViewController *)contentViewController {
    if (!_contentViewController) {
        SKViewController *contentViewController = [[SKContentViewController alloc] init];
        self.contentViewController = contentViewController;
    }
    return _contentViewController;
}

Note that we didn’t add the controller’s view as a subview of our cell’s contentView. When it comes time to configure this cell, in -cellForRowAtIndexPath:, we can pass our model to this controller and have it configure itself with the new content. Since these cells are reused, your controller has to be designed to completely reset itself anytime its model is changed.

UITableView gives us hooks for before and after a cell is displayed in the table view, and before and after it is removed from display. That’s when we want to add the cell’s view controller to our parent table view controller and the view controller’s view to the cell.

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    [cell addViewControllerToParentViewController:self];
}

- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    [cell removeViewControllerFromParentViewController];
}

Inside the cell class, implementations for these methods are simple view controller containment.

- (void)addViewControllerToParentViewController:(UIViewController *)parentViewController {
    [parentViewController contentViewController];
    [self.contentViewController didMoveToParentViewController:parentViewController];
    [self.contentView addSubview:self.contentViewController.view];
}

- (void)removeViewControllerFromParentViewController {
    [self.contentViewController.view removeFromSuperview];
    [self.contentViewController willMoveToParentViewController:nil];
    [self.contentViewController removeFromParentViewController];
}

The subview is added after the view controller is added as a child, to ensure -viewWillAppear: and company are called correctly. The table view’s willDisplayCell: method corresponds nicely with the appearance methods (-viewWillAppear: and -viewDidAppear:) and -didEndDisplayingCell: corresponds nicely with the disappearance methods, so these are the right time to perform our containment.

Holding the view controllers in the parent

Each cell have its own view controller works fine, but it feels a little weird. In Cocoa’s form of MVC, the models and views aren’t supposed to know about the controllers they’re used by. Having a cell (which is ultimately a UIView) hold on to a controller inverts that command hierarchy. To address this, we can hold on to all the child view controllers at the parent’s level, in the table view controller.

We can make this work in two ways. We can pre-allocate a view controller (and thus a view) for each item that we want to display in our table (which is easier), or allocate the view controllers as needed, and recycle them, the same way that UITableView handles cells (which is harder). Let’s start with the easy way first. When the iPhone first came out, devices were extremely strapped for RAM and couldn’t afford to generate views for each row in a table. Now, our devices have much more RAM, so you might not need to recycle views if you’re only displaying a few rows.

- (void)setupChildViewControllers {
    self.contentViewControllers = [self.modelObjects arrayByTransformingObjectsUsingBlock:^id(SKModel *model) {
        SKViewController *contentViewController = [[SKContentViewController alloc] initWithModel:model];
       [self addChildContentViewController:contentViewController];
        return contentViewController;
    }];
}

- (void)addChildContentViewController:(UIViewController *)childController {
    [self addChildViewController:childController];
    [childController didMoveToParentViewController:self];
}

(I’m using Objective-Shorthand’s -arrayByTransformingObjectsUsingBlock: here, which is longhand for -map:.)

Once you have your view controllers, you can pass their views your cell in -cellForRowAtIndexPath:.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = //make a cell
    SKViewController *viewController = self.contentViewControllers[indexPath.row];
    cell.hostedView = contentViewController.view;
    return cell;
}

And in your cell, you can take that hosted view, and add it as a subview, and clear it upon reuse.

- (void)setHostedView:(UIView *)hostedView {
    _hostedView = hostedView;
    [self.contentView addSubview:hostedView];
}

- (void)prepareForReuse {
    [super prepareForReuse];

    [self.hostedView removeFromSuperview];
    self.hostedView = nil;
}

This is everything you need for the easy way. To add view controller recycling, you need an NSMutableSet of unusedViewControllers and an NSMutableDictionary of viewControllersByIndexPath.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = //make a cell
    SKViewController *viewController = [self recycledOrNewViewController];
    viewController.model = [self.dataSource objectAtIndexPath:indexPath];
    self.viewControllersByIndexPath[indexPath] = viewController;
    cell.hostedView = contentViewController.view;
    return cell;
}

- (UIViewController *)recycledOrNewViewController {
    if (self.unusedViewControllers.count > 1) {
        UIViewController *viewController = [self.unusedViewControllers anyObject];
        [self.unusedViewControllers removeObject:viewController];
        return viewController;
    }
    SKViewController *contentViewController = [[SKContentViewController alloc] init];
    [self addChildViewController:contentViewController];
    return contentViewController;
}

- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    UIViewController *viewController = self.viewControllersByIndexPath[indexPath];
    [self.viewControllersByIndexPath removeObjectForKey:indexPath]
    [self.unusedViewControllers addObject:viewController];
}

- (NSMutableSet *)unusedViewControllers {
    if (!_unusedViewControllers) {
        self.unusedViewControllers = [NSMutableSet set];
    }
    return _unusedViewControllers;
}

- (NSMutableDictionary *)viewControllersByIndexPath {
    if (!_viewControllersByIndexPath) {
        self.viewControllersByIndexPath = [NSMutableDictionary dictionary];
    }
    return _viewControllersByIndexPath;
}

There are three important things here: first, unusedViewControllers holds on to any view controllers that are waiting to be reused. Second, viewControllersByIndexPath holds on to any view controllers that are in use. (We have to hold on to them; otherwise, they’ll deallocate.) Lastly, the cell only touches the hostedView of the view controller, fulfilling our earlier constraint where views can't know about view controllers.

These are the two best ways I’ve found to work with UIViewController objects in cells. I would love to hear if there are any techniques I missed.

April 20, 2015

Mythology

In one of my favorite posts of all time, Mike Hoye looks up exactly why we use zero indexed arrays. To spoil it, he finds that it was to optimize for compilation speed (rather than execution speed) on hardware where you only had a limited time to run your job. He writes:

The social reason is that we had to save every cycle we could, because if the job didn’t finish fast it might not finish at all and you never know when you’re getting bumped off the hardware because the President of IBM just called and fuck your thesis, it’s yacht-racing time.

So now, because Mike did the research, we can dispense with all of the arguments about fenceposts and pointer arithmetic. Off-by-one mistakes caused by zero-indexing are common, especially to newcomers who haven’t yet acclimated to the twisted way in which we bend our minds to make things easier for computers. Null-dereferencing bugs have been called a billion-dollar mistake, and zero-indexing seems decidedly worse and more common.

In the comments of that post, though, tons of programmers chime in with comments about “logical minds” and the “nature” of numbers. It’s as though these programmers didn’t digest the post. They want to justify the status quo as intentional, even when faced with cited evidence of the history: zero-indexing was just one more optimization from the early days of computing that found itself integrated into the heart of programming.

We come up with post-hoc reasons to defend things that are bad. Look at this pull request. A programmer suggests a change to the dash between years to be more precise. It’s a bit of light-hearted nerdery, which I would have expected everyone could get behind. But a few comments in, one contributor claims, “Personally, I’d prefer to keep the file as plain ASCII text.” Is there any computer on which Bootstrap is usable but which can only display ASCII text? We’re not talking about changing functionality, or even names — just a simple punctuation mark. And someone still has to find a way to disagree and try to maintain the status quo.

Reactions like these are constricting. And while constraints can be great sometimes, constraining ourselves unintentionally is when we limit ourselves from the full breadth of our thinking. They prevent us from critically analyzing about our world. The obsession with the status quo causes stuff to solidify over time. Certain elements of technology become canonized and mythologized.

The finest example of this is Model View Controller. I’ve written before about how each framework treats the “controller” portion of MVC differently, but I want to stress that even the even the other two parts of MVC, which we would normally think of as straightforward, are meaningless and inconsistent. For example, in Rails, a “view” is a template that is filled in with values from the model to generate HTML. In Cocoa Touch, UIView is a layer-backed object that can render itself into a pixel buffer. If you squint, they’re both representations of what the user will see, albeit in such an abstract way that it’s surprising that they have the same name.

And we can’t even rely on the model to be consistent, or even present! Imagine a sign up view controller. Are any of us actually moving the values from the form into a model object before sending it to the server? Why has MVC attained this state of reverence when it’s trivial to find cases where it doesn’t apply? And it’s not as though MVC is a mere suggestion: the Cocoa documentation actually states that every object has to be either a Model, a View, or a Controller, even though there are objects within Cocoa that don’t even fit in one of those three categories! “MVC” isn’t a rigorously-defined term anymore, but rather a necessary, low-information signal to other developers that our new framework fits into their worldview.

Some parts of the status quo have solidified so much that they can’t be changed. In a post called “The Next Big Language”, Steve Yegge argues:

C(++)-like syntax is the standard. Your language’s popularity will fall off as a direct function of how far you deviate from it.

If you want a language to be successful, you have to invoke methods with dot, use curly braces to make blocks of code, etc. He argues that C-style syntax is so hard to parse that it’s made it hard to create tools to manipulate code:

Most programmers don’t realize how often they need to deal with code that processes code. It’s an important case that comes up in many, many everyday situations, but we don’t have particularly good tools for dealing with it, because the syntax itself prevents it from being easy.

That’s why it’s bad.

C-style syntax probably will never go away as long as we have text-based programming languages. Even Swift, which tries to fix tons of flaws in programming, doesn’t even begin to move away from C-style syntax. It’s too ingrained in the way we view code.

This stuff isn’t a meritocracy. It just isn’t. Worse wins over better always repeatedly. PHP is the most dominant web language. A world where PHP is more successful than literally any other language isn’t a fair world. And I’m not upset because I expected this world to be fair; I’m upset because anyone dares to claim that it is.

This blog has become an exercise in questioning the way we make apps. I don’t want to be bound by mythology or ideology. Some ambitious ideas start out as laughable. And other ideas really are impractical. But the way we determine which is which is by trying them and sharing our results.

If someone tells you not to link your table cells and model objects directly, you have two good options: either find the blog post that convinces you that it’s bad idea, or try it and learn for yourself. (And then blog about the results so that we can learn from your mistake or success.)

It’s too easy to continue doing what we’ve always done. I want to question all the constants in my programming career. The things that are already status quo are don’t need cheerleading: they’re already winning. But the weird ideas, the undersung ones, those are the ones we should be championing.

April 15, 2015

Nestable

In my post on preferring composition to inheritance, I talked about the powers of the Decorator Pattern for adding behavior to something that already exists. Really, the decorator pattern is a lot like inheritance, just better in almost every way:

Instead of calling super when you need to access the parent, you use self.wrappedThing.

You get to explicitly disallow which messages get through to the wrapped object, instead of them all magically getting through to the superclass. This is a bit more work, especially if you have a lot of messages, but “explicit is better than implicit”, as PEP 20 says.

With subclassing, each subclass is locked to one superclass. With decoration, you can inject anything, since you just pass it in to the initializer. This makes testing way easier, since you can wrap anything, including a mock.

With subclassing, you have to decide at instantiation time which class you want to use and which behavior you want to add. With decoration, you can wrap the object with new behavior at your leisure, even wrapping one object in two different ways to add different behaviors to the same object.

You can decorate a decorated object, and you can continue to nest as many times as you want. At run-time, you can decide if you want to leave any levels of this nesting chain out.

And that nesting is what I want to talk about this week. They’re a lot like Matryoshka dolls. One goes into the next, over and over. But software is weird, so you can nest something that is the exact same “size” as the last thing. In the physical world, each nesting object has to get bigger than the last one. But in the digital world, the footprint of each object (namely, its type) doesn’t have to get bigger when it wraps something. What do I mean?

Let’s take a look at an example from Yegor Bugayenko’s blog. He has an interface (just an @protocol in Java-land):

interface Text {
  String read();
}

And he creates a chain of nested decorators to add a bunch of behavior to a core object:

final Text text = new AllCapsText(
  new TrimmedText(
    new PrintableText(
      new TextInFile(new File("/tmp/a.txt"))
    )
  )
);
String content = text.read();

That core object is the text from a file, and, crucially, he’s able to add all that stuff without increasing the footprint of each nested object beyond the Text interface that he defined above. The added benefit here is that you don’t have to expose a bunch of methods on each layer. Just conform to the protocol, and you’re good to go.

I adopted this pattern for Instant Cocoa’s data sources. Data sources in Instant Cocoa represent a collection where elements are fetched with index paths. You can browse the code for Instant Data Source. Here’s a truncated version of the ICDataSource protocol.

@protocol ICDataSource <NSObject>

//...

@property (nonatomic, assign, readonly) NSUInteger numberOfSections;
- (NSUInteger)numberOfObjectsInSection:(NSUInteger)section;
- (id)objectAtIndexPath:(NSIndexPath *)indexPath;

//...

@end

From this protocol, we derive several concrete implementations. First, ICSimpleDataSource, which is initialized with an array and represents a data source with one section. We also have ICRemoteDataSource and ICPaginatedDataSource, which are capable of asynchronously fetching a remote collection of objects, mapping them to your domain, and presenting them as a data source. These data sources are simple and straightforward.

Where ICDataSource objects get interesting is how you can nest them. ICSectionedDataSource is initialized with an <ICDataSource>, and uses its contents (along with a sectioningKey) to present a new data source, with a section for each unique value of the sectioningKey. Because it takes a data source instead of a plain array, you can use either ICSimpleDataSource or ICRemoteDataSource (or any data source of your own choosing, such as one that is initialized with an NSFetchRequest and fetches Core Data objects).

Another example of nested data sources is ICMultiDataSource. ICMultiDataSource is initialized with an array of data sources, and each sub-data-source it holds becomes its own section. (There’s an option to preserve subsections.) Again, since everything is built on this one protocol, we can wrap any combination of other data sources, including any of the ones previously mentioned, or, of course, your own custom ones. And again, its type “footprint” is still only <ICDataSource>, no matter what sub-data-sources it’s composed of.

You could also imagine something like an SKShowMoreDataSource, which would present the first, say, 3 objects, and then an object that is a placeholder for a cell that says “Show more…”. When the user taps on that cell, you could extract the full data source and pass it to a new table view controller that would present the full list.

In its original conception,ICPaginatedDataSource was a subclass of ICRemoteDataSource, which was a subclass of ICSectionedDataSource, which was a subclass of ICSimpleDataSource. This architecture was so limiting: since the “footprint” of each object included the footprint of all the classes above, it was hard to test all the various options and configurations. Now, you can inject any custom data source you want at any level, and the provided utility classes will use them correctly. Since they now all present the same interface and only the behavior changes, testing them is easier and they’re far more flexible.

April 7, 2015

The Object Graph

During the Q and A of the Sandi Metz’s last talk from Ruby Conf, she said something interesting:

Polymorphism is fine as long as it’s shallow and narrow and at the edges of your object graph.

I’ve been turning this quote around in my head for a while, especially the phrase “edges of your object graph”. What is an object graph?

A graph is an object with nodes (or vertices), and links that connect those nodes together. Normally, those links are called “edges”, but we’re already using the word “edges”, and I don’t want to complicate the terminology.

So in your app’s world, you have a graph. Your app delegate is probably where it starts. It holds on to the window and the root view controller, which in turn hold on to a bunch of other stuff, and so on. Each of those connection points is one of the “links” in our object graph. static pointers that hold things like singletons can also be the start of graphs.

But a really good object graph looks more like a tree than a graph. When your object graphs looks like a tree, the data flow is much clearer, and it’s easier to understand. Each object only controls its children, and children can only be changed by themselves or by parents; no other parent from another branch can change them. You might have one big trunk in the middle (ideally, an app coordinator), leading out to smaller branches (child coordinators and child view controllers), and into smaller and smaller components, like your views, models, and the rest of your objects. An aside: this is why coordinators are so valuable: they break up dependencies between your view controllers. The branches of your object tree don’t touch.

Now, what did Sandi mean about the “edges of your object graph”? Let’s not use the word “edge”, since it’s overloaded in the context of graphs. Let’s use the word “boundaries”. She’s talking about the tiniest leaves of our tree. Polymorphic objects are okay by Sandi as long as they are only referred to, instead of doing any referring. And this makes a lot of sense! Polymorphic classes are dangerous because small changes in them ripple to all of their subclasses and users. By making sure your inheritance hierarchies stay small and well managed, you can contain that complexity. When you refer to other objects, you’re more fragile. If you’re only referred to, a stable interface is the only thing you need to keep from breaking anything else.

In addition to your object graph, you also have a dependency graph. Here, your nodes are classes instead of instances, and your links are #imports instead of object ownership. (You can use scripts to analyze your dependency graph.) Recently, I’ve been working on a new extension for the Genius app. And importing even a single model class into the extension project requires a cascading series of imports that eventually sucks most of the app’s classes into the extension. It would have been great to have very clearly defined boundaries, so that I could import a module of code (like, say, the entities, or the authentication module) without dragging a ton of unrelated code along. Like in the object graph, structuring my dependencies like a tree here would have been very helpful.

It makes me think that it would be great to have two types of objects, separated into layers.

One is the “independent” layer: objects in this layer have very few dependencies and just do simple stuff. It’s your business logic, implemented as entities, policies, value objects, etc. It’s also your views and view controllers, since those ideally touch very few other things. But these objects very simple, and they’re easily transferred from project to project. These are the “pure objects” of the world.

The other is the “dependent” layer: this glues this stuff together at a highly-abstracted level. It doesn’t contain very much code, and the code that it does contain is in the language of the domain. It hooks into the lower level through object ownership, and gets called through blocks, delegates, protocols, and other communication patterns. These are the “coordinators” of the world.

The idea is that you could totally change the coordinators and go from an iPad app to an iPhone app to an extension, without having to change the independent layer at all. You can make classes so small that they and all their friends can fit in your pocket.

It reminds me a lot of an idea that Gary Bernhardt developed (paywall), which is the “functional core”/“imperative shell” split. Andy Matuschak has been pushing for it in our own community. He reveres Swift’s structs because they’re “inert, isolated, and interchangeable”. Having something that can’t change out from under you is very valuable.

It’s also somewhat reminiscent of Uncle Bob’s entity-boundary-control architecture (text). When he writes code for a Rails app, none of his business logic is tied to the framework. Instead, he can move his domain logic to any other framework quite easily, instead of stuffing it all into an ActiveRecord::Base subclass and being coupled to Rails forever.

When considering the object graph and the dependency graph, fewer links are better. Fewer cycles are better. I’m hoping to write code in the future that minimizes those two things and is all the more portable for it.

March 26, 2015

Announcing Instant Cocoa

I've been working on a library for a little while now to make developing iPhone apps easier. The library adopts a number of the patterns that I've talked about here on my blog, and is meant to fill in a lot of the gaps left by Apple's frameworks. It's out today. You can find it at instantcocoa.io, and on Github. It's a very ambitious project, and there's still quite a bit of work left to do. But it's worth launching now and getting feedback from the community.

I'm still working on documentation, so expect to see some changes at instantcocoa.io/docs. I'm hoping to have the documentation ready in about 2 weeks.

I want to give a big thanks to Tyler Galpin for designing the site and the amazing icon.

Screen Shot 2015-03-26 at 11.20.41 AM

My hope is that this project can help us all make better iPhone apps. If you see anything you'd like to comment on, please feel free to make a Github issue so that we can fix it. It’s going to be a bright future!

March 2, 2015

Emergence

A crufty codebase is an experience every developer has had. From the outset, you plan for a beautiful architecture, elegant data flow, and simple code, but after years of bug fixes and feature additions, the codebase morphs into a husk of its former self, displeasing and tiresome to work on.

As you write your programs, you make sequential straightforward changes, like adding features or fixing bugs. Each individual change is, as you intended, good, but the combination is something that neither you nor anyone else on your team can be satisfied with. This concept has relatives in systems theory, philosophy, economics, and political theory. In this post, we’ll explore some of those theories and use them to evaluate our practice.

As a sort of fictional case study, we have Mike Hadlow’s The Lava Layer Anti-Pattern. In it, he describes a situation where each of four developers continue to modernize the data layer of an app. Through no fault of management or any of the developers, the final state of the code is fragmented and confusing, various modules in disagreement.

Broadly, this concept is known as emergence. Emergence describes a system whose high-level behavior is fundamentally different than its low-level components. Emergence can be seen in lots of fields, including (but certainly not limited to) biology, computer science, and traffic. Note that the theory of emergence doesn’t ascribe any value to the high-level behavior; neutral low-level actions can cause both positive or negative high-level outcomes. The cruft in our codebases comes from a series of changes that weren’t intended to have an effect on the overall structure of the program, but nevertheless do.

There are two theories in economics that are useful for analyzing codebases. First, broken window theory. The broken window theory suggests that fixing little things like broken windows or graffiti reduces the incidence of more serious crimes, like muggings. There are broken windows in your codebase, and you can fix them them pretty easily. Increasing consistency will make future committers more reticent to make unsightly and changes. Use tools like clang-format to clean up whitespace and make code conform to standards, reducing needless comments in your code reviews.

The second economic theory that’s notable here is the Tragedy of the Commons. The Tragedy of the Commons refers to a simple idea: in a situation where a group shares a common resource, individuals can exploit that shared resource, enjoying the gains personally, and distributing the costs communally. It’s pretty easy to see how this applies to environmental issues, like pollution or overfishing.

The prototypical example is a group of ranchers that share a plot of land for their cows. As each rancher considers adding another cow to their herd, she evaluates the potential upside and downside. Upside: one more cow, which means more milk/beef/hide; downside: overgrazing of the shared land, for which the costs of repairing will be shared among all the ranchers. This is also known as an externality.

Think of your codebase as the commons: multiple people working in the same space. When working on a story or a ticket, you can take out technical debt at any point. Technical debt is formed when code is written suboptimally to optimize some other value, usually time. Especially on a team, taking a shortcut and finishing your work more quickly will make you look good in front of your teammates or your manager. Since someone has to pay back that debt, so you’re incentivized to throw your teammates or even a future version of yourself under the bus.

And it doesn’t even require ill intentions. Emergence can happen even when you have no designs either way. Have you ever reviewed a pull request that looked great in diff form, but when browsing the code later, it became obvious that the fix was unsound? It’s certainly happened to me. It’s possible (and sometimes even easy!) to accidentally write pull requests in such a way that they look good on Github, but closer examination of the fix’s surroundings reveals that it solves the problem in the wrong place or in the wrong way. This is most obvious with duplication. A diff can’t tell you if you’ve rewritten code that already exists in the codebase, and that can be a really simple way of building up technical debt, having code fall out of sync, and leaving holes for bugs to hide in.

Meditations on Moloch is an awesome blog post generalizing this concept to society, capitalism, and ideology. In it, the author quotes a short passage from the Principia Discordia, a conversation between a human and a goddess, which sums it up nicely.

”I am filled with fear and tormented with terrible visions of pain. Everywhere people are hurting one another, the planet is rampant with injustices, whole societies plunder groups of their own people, mothers imprison sons, children perish while brothers war. O, woe."

WHAT IS THE MATTER WITH THAT, IF IT IS WHAT YOU WANT TO DO?

"But nobody wants it! Everybody hates it."

OH. WELL, THEN STOP.

But how do we stop? Emergent behavior acts like entropy: reversing it takes work and, more importantly, coordination.

There are no real secrets here. A crufty codebase demands attention, and it won’t fix itself. Code will need to be refactored over time. For a team, coordination mostly happens at the code review level. This doesn’t just mean checking for style, but checking, at a very rigorous level, for flaws, duplication, confusing code, and spots that will otherwise cause problems in the future. Code review makes sure the team is synchronized.

For teams of one, solving your problem involves holistic attention to your codebase. No one else is around to catch your mistakes, so you have to put a lot of deliberation into it. On the other hand, there’s no one else to muck it up after you fix it.

But the best solution is just to never get yourself into the problem. Mike Hadlow suggests generally waiting for more maturity in the technologies that you introduce. He also seems to recommend waiting until you can replace a component wholesale instead of piecemeal.

This is your craft, and building good software is your primary job. Write code that doesn’t need documentation; barring that, write documentation. Write tests. Don’t write comments, but use good naming and method extraction to obviate them. With attention and coordination, you can make your codebase enjoyable to work in again.

February 23, 2015

Consistency is a Virtue

Last week, I talked about doing things on the right level. In some ways, that post is a plea for consistency. In the world of programming, consistency is a worthwhile ambition. Here, Brent Simmons requests some sanity when it comes to dot-notation versus bracketed message sending.

Let’s talk about a couple of languages. Smalltalk and Ruby are very similar languages, the latter rooted in the former. Smalltalk gets consistency right, to a fault. Everything is an Object, including numbers, booleans, and the idea of nothingness. Do you want Swift-esque enumerations? Use polymorphism. Everything is an Object. There’s one type of nil, compared to Objective-C’s four (nil, Nil, NULL, and NSNull). Smalltalk values consistency so much that it throws user expectations out the window. Remember how I mentioned Smalltalk is consistent to a fault? In Smalltalk operators (like + or *) are just methods that are defined on objects. However, messages have precedence from left to right, so 3 + 4 * 5 evaluates to 35, as though your code read 3.plus(4).times(5), instead of adhering to normal mathematical order-of-operations, as you might expect. (Seems like Alan Kay can invent OO, but can’t get OoO right!)

Ruby also has this Everything is an Object concept, with one object for nil, etc. But in Ruby, purity gives way to pragmatism, and operators like * have a higher precedence than operators like +. However, closures, simple in Smalltalk, are made complex in Ruby. There are three types of closures in Ruby: block, Procs, and Lambdas. The differences between them are unimportant and enumerated elsewhere. With three types of closures, knowing when to use which becomes an exercise in expertise rather than ease. It’s not immediately clear when you should use each or what the performance ramifications are. The stewards of Ruby let implementation details get in the way of the “user interface” of their language. Developers don’t care which closures can’t go in arrays and they don’t want to have to think about what the return keyword binds to — they just want to write code. Keep it simple for them.

Objective-C, like Ruby, is also based in Smalltalkian roots. In trying to make Objective-C more performant, however, compromises were made, and the designers used primitives to represent concepts like truth, falsity, and numbers. These primitives, since they aren’t objects, can’t go into native collections like arrays and dictionaries and must be “boxed-up” in a special class. That class, NSNumber, has no facility for manipulating the numbers therein, which leaves the developer constantly boxing and unboxing numbers to use them. Swift smoothes over this particular issue by treating integers and other numbers as structs, which retain the performance characteristics of primitives, can be stored in collections, and can be messaged.

And consistency trickles down from languages into standard library design. Apple does a great job with consistency in API design. Long, precise method names make it extremely specific what types you need to pass in, what type you’ll get, and what the function does. Apple even provides a WWDC talk about how to design your APIs.

Contrast this with PHP’s standard library. rtrim, strlen and str_replace are all functions that operate on strings, but they all have differing prefixes. (It turns out that this is because PHP’s first function lookup was based on the length of the function name, so functions needed names that were as varied as possible. The height of absurdity.) Compare these function names to the related Foundation method names. Here, consistency gives programmers a super power — the ability to guess what the function should be called — and autocomplete can take it from there.

And it affects your own code as well. Let’s take an example, like view allocation. There are a lot of places where you can set up your subviews. You can do it in your UIViewController’s -loadView or -viewDidLoad, or you can do it in UIView’s -initWithFrame:, or in Interface Builder, or anywhere else (it’s just software, after all). My preference is a lazy initializer:

- (UITextField *)usernameField {
    if (!_usernameField) {
        UITextField *usernameField = [[UITextField alloc] init];
        usernameField.placeholder = @"Username or email";
        [self addSubview:usernameField];
        
        self.usernameField = usernameField;
    }
    return _usernameField;
}

Once allocation and configuration are always done in the same way, you no longer have to think about where it goes. New method, every time. You never have to think about where to find it, either. Command-click on the getter for the view, and you’re taken right to the place where the view is created and configured. Now, if we extract the line of code that sets the placeholder, we’re suddenly left with a method that relies only on the name and class of the property.

- (UITextField *)usernameField {
    if (!_usernameField) {
        UITextField *usernameField = [[UITextField alloc] init];
        [self configureUsernameField];
        [self addSubview:usernameField];
        
        self.usernameField = usernameField;
    }
    return _usernameField;
}

Is this ripe for metaprogramming? You’d better believe it. If we mark the usernameField property as @dynamic, we can catch it in +resolveInstanceMethod: and create and configure it dynamically:

@implementation SKView

+ (BOOL)resolveInstanceMethod:(SEL)sel {
    NSString *selectorName = NSStringFromSelector(sel);
    
    NSString *viewName = [self viewNameFromSelector:selectorName];
    Class viewClass = [self viewClassForPropertyNamed:viewName];
    SEL configurationSelector = [self configurationSelectorForViewNamed:viewName]; //-configure<ViewName>
    BOOL isSetter = [selectorName hasPrefix:@"set"];
    if (isSetter) {
        IMP implementation  = imp_implementationWithBlock((id) ^(SKView *self, UIView *newView) {
            return [self.views setObject:newView forKey:viewName];
        });
        class_addMethod(self, sel, implementation, "v@:@");
        return YES;
    } else {
        IMP implementation  = imp_implementationWithBlock((id) ^(SKView *self) {
            if ([self.views objectForKey:viewName]) {
                return [self.views objectForKey:viewName];
            }
            UIView *view = [[viewClass alloc] init];
            [self addSubview:view];
            [self.views setObject:view forKey:viewName];
            if ([self respondsToSelector:configurationSelector]) {
                [self performSelector:configurationSelector];
            }
            return (id)view;
        });
        class_addMethod(self, sel, implementation, "@@:");
        return YES;
    }
}

@end

Consistency isn’t just a facet of good code, it is good code.

(more…)