A Simple iOS App to Commemorate Mad Men

For those who aren’t fans, AMC’s Mad Men ended recently. Arguably one of the best TV series in the last decade and definitely my favorite, I wanted to do something to commemorate its finale. Fortunately, the last episode coincided with the end of my undergraduate thesis and a two-week stretch until graduation. I decided I could explore mobile programming and continue to worship Mad Men by creating an iOS app. What I ended up with was a small but surprisingly stylish application called Mad Draper. It may not be the most fleshed out application in the store, but it was a very helpful project for picking up some introductory Swift and iOS skills. Basically, Mad Draper lets you flip through some quotes from the show, backed by famous advertisements from the 1960’s. You can swipe through a series of screens like this one:

example-draper

Each image can be shared via text, email, Facebook, Twitter, etc. Quotes were curated by hand from an IMDB database, and the images come from all kinds of famous companies like Heinz, Ford, and Budweiser.

And, the application will send you quotes as notifications! This last part has really made it fun to have on my phone for the last ten days or so. Quotes can be scheduled for time intervals ranging from never to weekly.

To make this a reality, I started with Ray Wenderlich’s Swift tutorial (it comes free with signing up). I chose Swift mostly because it seemed fun and flashy, as opposed to its wordy predecessor. The tutorial is really fantastic, and it walks you through a lot of Xcode’s powerful but cryptic functionality.

Finished with the tutorial, I hacked at a Swift application with a Parse database. Sometimes Parse gets flack for being what some consider a replacement for hardcore coding, but its cloud services were key for quickly scaffolding this project.

The quotes portion of the application was pretty straightforward. I put them all in a Parse database, and I fetch them when the app opens. When the user swipes, the next quote is selected randomly from the list held in memory.

The notifications portion was a little tricker. Notifications are usually triggered by some action, but I wanted to send scheduled notifications. At first, I scheduled a bunch of notifications in a loop. Apple doesn’t allow an application to have more than 64 scheduled notifications at once. This meant that when the user reopened the app, I’d cancel all pending notifications and scheduled 64 new ones. This obviously was not ideal, especially if the user didn’t reopen Mad Draper before the notifications finished.

The answer was Parse Cloud Code. Parse lets you write Javascript code and deploy it on their servers, essentially creating a backend really fast. And, their Background Jobs were exactly what I needed for event-less notifications. Parse can group devices into different channels. I labeled each time interval a different channel, where the interval is determined from the settings. Here’s what checking and settings a user’s channel looks like in Swift:

    // Fetch the current setting
    let defaults = NSUserDefaults.standardUserDefaults()
    var channel = defaults.stringForKey("quote_notifications")
    
    // Give users with no channel the default of daily
    if channel == nil {
      channel = "Daily"
    }
    
    // Reset the channels on parse
    var currentInstallation = PFInstallation.currentInstallation()
    currentInstallation.channels = [channel as! AnyObject]
    currentInstallation.saveInBackground()

Next, notifications could be sent to each channel through cloud code. Here’s what the code to send a quote notification to a given channel looks like:

function sendPush(timegroup) {
  var Quote = Parse.Object.extend("quote");
  var query = new Parse.Query(Quote);

  query.find({
    success: function(results) {

      // Create random alert content
      var index = getRandomInt(0, results.length);
      quote = results[index];
      text = quote.get("text");
      speaker = quote.get("speaker");
      alert = text + "\n-" + speaker;

      Parse.Push.send({
        channels: [timegroup],
        data: {
          alert: alert
        }
      }, {
        success: function() {
          response.success(timegroup + " push successful.");
        },
        error: function(error) {
          response.error(timegroup + " push failed");
       }
      });
    },
    error: function(error) {
      console.log("An error occurred fetching quotes")
      console.error(error)
    }
  });
};

Parse.Cloud.job("dailynotification", function(request, status) {
  sendPush("Daily")
});

Scheduling the job can be done from a fancy Parse interface where logs and analytics are stored. This system was a significant upgrade from scheduling the notifications in the application.

From a design perspective, I had a lot of help from my colleague Runi Goswami. With her advice, I put a dark semitransparent layer over the ’60s ads so that the white text on top could be read easily. She was also adamant about using a font called Cooper Hewitt by Chester Jenkins, which looks awesome. And of course, she churned out the “share” button and the app icon. On the coding side, I used small tricks like fading the text and hiding the “share” button from a shared image to polish things up.

After a long wait in Apple purgatory (roughly one week), I pushed my project to the App Store. It was a fun few days putting everything together, and I learned that XCode is a really amazing tool. Swift is remarkably straightforward, too, but I wish iOS had more libraries for making UI elements; building an iOS view is much tougher than building an HTML page. I also learned to appreciate Parse’s functionality. It wouldn’t be my preferred tool for a large operation, but it was great for this quick project.

If you’re interested in checking out the code, it’s hosted on Github.