At Recordit, our goal is to make capturing and sharing screen captures as fast and easy as possible. When we saw that Twitter opened up GIF support in their API, we couldn’t have been happier.
It only took a few days to integrate Twitter into our Mac app and to scale out our back end for sharing and GIF processing. We’d love to share what we learned about both.
Native Twitter authentication on OS X
We first considered implementing the standard OAuth flow. But with native support of Twitter into OS X, we felt we could do better. As we dug deeper, we realized that we check for the existence of a connected Twitter account on a Mac, and prompt a user if one didn’t already exist. A quick screen share below:
To implement this flow, we first use STTwitterOS’ +twitterAPIOSWithAccount to get an instance of ACAccount. This represents a locally saved Internet account. If no such account exists, we use AppleScript plus Apple’s Scripting Bridge to bring up the user’s Twitter settings in the OS X Setting pane.
To be more specific, we write the following AppleScript code:
tell application "System Preferences" activate set the current pane to pane id "com.apple.preferences.internetaccounts" get the name of every anchor of pane id "com.apple.preferences.internetaccounts" reveal anchor "com.apple.twitter.iaplugin" of pane id "com.apple.preferences.internetaccounts" end tell
We then run it through Apple’s Scripting Bridge, which generates a header file with an API that you can use to communicate with another application. This results in the following Objective-C code:
SystemPreferencesApplication *systemPreferences = [SBApplication applicationWithBundleIdentifier:@"com.apple.systempreferences"]; SystemPreferencesPane *pane = (SystemPreferencesPane *) [[systemPreferences panes] objectWithID:@"com.apple.preferences.internetaccounts"]; SystemPreferencesAnchor *anchor = (SystemPreferencesAnchor *) [[pane anchors] objectWithName:@"com.apple.twitter.iaplugin"]; [systemPreferences activate]; systemPreferences.currentPane = pane; [anchor reveal]
After the user provides credentials, we can then be guaranteed that our API upload of the tweet with a GIF will work. (And we only need to do this on the first use, which makes it really simple to share our GIFs.)
Generating GIFs fast, and at scale
To create the best user experience possible, we chose to do server-side rendering of GIFs. This also lets us do other performance upgrades without having to push client-side updates.
In expectation for Twitter’s scale, we needed to make sure we had the proper hardware and infrastructure to handle the load. This meant designing and building the following architecture, as diagrammed by (you guessed it) a GIF:
We modeled a service-oriented design, where individual components can focus on what they do best. As such, we have the main API and workers in Ruby, the server that catching user’s frames in Node (to take advantage of asynchronous I/O) and the other quant-heavy processing systems built in Python.
In addition, we have our intra-system communication being done through our homebrewed queue:Borium, a lightweight Ruby queue that plays nice with Node and Ruby. The server balancer helps us distribute the load between the specialized workers (encoders, processors, or file receivers), helping us scale each component independent of one another.
Overall, we love the experience that we’ve created. Users have incredibly fast GIF processing, and can share on Twitter just like a native OS X application. We really feel we’ve created the best screen sharing solution for our users, and are excited to incorporate Twitter into that fold.
Did someone say … cookies?