Since my provider doesn’t provide SSL, IMAP or a decent webmail reader, I decided to take the plunge today and switch to Google Apps for Domains.
Obviously it’ll take some time to see if it’s worth it, but so far I’m liking it. One thing that I was eager to do was move my email to IMAP to take advantage of it’s synchronization features. Seeing as how there are no free import tools from Apple Mail to GMail, I came with an ad-hoc approach that worked for my purposes:
- Archive your Mail inbox to a backup file and then delete your account out of Mail.
- Set up Mail to use your new GMail IMAP account and verify that it works.
- Import your backed up inbox to Apple Mail. This will create a new folder separate from your GMail stuff.
- This is the slow part. Drag about 300 messages at a time into your new GMail inbox folder. Mail will sync these new messages from your machine to the GMail servers while removing them from your import inbox. I had to go through about 3000 messages, so this took about an hour or so.
Your messages will appear in the GMail inbox in the correct date order, but if you sync with an iPhone, you’ll only get the most recently added 50 messages, which are most likely the ones you just imported and are quite old. To get around this, I found this technique in Google groups which worked like a charm:
In your inbox, select all messages (ALL, not just the first page!) Then give them a dummy label like “sort label”. Once you’ve applied this label only to the messages you want to be sorted in your inbox, select all inbox messages again and click “Archive”. This won’t delete your messages, just move them out of the inbox and into the “All Mail” folder. Once your inbox is empty, click on the label you made in the sidebar (e.g. click on “sort label”) to pull up those messages with that label. Then, select all (ALL) messages with that label, and in the drop-down menu above select “Move to inbox.” Once you do this, you can delete that label (it won’t delete your messages) and your inbox messages will now sort correctly on the iPhone.
Brent Simmons has a post up about the amount of polish and thought that goes into an iPhone app. It’s true—I’ve never put as much effort into the details of an application as I’ve put into the app I’m working on.
Case in point: the initial settings dialog that’s presented when a user first loads our app. This dialog gathers the user account information necessary to login to our service. It also persists the information into our root.plist file so it can later be edited by the iPhone settings application (I hate shunting our users to another application just to edit login credentials, but that’s a rant for another time).
Our initial architecture put a simple “Welcome! Enter your information, etc.” sort of message at the top of the screen and a group-style UITableView below it with cells corresponding to each user credential item (username, password, etc.) When the user touched a cell, we pushed in an editing view that allowed them to set the credential item. The editing view consisted of a single UITableViewCell with an embedded UITextView, and the iPhone keyboard for text entry.
The user interaction worked like this:
- Tap an item in the settings dialog to edit
- The app slides you over to the editing view controller and displays the iPhone keyboard to do your editing
- Tap the Done button in the upper right when you’ve completed editing.
- The app slides you back to the settings dialog and displays your newly edited item
So this worked fine. It was solid, gathered the data properly and got the job done.
But it bugged me that there had to be so much moving around just to edit these couple of fields. When I would debug the app’s initial load experience, I’d have to blow away the app each time on the simulator to go through this process literally dozens of times. And sometimes I’d forget where I was in the process and type in the wrong credential. Sometimes I’d get so tired of the whole back-and-forth process, I’d hardcode credentials for the debugging session just to avoid having to enter into the dialog at all.
Warning bells. This was a point of friction in the interface. A small point, but frustrating for me. True, I was going through the process dozens of times, but it still bugged me. If I was having these issues as the developer of the application with a debugger in front of me, our users would be guaranteed to have issues. Not showstopper-type issues, but I’d hear about it.
So I took a few hours yesterday and did something about it. I decided that our screen should work almost exactly like the iPhone settings app—if a user interface works and works well, copy what it does.
I reworked the editing mechanism. Gone is the movement to a separate screen for editing. In it’s place are text fields embedded in the table view cells that are activated when the user taps a credential item in the initial screen, allowing for in-line editing of this information. This brought up a second problem. When the user tapped on a field toward the bottom of the screen and the iPhone keyboard was displayed, the keyboard hid the field. This was a stumper. No amount of calls to selectRowAtIndexPath:animated:scrollPosition: would work. Finally, a bit of googling revealed this gem by Matt Gallagher to get me over the top. The view would now automatically scroll to display the selected field if it was occluded by the keyboard.
So the final result? Let’s check out the user’s interaction with this dialog again:
- Tap an item to edit
- iPhone keyboard slides up and you edit the item
- Hit return or select another field to continue, or hit the “Save” button to exit the dialog altogether
That’s around 1-2 fewer steps, with the added bonus that users have a very clear context in their minds of what they’re editing—something which they didn’t have when they were forced to another screen each time to edit a simple text field.
I never would’ve done this with a desktop application. It wouldn’t have been an issue. Need to gather user information? Put together a dialog with the correct number of text fields, some labels and an OK button and you’re done. Not enough real estate? Resize the canvas.
Not so with the iPhone. Since the platform is so limited, the thought you put into an interface affects your users an order of magnitude more than it would on a desktop app. It’s a bit like a fractal—the deeper you think about your user’s interaction with your app, the more interaction scenarios you uncover, the more code you write to handle these interactions, the more rewarding your app is to use.
There are a few things I think are essential to being a good developer. I'm probably parroting Joel Spolsky here, but I wanted to get them down while they're fresh in my mind:
Exposure to more than one platform and language
If your only experience is with one language on one platform (i.e., perl on Linux, C# on Windows, etc.), this is a signal to me that you're inflexible and not willing to stretch yourself to do new things. It's definitely uncomfortable to do try new languages and OSes, but that's the only way to stretch yourself and get better.
Exposure to pointers
Lack of exposure to pointers is one of Joel's pet peeves and I've adopted it as one of mine as well. Where I went to school, Java was the language of choice for freshman year CS courses. This was a bad decision since the first sophomore year course was Architecture and Assembly language, something which Java does precious little to prepare you for.
When I first started in industry, my first language again was Java and then C#. Another bad experience, since this left me with a rather steep learning curve for my next experience, working with low-level C++ code on HP-UX. But, to tie in with my previous point, I specifically went after this position because I saw a gaping hole in my experience and wanted to fill it in. And I'm much better off for it. I'm confident with my feel for how memory is being managed and manipulated during the course of a program's execution, be it managed, unmanaged, embedded or desktop.
But I sure wish I'd had the low-level introduction to C in my first year as a CS student.
Exposure to things that are not code
I'm talking about documentation, gathering requirements, interacting with users and customers, creating a design document or diagram. These are the things that you will most certainly not learn in college, and they're definitely not as fun as just coding all day, but they're essential to being anything more than a coding monkey.
There's probably more that I'm forgetting, but if I'm going to interview you or be interviewed by you, these are the big things I'm going to be looking for besides competency with your hard skillset.
I'm taking it upon myself as part of my ongoing community service to educate the public about the different sorts of donuts out there and their relative merits. So, here's a quick summary:
- Krispy Kreme: Famous for their hot glazed donuts and nothing else really. They possess a light, airy texture and aren't overly sweet or doughy.
- Dunkin' Donuts: Basic donuts for when you're in a bind and need one quick. Not a lot positive to say here. Cakey, mass-produced and not very good. My personal favorite is their jelly, which is usually pretty generously filled and covered with a healthy dose of powdered sugar. I really wish Dunkins would divert some of their resources from developing new 1000-calorie monster flatbread sandwiches to developing a better donut.
- Honey Dew: See Dunkin' Donuts
- Grocery Store Donuts: Don't. Just...don't.
- Top Pot Doughnuts: My current favorite. They started offering these at Starbucks a year or so ago and quickly ascended to the top of my list. When consumed cold, you're basically eating a rock, but a warmed-up Top Pot is something to savor. Plenty of texture, and very filling. Their chocolate glazed leaves something to be desired, however. It lacks any sort of chocolaty flavor and tastes more like their plain glazed version only...off somehow.
Still on my list to try: About a million mom-and-pop donut places in greater Boston, including Verna's in East Boston.
Watch this video.
It’s somewhat disturbing for me to think that the young people of our country can’t do basic math, but then they sky seems to be falling on our mathematics education standards with the start of every new school year. I wonder if I should start administering a basic math skills assessment when I interview potential engineers.
The basic problem here seems to be lack of class time. The meteorologist in the video states that children don’t receive enough teaching on the basic algorithms of mathematics—how to perform double digit multiplication, long division, etc. The curriculum she rails against instead teaches more abstract approaches to solving these problems—breaking down a long double digit multiplication into smaller pieces and then adding those pieces up, for instance.
I’m of two minds about this, as with most things. I agree that not teaching children so that they can evaluate math problems mechanically with a foolproof algorithm so that they can be guaranteed to arrive at the correct answer seems to be a mistake. It’s creating a culture where nobody can do arithmetic anymore without a calculator and that clearly isn’t a good thing.
On the other hand, only knowing how to mechanically solve problems doesn’t prepare children for the inevitable moment when they encounter a problem that doesn’t fit into the algorithm, a problem that requires more analytical, critical thinking. I solve both types of problems every day as an engineer, and we need people who can handle both.