June 30, 2015

Protocol-Oriented Networking

Crusty, the antagonistic character from WWDC 2015 Session 408, has been making the rounds on the blogosphere, writing about protocol-oriented programming. For me, protocol extensions in Swift are easily the coolest new feature, because they enable us to add behavior to a set of data easily.

In a post from a few weeks ago called Templating, I describe a flexible networking architecture, that relies heavily on protocols to define and send network requests. It's been working well in practice, and a few cases popped up where the architecture made it really easy to handle new unexpected request types. I hope to write about those soon.

For this post, I'd like to examine the new protocol extensions, and what they can do for this networking design. Ultimately, what we were doing in the Templating post was adding behavior to a set of data. Since I wrote it first in Objective-C, we did it with decoration.

With Swift 2, however, while we could continue to use decoration to wrap our data with new functionality, we've been given a new power with protocol extensions. Protocol extensions let us add concrete methods to a protocol that are dependent on the abstract methods in that protocol. It's a form of the template method pattern, but one that doesn't rely on inheritance.

I'm still very new at the Swift stuff, so you'll have to forgive my sins.

Let's define a lighter version of the SKRequestTemplate protocol from the previous post, but in Swift this time. Since we're adding sendRequest() directly onto the protocol, it's no longer a template, but the request itself.

protocol Request {
    var baseURL : NSURL? { get }
    var method : String { get }
    var path : String { get }
    var parameters : Dictionary<String, String> { get }
}

The baseURL property is marked as an optional, becuase -[NSURL URLWithString:] returns an optional by default. Since there's no good default for a URL (like the empty string is for strings), we'll prevent the user of our networking protocol from having to use a scary bang and allow her to return an optional here.

Okay, let's define our first request. We'll use Github's Zen endpoint, which just returns a short proverb as a string.

struct ZenRequest : Request {
    let baseURL = NSURL(string: "https://api.github.com/")
    let path: String = "zen"
}

Uh-oh, the compiler is already complaining. Swift wants to require us to return something for the method and parameters. That would make this request ugly, though, so we won't be doing that. We could mark each property with the optional keyword, but then we have to mark the whole protocol as @objc, and I want to make this as Swifty as possible. (Ash Furrow lays out this problem neatly in his post, Protocols and Swift.)

Fortunately, we're saved by protocol extensions here. We can give a default implementation for these properties in an extension, and we can leave it out of the individual request structs.

extension Request {
    var method : String { return "GET" }
    var path : String { return "" }
    var parameters : Dictionary<String, String> { return Dictionary() }
}

Now let's add our sendRequest function to the RequestTemplate:

extension Request {
    func buildRequest() -> NSURLRequest? {
        guard let baseURL = baseURL else { return nil }
        guard let URLComponents = NSURLComponents(URL: baseURL, resolvingAgainstBaseURL: true) else { return nil }
        URLComponents.path = (URLComponents.path ?? "") + path
        guard let URL = URLComponents.URL else { return nil }
        let request = NSMutableURLRequest(URL: URL)
        request.HTTPMethod = method
        return request
    }
    func sendRequest(success success: (string: String) -> (), failure: (error: ErrorType) -> ()) {
        let session = NSURLSession.sharedSession()
        guard let request = buildRequest() else { return }
        guard let task = session.dataTaskWithRequest(request, completionHandler: { (taskData, taskResponse, taskError) -> Void in
            if let taskError = taskError {
                failure (error: taskError)
            } else if let taskData = taskData {
                guard let string = NSString(data: taskData, encoding: NSUTF8StringEncoding) as? String else { return }
                success(string: string)
            }
        }) else { return }
        task.resume()
    }
}

Wow, look at all those guard let statements! Exclamation points are for your writing, not your code. We can now create and send our request:

ZenRequest().sendRequest(
    success: { string in
        print(string)
    },
    failure: { error in
        print(error)
})

This is a really simple version of templated requests (I left out a few complexities, like parameters, headers, JSON parsing, etc), but I certainly like how succinct it is. A GET request with no parameters is only a few lines of code. Supporting different types of requests, such as multi-part requests, means overriding the buildRequest method, and returning whatever cooked URL request is appropriate.

June 16, 2015

Declarations

“Declarative” and “imperative” are often used as substitutes for “object-oriented” and “functional”. Conflating “declarative” and “functional” creates confusion and hurts programmers.

Without picking on Nick specifically (since the internet is replete with examples of programmers making the same mistake), this essay on Swift 2’s errors serves as an example. Writers that make this mistake often use the word "imperative" as a thinly-veiled insult against OOP.

The value of declarative code is in describing what you’d like to do, rather than concerning yourself with how to perform the task. Let’s examine one of the standard examples that functional programmers use to explain how imperative and declarative code are different. Imperative code is using a for-loop to iterate over an array and perform some task:

var numbers = [1,2,3,4,5]
var total = 0

for(var i = 0; i < numbers.length; i++) {
  total += numbers[i]
}
console.log(total) //=> 15

On the other hand, the declarative style lets you define how each element in an array should be incorporated, via a block, and the reduce method handles applying that incorporation to each element. We no longer have to concern ourselves with how to merge the values, because reduce handles that for us.

var numbers = [1,2,3,4,5]

var total = numbers.reduce(function(sum, n) {
  return sum + n
});
console.log(total) //=> 15

Without question, this second solution is preferable. And it does have the word function in it. But we should resist calling solutions that use blocks or functions “declarative”, because there’s nuance here. I can write code that’s more imperative than the first solution: a C array where elements in the array are mapped directly onto an unbroken block of memory. Or worse: assembly that reads each element into a register and adds it to itself.

And I can also write code that’s more declarative than the second solution — a message with no parameters that describes exactly what to do, without saying how to do it:

[numbers sum];

Now, I’d probably never write a method like this. But it’s certainly more declarative. Now I don’t even care how the numbers are added together, and as a cherry on top, there’s no blocks or functions seen anywhere — just a message. Maybe it’s implemented with reduce under the hood, or maybe there are some optimizations in place, but they’re invisible and uninteresting to me. If you think sum is a weird method for an array, think about something like reverse, which could be implemented in terms of reduce, but normally isn’t.

Imperativity-declarativity is a spectrum, and that spectrum lies on an orthogonal axis to the functional/object-oriented divide. As we build abstractions, we go up on the declarativity scale. That’s what reduce (and its friends) are: great abstractions. Abstractions are awesome. If you can understand some concept in the general case, that catapults your thinking much further than if you just dealt the concept in its specific form. Great abstractions don’t have to be complicated to be useful. An Objective-C implementation of map can be done in 5 lines of code.

It’s easy to write imperative code in both functional and object-oriented languages. However, when writing code in either style, great declarative code and great abstractions help increase the facility we have in our domain.

June 3, 2015

Why I don’t write Swift

Often, readers will ask me why all my blog technical posts are in Objective-C, and not Swift. I don't write blog posts in Swift because I don't write code in Swift. There are three big reasons for that.

Swift is not production-ready

Trying to use Swift in any professional capacity is a joke. A very cruel joke. The "tooling" is terrible: compilation speed has been abysmal, and SourceKit spent the better part of the year as a punchline.

Last year, at WWDC 2014, Apple claimed that changes to Swift over the course of the year would probably break source compatibility, but that binary compatibility would be maintained (Apple dev forums). That's now rumored to be a goal for WWDC 2015:

With iOS 9 and OS X 10.11, we are told that this will change: Swift is planned to reach what is known as “Application Binary Interface (ABI) stability,” and its code libraries will therefore be pre-installed within the new iOS and Mac operating systems.

Even if they could have maintained binary compatibility all year, the source changes will break old versions of your code from compiling. This means awesome tools like git-bisect are completely useless. Being able to hop to past versions of your app is part of the value of version control and writing code in Swift ruins it.

I understand and accept the "release early, release often" philosophy, and I'm glad the Swift team has embraced it. It's good to polish Swift in public rather than in private. However, for someone who maintains their livelihood through code, writing that code in such a fledgling language is dangerous. It's never been smart to program using the bleeding-edge technologies. How many times do we have to be bitten before we become a little shy?

Swift is complicated

Swift is not a simple language. This Quora answer by Rob Rix is bound to become an instant classic. I don't even understand how some of these bullet points can be real.

  • enum cases act like functions, but are not functions.
  • The rules for overriding a superclass’ init are Byzantine to the point of impossibility.

At 10:05 in Build Phase 82, the hosts discuss methods versus computed, lazy, and stored properties. There are so many little rules to know about!

How do you choose whether to use a struct or a class? Well, I hope you're ready to memorize a bunch of arcane rules for how these two (nearly identical!) things work.

There's so much new stuff to learn about. But it's not the good kind of learning, where you expand your mind and discover new ways of thinking and working. It's rote memorization of the six new inscrutable ways to make readonly properties. Learning that stuff won't make you a better programmer or thinker, it'll make you better at working around Swift.

Objective-C has plenty of complexity in it, given that it's a superset of C. But we had a chance to totally change that, and we dropped the ball. Designing languages isn't easy, especially languages that are going to be used widely in practice. But Swift tries to be great at both functional and object-oriented programming, and ultimately, becomes awkward at both.

I'm not good at Swift

The final big reason I don't write Swift is that I don't think I can write good Swift yet. I'm not really convinced that any of us can. Our job is to deliver timely, high-quality software, and there's tons of experience doing that in Objective-C.

Don't get me wrong: that doesn't mean I don't think I can write great Swift ever, or that it's not worth learning. It's just not worth shipping code in right now. I love reading the blog posts, with people exploring and researching and trying to understand all the new things we can make. One day I hope I'll understand transducers and lenses and functors and closed groups. Ultimately though, for the near- to mid-term future, I can ship much better code with my Objective-C knowledge, and anything I do in Swift will be fundamentally experimental.

It'll be interesting to see what next week's announcements bring us. I'd love to eat my words and see some new stuff in Swift that is worth all the pain. My original plan was that I'd wait a year before writing any Swift, and I hope that I don't have to wait any longer. My suspicion, though, is that we'll see a more stable Xcode 7, and Swift 2.0, which will bring us a little cleaned-up syntax and not much else.

Post-WWDC update: Protocol extensions are so so so cool, but ultimately, I think my stance will stay the same. Via Michael Tsai, iOS 9 still doesn’t have ABI compatibility. My new plan is that once Swift is source compatible with previous versions, the next new app I write after that will be all Swift. I don’t want my code to break when I go back in git, and I don’t want to deal with the context switching of having Objective-C and Swift in one app.

May 28, 2015

Templating

Last week’s post was about a few common networking patterns. I’ve never been satisfied with any of them, so I wanted to describe how I might structure things. I'm assuming a JSON API over HTTP, but these principles are flexible enough to work with any setup.

What are the goals I have for a networking infrastructure?

I want skimmability, simplicity, composability, and lots of flexibility. Let's take the first two at once. What I want is a single file that describes how a request works. A new developer can glance at that file and understand exactly what that request entails and how it's structured.

I laid out this pattern in Prefer Composition to Inheritance: the request template.

@protocol SKRequestTemplate <NSObject>

@property (readonly) NSURL *baseURL;

@optional
@property (readonly) NSString *method;
@property (readonly) NSString *path;
@property (readonly) NSDictionary *parameters;
@property (readonly) NSDictionary *headers;

@end

You can define a really easy-to-skim object that represents a single request. We have the most fundamental element of the networking request represented as an object. We can't break this down into any smaller objects, and that means it's simple enough.

If I were writing this code in Swift, it would almost definitely be a struct, since it's a just a dumb holder of data. You can keep these objects around as long or short as you like, since all they do is store information. (You can take a look at a fully implemented request here.)

Because it's just a protocol, these objects are super flexible. You can bring your own inheritance heirarchy if you like, for example inheriting from one template that has a base URL built-in and maybe some helper methods.

But these objects can't send any data over the network. To do that, we could we could be lazy and pass the template to some kind of global sender:

[[SKRequestSender sharedSender] sendRequestWithTemplate:loginTemplate];

But that wouldn't be in the spirit of this blog. What would be awesome is if we could use decoration to add a -sendRequest method to this template.

@implementation SKSendableRequest

- (instancetype)initWithRequestTemplate:(id<SKRequestTemplate>)template {
    self = [super init];
    if (!self) return nil;

    _template = template;

    return self;
}

- (void)sendRequestWithSuccessBlock:(void (^)(id result))successBlock failureBlock:(void (^)(NSError *error))failureBlock {
    NSURLRequest *request = //generate a request from a template
    [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        //handle response
    }] resume];
}

@end

As I wrote this object, I saw that there are two complicated steps that I wanted to break out into their own objects. One is building the NSURLRequest object, and the other is parsing the response.

Request

To generate the request, I made SKRequestBuilder. This class takes a request template and vends an NSURLRequest. Creating the request was originally a method on the SKSendableRequest class, until it started getting gnarly, at which point I graduated it to its own class.

@implementation SKRequestBuilder

- (instancetype)initWithRequestTemplate:(id<SKRequestTemplate>)template {
    self = [super init];
    if (!self) return nil;

    _template = template

    return self;
}

- (NSData *)HTTPBody {
    return [NSJSONSerialization dataWithJSONObject:self.template.parameters options:0 error:nil];
}

- (NSURL *)URL {
    NSURLComponents *URLComponents = [NSURLComponents componentsWithURL:self.template.baseURL resolvingAgainstBaseURL:YES];
    NSString *path = [URLComponents.path stringByAppendingString:self.template.path];
    URLComponents.path = path;
    return URLComponents.URL;
}

- (NSURLRequest *)URLRequest {
    NSMutableURLRequest *mutableURLRequest = [[NSMutableURLRequest alloc] init];
    mutableURLRequest.HTTPMethod = self.template.method;
    mutableURLRequest.HTTPBody = [self HTTPBody];
    mutableURLRequest.URL = [self URL];
    [self.template.headers enumerateKeysAndObjectsUsingBlock:^(NSString *fieldName, NSString *value, BOOL *stop) {
        [mutableURLRequest addValue:value forHTTPHeaderField:fieldName];
    }];
    return [mutableURLRequest copy];
}

@end

For simplicity, I've left out a few details here (like nil checks and query parameter handling). I'll link to a gist at the end of the post which has handles more stuff.

This also changes the SKSendableRequest initializer to create the request builder from the template:

- (instancetype)initWithRequestTemplate:(id<SKRequestTemplate>)template {
    self = [super init];
    if (!self) return nil;

    _requestBuilder = [[SKRequestBuilder alloc] initWithRequestTemplate:template];

    return self;
}

Response

For parsing the response, we need an object that takes an NSURLResponse, NSData, NSError and parses it into a result and an error, which are what are returned to the completion blocks.

@implementation SKResponseHandler

- (instancetype)initWithResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *)error {
    self = [super init];
    if (!self) return nil;

    _response = response;
    _data = data;

    _error = error;
    _result = [NSJSONSerialization JSONObjectWithData:self.data options:0 error:nil];

    return self;
}

@end

There's one more thing we need to handle. Requests aren't necessarily going to want to return the error from NSURLSession or the JSON result. They might want to use the JSON to generate a local domain object, or they might want to extract errors from the JSON response.

To that end, I made the error and result properties of SKResponseHandler mutable. I also added one more method to the request template, called -finalizeWithResponse:. The template can implement that method to transform the result or error of the response before its returned to the completion block. For example, a login request might implement that method like so:

- (void)finalizeWithResponse:(id<SKResponse>)response {
    response.result = [[SKSession alloc] initWithDictionary:response.result];
}

This way, all the logic tied to a particular endpoint is located in one class, and any class using it gets fully baked objects in their completion block.

Our final -sendRequest method looks like this (again, slightly simplified):

- (void)sendRequestWithSuccessBlock:(void (^)(id result))successBlock failureBlock:(void (^)(NSError *error))failureBlock {
    [[[NSURLSession sharedSession] dataTaskWithRequest:self.requestBuilder.URLRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        SKResponseHandler *responseHandler = [[SKResponseHandler alloc] initWithResponse:response data:data error:error];
        [self finalizeWithResponse:responseHandler];
        if (responseHandler.error) {
            if (failureBlock) {
                failureBlock(responseHandler.error);
            }
        } else {
            if (successBlock) {
                successBlock(responseHandler.result);
            }
        }
    }] resume];
}

One of the big benefits to separating request building and response handling into their own objects is that users can inject whatever request builder they want. If their data comes back in MessagePack format, they can bring their own response handler. The NSURLSession could also easily be injected.

You could easily create an initializer that accepts a request builder -initWithRequestBuilder:, but injecting a response handler is a bit harder, since it's initialized with the response data. To get around this, you could inject a class to be intialized. This is a tough problem and I don't have a great solution for it yet.

I've packaged up this code into a gist. I'm not sure if this code will become a library, but there's a pretty good chance it'll end up as the networking layer for Instant Cocoa.

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.