Last week I released my first iPhone open source project, Facebook Connect for iPhone, and today I'm ready to start talking about the next one. Five months ago I talked about open-sourcing as much of the Facebook iPhone app as I could, and as you can see by the delay, that has turned out to be easier said than done.
Developing an app and developing a generic library are very different goals. A lot of the code I wanted to release was not generic enough, used hacks that worked just well enough for my app, and was coupled with a Facebook-specific data model. So, one by one I've been redesigning and refactoring each of the components I wanted to open source, adding them to a new Xcode static library project, and then reintegrating them with the Facebook app. I just finished doing that a few days ago, and now I'm ready to start sharing the results.
The name of the new project is Three20, after the 320-pixel-wide screen of the iPhone. The code is all hosted on github for your cloning pleasure. There is an excellent sample app called TTCatalog which lets you play with all of the various UI components. Documentation? Well... there are instructions for how to add Three20 to your project, but I am still working on comprehensive documentation for each of the classes. For now, the sample app and the code itself are your documentation.
So, what kind of iPhone UI goodness does Three20 provide?
TTPhotoViewController emulates Apple's Photos app with all of its flick'n'pinch delight. You can supply your own "photo sources", which work similarly to the data sources used by UITableView. Unlike Apple's Photos app, it isn't limited to photos stored locally. Your photos can be loaded from the network, and long lists of photos can be loaded incrementally. This version also supports zooming (unlike the version in the current Facebook app).
This has probably been the single biggest timesink in the whole Facebook for iPhone project for me, so if I can help anyone else save that time I will sleep better.
TTMessageController emulates the message composer in Apple's Mail app. You can customize it to send any kind of message you want. Include your own set of message fields, or use the standard "To:" and "Subject:". Recipient names can be autocompleted from a data source that you provide.
Web image views
TTImageView makes it as easy to display an image as it is in HTML. Just supply the URL of the image, and TTImageView loads it and displays it efficiently. TTImageView also works with the HTTP cache described below to avoid hitting the network when possible.
Internet-aware table view controllers
TTTableViewController and TTTableViewDataSource help you to build tables which load their content from the Internet. Rather than just assuming you have all the data ready to go, like UITableView does by default, TTTableViewController lets you communicate when your data is loading, and when there is an error or nothing to display. It also helps you to add a "More" button to load the next page of data, and optionally supports reloading the data by shaking the device.
Better text fields
TTTextEditor is a UITextView which can grow in height automatically as you type. I use this for entering messages in Facebook Chat, and it behaves similarly to the editor in Apple's SMS app.
TTPickerTextField is a type-ahead UITextField. As you type it searches a data source, and it adds bubbles into the flow of text when you choose a type-ahead option. I use this in TTMessageController for selecting the names of message recipients.
HTTP disk cache
TTURLRequest is a replacement for NSURLRequest which supports a disk cache (NSURLRequest can only cache in RAM). It has some other nice features too. HTTP posts are as easy as supplying a dictionary of parameters. The TTURL loading system can also be suspended and resumed at any time, which is a great performance helper. Network threads often fight with the UI thread, so you can suspend the network any time your app is graphically intensive.
TTNavigationCenter is for those grizzled old web developers like myself who want to organize their app by "pages" which can be displayed by visiting a URL.
Your view controllers can simply register URL patterns that they handle, and when those URLs are visited the controllers will be created and displayed. You can also register generic actions that are called when a URL is visited.
TTNavigationCenter also persists and restores the full path of navigation controllers and modal view controllers, so your users can quit the app and come back exactly where they left off.
How mature is Three20?
As of today I would call this code alpha quality. If you attempt to use Three20 at this stage, be prepared for a little bugginess. While this code is derived from Facebook for iPhone 2.2, much of it has been rewritten, and that new code has not yet shipped in any app on the App Store. I am using Three20 to develop Facebook for iPhone 3.0, which is slated for early May, so things should be stable by then.
New open source projects are always exciting because you never know who is going to wander into your garden. If you have any questions, please email me!