Baby’s First Monad

Since this is an app designed to pull down recent showtime listings from the Internet¹, I realized I’d need a network request in order to fetch the data and populate a listing of showtimes. In this case, a simple array to populate a tableview with the movies that are playing for each theater. I didn’t want to waste time building the entire API before digging into the app, so I spun up a dummy heroku instance to return some hard coded values. At this point, my muscle memory is nearly wired to pull in something like AFNetworking and start making GET requests. Before I knew it, I had a podfile and a view model ready to go; but quickly realized that I’m supposed to be doing this the Reactive Cocoa way.

Without much searching around, I decided to place my best foot forward and see how far I could get without tripping. From what I’ve seen in the past, the macro RAC will magically populate an object with data by assigning it to something called a RACSignal. So that’s where I began: RAC(self, movies) = [self fetchMoviesSignal]; Now I just needed to see what this fetchMoviesSignal entailed.


RACSignal appears to be the workhorse of reactive cocoa. When inspecting the headers, we’re told that RACSignal inherits from RACStream, which is a class that represents a monad, upon which many stream-based operations can be built (it looks complicated, so I closed the header to regain my attention).

Since I already had AFNetworking imported, I decided to expirment with wrapping it in a new signal object. As it turns out, it was fairly straightforward. This is what I ended up with:

- (RACSignal *)fetchMoviesSignal {
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [[AFHTTPRequestOperationManager manager] GET:@"" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
            [subscriber sendNext:responseObject];
            [subscriber sendCompleted];
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            [subscriber sendError:error];
        return nil;

Before I got here, I had to ask myself what a subscriber was. The documentation for the subscriber states that it represents any object which can directly receive values from a RACSignal. The header file for the RACSubscriber protocol was actually very informative.² sendNext:, sendCompleted, and sendError: all made perfect sense to me at the time. When I built and ran, and saw that my movies array was populated with the JSON response from the GET request, I felt all warm and fuzzy.

Even though I didn’t accomplish much, I took quite some time before arriving at this. I did a lot of reading the header files and other blog posts I came across to make sure I wasn’t way off track. I think next time I will try to bite off a little more and see what all I can accomplish in the UI. I’ll need to populate my table with the showtimes and movie posters, so it sounds like I have my work cut out for me yet!