• Synchronous vs asynchronous networking programming

    When I first started learning how to write code, everything I wrote was done sequentially with some goto loops; it waited for input, did something and then waited for more input. When I started writing network code on Mac OS, I had to fumble through Universal Procedure Pointers (UPP) in order to wait for connections and not block the user interface. Now that we're into the golden age of Mac OS X and iOS, those days are behind us. Most network programming is done with NSURLConnection either the synchronous or asynchronous calls.

    The synchronous call

    + (NSData *)sendSynchronousRequest:(NSURLRequest *)request
    	returningResponse:(NSURLResponse **)response
    	error:(NSError **)error

    is quite easy to use as it simply returns an NSData object. Anyone that has done iOS programming knows, you absolutely cannot use this call on the main thread as it blocks and won't return until it times out, errors out, or returns data. The iOS watchdog timer will kill an unresponsive application as outlined in an Apple technote.

    So what many developers do is either wrap this call in an NSOperation or simply perform it on a separate thread. This allows the user interface to be responsive and won't get the application killed by the watchdog timer.

    However, this is probably not the best way to handle network calls and I'm kind of disappointed that Apple has even provided the method. There are a number of things that the synchronous call can't do (even in a background thread):

    • Requests can't be cancelled. Once you issue the call, it only returns when it times out, when it gets an error, or gets the data back. There are many cases where you want to cancel a request; for instance, if you're loading a bunch of images and a use exits a screen, you should cancel the outstanding requests.
    • Authentication can only be specified at the start of the call. Using NSURLProtectionSpace, the authentication can be specified as part of the request. If you want a user to enter a username/password based on an HTTP 401 error, you can't do this with a synchronous call.
    • Responses can only be handled at the end. For instance, redirect (page moved requests) can't be acted upon until all the data is downloaded whereas with an asynchronous call, you get the response once the header is downloaded. A former Apple engineer, Jens Alfke, wrote that basically the synchronous call treats many response as errors instead of recoverable conditions.

    The first point is my biggest problem with the synchronous call and people might say that if you never want to cancel the call, who cares? That seems a bit short sighted to me.

    Using the code that Dave Dribin wrote on concurrent NSOperations you can easily construct a nice asynchronous networking class and queuing mechanism. I've done this twice and there is no reason that I can think of to still use synchronous networking calls on iOS.

    I'm sure that some people will argue with my logic and that's fine. I've been writing networking code for my entire career and while I'm not going to claim to be an expert on it, I've seen good and ugly (mostly written by me). The synchronous calls look quick and dirty while the asynchronous calls look like a lot of work. I agree with a friend of mine when he said in a StackOverflow discussion that asynchronous calls were the "The Right Way".

    In fact, asynchronous networking calls really aren't a lot of work. I was scared of asynchronous networking calls until I started writing Objective-C code; you just have to structure your code with delegates and handle the callbacks. I believe you should do this wrapped in an NSOperation to make sure that you only have a few networking calls outstanding at a time (you really only have so much bandwidth so trying to flood the channel with calls isn't going to be all that effective). In addition, this will help properly display the network activity indicator on iOS.

    Can anyone think of a reason besides "it's easier" to use the synchronous version of NSURLConnection vs the asynchronous call?

  • Losing a customer

    When I setup the DBA for my company, Gruby Solutions, I went ahead and found a free business checking account with Washington Mutual. While I didn't need a bank account as my company is a sole proprietorship, I figured it would look more professional and could have some benefits down the line. When Chase bought Washington Mutual, the free account transferred over. When my wife was looking for a bank account for her business, she also chose Chase.

    Things were fine until last month when Chase sent us letters saying that they'd start charging us $15 per month for our accounts, but with a minimum balance of like $5000 or a large number of debit card transactions, the fee would go down. As my company isn't bringing in any money right now, I decided to simply close my account. My wife, on the other hand, needs her account for her business. She did some research and found that Comerica bank offered free business accounts; there is a branch pretty close to our house, so it was a no brainer for her to also start the process of closing her account. (They do charge for allowing us to hook Quicken to it which annoys me as I've gotten used to downloading transactions from my bank.)

    While I understand that Chase probably considered us freeloaders, they lost 2 banking customers that will likely never return.

  • An exercise in frustration

    When I was training for the 2 marathons I ran, I listened to audiobooks to pass the time as training runs could last for hours (it takes awhile to run 20+ miles on the long runs). I bought a number of books from Audible.com. Once I stopped training, I couldn't justify the monthly cost for audible, so I switched to listening to podcasts on my runs. The other day, my dad showed me how he checked out an audio book from the library to listen on his iPod Touch. It looked promising, so when I got home, I went to the San Diego Public Library Web site and browsed to the eCollections link. I found a book that said it could be played on the iPod, so I checked it out and installed the OverDrive software on my iPhone.

    Safari.png

    Unfortunately that's where the easy part ended. After a bunch of frustrating tries and re-reading the help information, I realized that the OverDrive software only played MP3 files. Well, I can use iTunes on my iPhone to do that, so what good was the software? There is a button on there labeled "Add Website" which implies it would make it easier to download directly on the device. I tapped on it and it launched Safari on the iPhone. Lovely. After more searching and reading reviews about the software, I came to the conclusion that the software was almost useless. I would have expected that I could enter my library card number and PIN, browse for books on the device and listen to any available audiobook. That's not what happens; the OverDrive folks didn't implement a WMA player that handles the DRM used on the books, so it would only play unprotected MP3 files.

    I almost gave up on the concept of listening to checked out audiobooks on my iPod that I use for running or iPhone when I decided to install the OverDrive software in Windows 7 in VMWare (remember I'm a Mac user). The software offers an option to transfer the audiobook to an iPod. Hmmm...my iPod is Mac formatted and the documentation said it had to be Windows formatted. I didn't want to do this and dug into my box of cables and stuff and found an old iPod Nano. I plugged it in, grabbed iTunes for Windows, reformatted the iPod and started the process to transfer the audiobooks to the iPod.

    I'm not going to get into the nitty gritty of what is going on, but using the software in the manner it was intended, I was able to transfer unprotected audiobooks to my iPod and iPhone. Wow, this is a huge hole that isn't the same as the analog hole. Either this is a significant oversight or a deliberate choice that the audiobook publishers have decided to accept.

    The process of checking out these audiobooks was quite painful despite reading all the FAQs and me being a software engineer. My dad figured it out much faster than I did, so maybe I over analyzed it or my dad wasn't as discriminating in his choice of books. Our library offers 100 audiobooks in MP3 format which I could have used with much less frustration while it offers 1784 books in WMA format (most of it protected so that it expires after the lending period). I'm not sure how OverDrive has convinced over 13,000 libraries to adopt their system, but the system is almost unusable.

    Has anyone found the process of checking out audiobooks easy? It's almost worth buying them from Audible.com to avoid the dealing with this.

  • Review: MailHub (plugin for Mail.app)

    One of the things I do is "collect" software never knowing when I'll use it, but there are a small staple of applications I use all the time. When I saw MailHub, a plugin for Mail.app, I quickly downloaded it and played with it for a few minutes. I don't think I spent more than 10 minutes with it before I pulled out my credit card and purchased it! One of the problems with receiving so much email is what to do with it. I used to run rules on messages and kept having to setup new rules to move messages. This was inefficient for me, so dealing with messages as I read them seemed much more efficient.

    If you don't use rules in Mail, you have to use the mouse to move messages to different mailboxes/folders. For people like me that like to use the keyboard as much as possible, the process of reading a message, then moving my hand to the trackpad/mouse to file a message just wasn't attractive. With MailHub one or two keystrokes is all it takes to move messages to mailboxes. To top it off, MailHub has smarts that tries to figure out where the messages will go and it does a pretty decent job. MailHub does a number of other things, but the ability to file messages quickly is ideal for me. My inbox is now down to zero as I deal with messages quickly as I read it.

    The $19 cost for MailHub is peanuts as it saves me a significant amount of time. The plugin hasn't affected the stability of Mail and is quite integrated into Mail.

    Pros

    • Excellent integration with Mail.
    • Learns about where to file messages.
    • Easy to use keystrokes to file messages.
    • Low price.

    Cons

    • Every update to Mail requires a plugin update. Mail plugins are not supported by Apple and with Snow Leopard, Apple has added a version ID to each Mail release, so plugins have to get updated. MailHub has been updated to support the new Mail versions.
    • Only works with Mail. This really isn't a knock on MailHub, but I've started using Outlook for Mac to integrate with my work's Exchange server and I miss MailHub when using Outlook

    Summary

    If you use Mail on the Mac and get more than just a few messages a day, MailHub is definitely worth a look. There is a 30 day trial, but I suspect that you'll purchase it after just a few days. The plugin is well done and it's simplicity makes it a breeze to use.