iPhone Development

Migrating an iPhone app off of Three20

I decided to give my EveryMarathon marathon calendar iPhone app a few tweaks and release an updated version while watching a college football bowl game on TV – easy enough, right? I’d developed the app on my old MacBook Pro using Three20, which is an application framework for iOS.

Choices, choices

I didn’t have Three20 on my new MacBook Air, mostly because I wasn’t using it for any current development projects – it’s not maintained any more from what I can tell, as the lead developer moved on to a new framework, Nimbus. I’m not using that either – instead I wrote a boilerplate iOS application template I like to use for new iPhone and iPad apps, especially if they need to talk to Drupal or another REST service.

I had two choices at this point – download and build Three20 as a set of static libraries (major pain in the neck last time I tried, and I think things probably got worse when XCode 4 was released) and tweak the app, or port the whole thing off of Three20 to Apple-standard UIKit code. Luckily, there were a few more football games on TV, so I decided to drop Three20 completely.

Three20 Tables

The one thing I really liked about Three20 was the reasonable handing of table views and data sources – much easier than working with UITableView and its delegate and datasource.  Rewriting all of my table datasource code was a pain in the neck, but it was easy enough to test as I went. I’d commented out all Three20 related code, and removed all references to its header files throughout the app, so I was able to get something running, even if it didn’t do anything, pretty quickly.

Three20 Navigator and URLs

The real mess came from replacing TTNavigator, which I’d initially thought was pretty clever, but as soon as you try and do any special cases, completely falls apart. Basically, the idea is that each controller in your iPhone app maps to a URL, which then you can call from any other controller when a button is pressed, or a table cell is selected, or what have you.

The problem with TTNavigator is that you can’t pass objects in these URLs without some major hacks, but if you write your app using UIKit, you can simply pass an object to a UIViewController in an init method, or set it using a property setter method. Three20 heavily relies on these TTNavigator URLs, and you end up with some weird overloading of default UIKit arguments (such as target in a navigation bar button) to get it all to work. Basically, it’s not pretty under the hood.

Rewriting all of the TTNavigator stuff was pretty straightforward, once I rationalized out my use of arguments in TTURLs – for instance, I was passing Drupal node ids instead of just the object, and then relying on my data singleton to resolve the node ids into objects.

Three20 Tab Bar

Ripping out the Three20 tab bar controller was straightforward – I subclassed UITabBarController instead, replaced the Three20 URLs with instances of the view controllers in navigation controllers, and it all pretty much worked.

TTWebViewController is pretty nice, but I replaced it straight up with SVWebViewController, and it’s basically a drop-in replacement, without relying on a whole bunch of other stuff.

Now that the app doesn’t rely on Three20, creating an iPad version should be pretty straightforward, especially as the app doesn’t have a fancy user interface. Three20 had a couple of branches that maybe supported iPad use, but it seems like the TTNavigator is really holding the app back.

If you have any questions about migrating your Three20 apps over to UIKit, let me know – I didn’t try to migrate the app over to Nimbus, but I don’t think all of the features in Three20 are in Nimbus yet anyway. My biggest problem with Three20 is that once you use it, you’re more or less stuck using it for everything, and it’s tough to bring in third-party or Apple code that doesn’t support it.

Drupal Planet Facebook Development iPhone Development

Drupal 7 + Facebook Open Graph + Timeline = iPhone app

We’re steadily getting closer to a vision of the semantic web – and it’s being driven by Facebook through their Open Graph Protocol. Open Graph came out in 2010, and it initially supported a large set of different object types and properties (for instance, music, article, book) – very interesting, but there are certainly more object types now!

In my case, I wanted to create an app for keeping track of highpoints, which are the highest point in each US state (for instance, Mount Whitney in California). Users can “summit” a highpoint, and then share that on their Facebook Timeline through an iPhone app I’m working on:

To support the Open Graph Protocol, you’ll need Drupal to provide meta tags for Facebook to parse. There are several modules in this space, but the momentum appears to be with the D7 module Metatag. Metatag is great, but it does not support custom Open Graph types (in the November dev release, anyway), so I had to modify the Open Graph module to add my “highpointer:highpoint” Open Graph type, and it’s custom properties – state and height. I also had to add “fb:app_id” as a custom type, because I didn’t want to use the Drupal for Facebook module just yet for this project. The next step would be to make this more flexible.

You’ll need to create an app as a Facebook Developer, then configure its Open Graph type, action, and properties. Your iOS or Android app can make one call to the Facebook API to tell Facebook that your user has summited a highpoint, or read a book, or whatever your site does. Then, in their Facebook Timeline, your app’s Aggregation will show up:

Right now, the Facebook iOS SDK Single Sign On does not work with the code samples they provide and the current version of the Facebook mobile app and iOS 5. The workaround is to either authenticate through Mobile Safari to the mobile version of Facebook’s web site, or put up a Facebook login dialog box in your app for the user to authorize your app. I went with the login dialog box:

Toolbar icons and app background are from MediaLoot, which is a great graphic design resource, and well worth the money.

Some of the third party iPhone libraries I relied on:


DrupalCon Denver 2012! PhoneGap + Drupal Presentation

I’m excited to be speaking at DrupalCon Denver 2012 on Drupal and PhoneGap with Fabian Franz! Here’s a link to the session:Auto Generate your Mobile Drupal App Using PhoneGap

There’s a lot of momentum around PhoneGap and bringing Drupal into native apps using HTML, CSS, and JavaScript. Once you’ve built your Drupal site to be mobile-ready, either with a mobile-specific theme or with responsive design, you can use PhoneGap to add camera functionality, native maps, in-app purchases, push notifications, and you can put your app up on the Apple App Store or the Android Market.

DrupalCon Denver 2012 - I am a Speaker!


Rails equivalent of pathauto in Drupal for SEO Friendly URLS

One of the things I like about both Drupal and WordPress is that creating SEO-Friendly URLs is very easy. Instead of having your URL be (or worse,, you can have

With WordPress, it’s basically out of the box with permalinks, though I don’t usually pick the default format. Drupal requires an additional module called pathauto, but once you add it, it works pretty painlessly. I’m sure there’s some tweaking involved somewhere, but it works fine for me on a few Drupal 6 and Drupal 7 sites.

Working with Rails, it’s not quite as easy. I’m using ActiveAdmin as a back-end (instead of ActiveScaffold or RailsAdmin), so I wanted to make sure anything I picked would work with it. Friendly_id was my first choice after taking a look at a few contenders.

Installing it was pretty straightforward, just following the directions, and adding a new migration for my “slug” column. In Friendly_id, slugs are tokenized versions of any other column, in my case name. Ran into one weird problem by not specifying the exact version of the gem in my Gemfile, but once I added that, things worked.

One nice thing is that I didn’t have to muck with my routes at all for this to work with Rails 3.1.

Drupal Planet Talks

Building Mobile Apps with Drupal – Drupal Camp Austin

I spoke at Drupal Camp Austin about developing mobile apps on top of Drupal. Most of the talk was about PhoneGap, but I also covered configuring the Services module to set up Drupal to serve content to mobile apps.

I’d love to hear your thoughts on Drupal as a back-end for mobile apps, and using PhoneGap with HTML5, CSS, and JavaScript to build mobile apps for Drupal.

The talk was recorded on video, and after it gets posted, I’ll put it up on this blog as well!


Speaking about Mobile Apps at Drupal Camp Austin

On November 19, I’ll be presenting a session at Drupal Camp Austin called Building Mobile Apps with Drupal on how to create mobile apps with Drupal as a back end.

I gave a talk on this topic at Dallas Drupal Days in July, and focused on native app development for Android and iOS , with just a little about PhoneGap for building a hybrid web/native app. Turns out everyone seems to be interested in PhoneGap/HTML5/CSS/JS apps for Drupal, and not so much building native apps. So for this presentation, I’m going to be talking much more about PhoneGap and how to use Drupal with it.

The number one use case everyone seems to have is that they have a Drupal site, and they want their users to be able to take a picture on their phone and upload it. This actually turns out to be pretty straight forward with PhoneGap, a little less so on the Drupal side.

I’m working on the presentation now – it’s not going to be the same as the Dallas one for those of you who have seen it on SlideShare (or in person 🙂 )

Facebook Development

Facebook Open Graph Developer Day 2011

Notes from the Facebook Open Graph Developer Day in Austin on November 2, 2011

Spent a productive day listening to Facebook presentations around the changes and improvements to Open Graph that were announced at f8 2011. Facebook is really pushing for the vision of the Semantic Web that has been around for years, using their Open Graph syntax. Really interesting to see how they are working with nouns, verbs, and aggregations – the new Facebook Timeline is a perfect fit for my EveryMarathon marathon calendar app.

Much of the presentation was targeted to information I’d already seen after setting up Open Graph for marathons, but it was nice to see what Facebook was letting app developers do with Aggregations and Achievements.

Improved authentication dialog:

  • Show the users what Timeline aggregations they’ll be doing
  • Find conversion percentages based on which actions you ask to allow


Can show min or max of items in the array – can also pluralize so, “Jeff has finished 1 marathon” or “Jeff has finished 55 marathons”

Facebook for Mobile:

  • Bookmarks go to mobile web site from, native apps on iOS and Android – configure in your app settings under Native Mobile Apps
  • Open Graph works with both
  • Should be able to publish Open Graph actions to timelines that then point to an existing mobile app or mobile web site.

Next Steps for Mobile Apps:

  • Integrate Single Sign On into native app
  • Create a mobile web app
  • Can use Facebook plugin for Phone Gap for mobile web apps
  • Configure mobile web URL in the developer app
  • Build in your social components

Cloud Services

  • Facebook set this up so that you can publish your Open Graph data on a server so their crawlers can access it
Drupal Planet Phonegap

Easier Drupal Plugin for PhoneGap iOS Installation

There’s been a lot of buzz about PhoneGap this month – the project just released version 1.1.0, the open source project is moving to Apache, and the parent company, Nitobi, was acquired by Adobe.

PhoneGap provides an easy way to make web pages into native mobile apps by wrapping HTML, CSS, and Javascript with an iPhone, Android, Windows Mobile, or Blackberry application. PhoneGap plugins provide services that web apps can’t get, such as interfacing with the phone’s camera.

For Drupal web sites, this means that if you add a mobile theme to your site, you can wrap your site with PhoneGap and have a mobile app. There’s certainly more you can do with mobile and PhoneGap, but that’s the easiest thing to do.

It gets a little trickier if you want to build an actual mobile application that isn’t just your Drupal site, re-skinned. You can certainly write JavaScript that talks to Drupal Services, but it’s pretty painful to write and debug. I wrote a PhoneGap plugin for Drupal for iOS that makes this much easier.

I just finished testing out the plugin on PhoneGap 1.1.0, the latest release, and it works great. I think the biggest frustration will be PhoneGap’s new whitelist feature for only allowing access to certain domains through your app. You will specifically have to add any domains that you retrieve content, images, JavaScript, or CSS from. For instance, if you use an externally hosted jQuery.

I cleaned up the installation process for the Drupal Plugin by forking two open source projects that the Drupal Plugin for PhoneGap relies on: the Drupal IOS SDK  and ASI HTTP Request and making all of the changes that you previously needed to make yourself in my forks.


Deploying Tweeter Keeper on the Heroku Cedar Stack

To go along with my talk at the Lone Star Ruby Conference on Consuming the Twitter Streaming API with Ruby and MongoDB, I’m going to provide some deployment instructions for how to take the Tweeter Keeper ruby script and deploy it on Heroku.

Heroku provides a managed platform to run Ruby applications (not just Rails), which we can use to run Tweeter Keeper “in the cloud”. Currently, you can run one process on Heroku for free, and you can get a free MongoLab account through Heroku as well if you want to experiment with the Twitter Streaming API.

Your first step will be to sign up with Heroku and create an account on their web site.

Make sure you have Ruby 1.9.2 – the easiest way to do this is to set up RVM, if you haven’t already.

Next, go ahead and install the Heroku gem so you can interact with the Heroku platform from your command line.

Tweeter Keeper has Gemfile and Gemfile.lock setup already for Bundler, so you should be able to run bundle install from your command line, and then bundle exec ruby tweeter-keeper.rb to run the app. Be sure to set up config.yaml with a valid Twitter account’s username and password.

Tweeter Keeper isn’t a web process – it’s a command line tool that you run with bundle exec. Heroku’s Cedar Stack has support for specifying processes within your Procfile that your application can execute. Here’s the Procfile for Tweeter Keeper (just one line):

tweeterkeeper: bundle exec ruby tweeter-keeper.rb

If you need to run multiple processes (for instance, a companion web application in Sinatra or Rails), add it to the Procfile.

We’re going to use the Cedar Stack from Heroku – this isn’t currently the default, so you’ll need to specify it when you create an application on Heroku. Heroku’s Cedar Stack relies on bundler, so make sure everything’s working ok on your local development environment first.

heroku create --stack cedar

Heroku will create a new application for you, with a crazy name (that you can easily rename).

You’ll need to configure a MongoDB add-on service from the Heroku add-ons – I used MongoLab, but you can also use MongoHQ.

heroku addons:add mongolab:starter

You use git to push your code to Heroku – add your Heroku git repo as a remote:

git remote add heroku

And then go ahead and push your code out!

git push heroku master

Now see if your process is running on Heroku:

heroku ps

You should see something similar to:

Process       State               Command
------------  ------------------  ------------------------------
tweeterkeeper.1  up for 9h           bundle exec ruby tweeter-keeper.rb

To see if your tweeter keeper process is keeping tweets, go into the add-ons section for your project, pick MongoLab, and select your MongoDB collection – it should be filled with Tweets!

Ruby Talks

Speaking at the Lone Star Ruby Conference Today

I’m speaking at the Lone Star Ruby Conference today on the Twitter Streaming API.

Check out the source code on GitHub –

Here’s the slides from the presentation: