Tuesday, September 28, 2010

Fun facts about Pilots

On a recent flight, I sat alongside a pilot who was returning home to the Seattle area. A lot of interesting things came up in my chat with the pilot, stuff I didn't really know about:
  • Pilots fly free on all domestic routes, regardless of airlines. All airlines have an agreement to lets each others' pilots occupy empty seats.
  • If no seats are available, the travelling pilot can also occupy an extra seat in the cockpit that is usually empty.
  • Pilots retire at 65(!).
  • The pilot I spoke with had been flying for 30 years. His pay/benefits today are half what they were 20 years ago (adjusted for inflation).
  • Until ~10 years ago, most commercial pilots came from the military (air force/navy). Now, it's about 50% military and 50% from pilot schools.
  • For pilots, career all about seniority. If this guy (a captain currently) were to leave his airline and join another airline he would start as a flight engineer. That's one level below first officer, who is below captain. This is a result of unionization.
  • Flights longer than 8 hours require 3 pilots (1 captain and 2 first officers) to rotate flying duties. Flights longer than 12 hours require 4 pilots (1 captain and 3 first officers). They usually fly 3-4 hour shifts.
  • Pilots at traditional airlines (American, Continental) make more than pilots at startup airlines (Virgin America, Jet Blue).
  • Airlines like Horizon Air/American Eagle/etc serve as training grounds for pilots, who then move to the more lucrative airlines.
  • On average, pilots fly between 9 and 14 days a month.
  • Pilots train on simulators every 9 months, and typically work on hard scenarios like dual engine failures once every couple of years.
  • Boeing and MD planes have "steering wheel" type controls. Airbus has fly-by-wire joystick like controls.
  • A 737 needs about 6000 feet to land comfortably. Headwind makes a huge difference in amount of runway needed.
  • Airbus planes felt more "robust" to this pilot.
  • Bird hits are more common than passengers realize.
  • Tegucigalpa, Honduras, is the hardest airport that he's landed in. Overshooting the 5000 foot runway drops you off a cliff and on to a strip mall. There have been 2 crashes in the last few years, with one dead pilot.

Thursday, September 9, 2010

Google Instant's biggest win? Teaching users to search better

The biggest impact of Google Instant is that it teaches users how to search more effectively. Based on these dynamic results, users can tweak their query such that it helps them find the exact answer they were looking for, even if they started with a bad query. Teaching users how to improve their search query is huge. The immediate impact is that it improves users' perception of Google's search results. Same with speed - users will perceive Google as being much faster than anything else out there because of the instant results.

Perception is reality. Speed and relevance are a search engines bread & butter. I think Google just upped the ante by a lot.

Credit to Microsoft though - this probably wouldn't have happened if it weren't for Bing's recent gains. Proof that competition provides the best kick-in-the-pants needed to innovate.

Friday, September 3, 2010

Integrating Core Data into your Three20 App

The Three20 library for iPhone app development is pretty cool - it take care of a lot of the 'mundane' code that you might need to write to accomplish basic tasks. Apple really should include some of the functionality of Three20 in the iPhone SDK itself, specially the Network stack.

As I built a more advanced app using Three20, I realized that it would be great to be able to persist to a database to make loading quicker when state on the server is unchanged. I needed some pretty basic Core Data integration in my app, and it was a little annoying that Three20 didn't have a Core Data-backed implementation of TTModel built into it. It seems like a lot of people want this, but there isn't any good post about it I could find. Jeff Verkoey, who currently maintains Three20, started writing a Core Data based tutorial but didn't get around to actually doing much with it. And there are a few threads in the Three20 Google group but nothing too comprehensive.

Having built this for my app, I figured I would post some more concrete information here for others who might find it helpful. I really want to just contribute a clean cut of this code as a TTCoreDataModel with unit tests to the Three20 source, but I don't have the luxury to spend time on it currently.

So here's a quick step-by-step on how to modify your existing Three20 based app to add basic Core Data support. The specific example I use fetches data from a server using TTURLRequestModel and writes it out to SQLite using Core Data entities. When displaying data to the user, it fetches data from Core Data using a NSFetchedResultsController, which efficiently interacts with Core Data.

Step 1:
Add CoreData.framework to your list of dependencies. Then, add the Core Data stack. Usually, you would do this in the AppDelegate. Jeff's AppDelegate files have this implemented, if you want an example. In my case, I wanted different databases for different Models, so I had these in my TTModel implementations.

Step 2:
Create your model. Add a new file of type "Data Model" in XCode (available in the 'Resource' section). Make sure the .xcdatamodel file gets added to your Target so that it's compiled into your binary. Look here for information on using the modeling tool. Once you've created your model, import the code for the Entity objects into your project. Now you're ready to start using Core Data.

Step 3:
Update your TTURLRequestModel implementation. Let's assume you're simply downloading some JSON and want to write it out to Core Data as an Entity you created in Step 2. Update your (void)requestDidFinishLoad:(TTURLRequest*)request implementation of TTURLRequestDelegate as follows:

A few notes about the code above:
  • DBResource is my simple entity containing an "id" and a "name".
  • The NSAutoreleasePool helps clean up memory allocated in this tight loop here
  • -reseting the context makes sure that the data faults in as needed instead of staying in memory when you read it using the NSFetchedResultsController
Step 4:
In your TTTableViewDataSource implementation, create a NSFetchedResultsController and configure it to fetch your Entities as needed. Then, override the (id)tableView:(UITableView*)tableView objectForRowAtIndexPath:(NSIndexPath*)indexPath method to return a TTTableItem built using the Entity you fetched from Core Data

Now, your TTTableViewDataSource is configured to read results from the DB you created and display them in your view. Remember that tableViewDidLoadModel can be called multiple times, so clean up any previously allocated NSFetchedResultsController if you need to.

Step 5:
Implement your logic to delete/update your Core Data entities. Depending on how your app uses data persistence, you want to ensure that you update/delete your entities from Core Data. For instance, if you always want to fetch data from the server and load them into Core Data on first run, then update Step 3 to first delete all entities. If you wish to show local data when available but fetch when not, then update Step 3 to not hit the server before checking locally. When deleting entities, remember that Core Data only lets you delete a single entity at a time (so you must fetch all and loop through each to delete it). If you want DROP TABLE ... semantics you're going to need to maintain different NSManagedObjectContent and NSPersistentStoreCoordinator for each such table, and then simply delete the database file.

So, this isn't too hard really. Assuming you're familiar enough with building your Three20 app, my notes above should help you get started with integrating Core Data into your app. My app uses a TTSectionedDataSource, and with a few tweaks to NSFetchedResultsController it's simple to do that too.