• Running with an iPhone

    A few weeks ago I started listening to audiobooks again and became very engrossed in a James Patterson book. I was running with an iPod Nano and walked the dog with my iPhone as well as had my iPhone with me while driving. In order to keep my position in the book, I had to sync the Nano after my run, then sync my iPhone and then before my run, sync the iPhone and then the Nano. This got old real fast (a few days).

    I had been eyeing the Fisica Fitness Sensor Key for my iPhone to hook up my heart rate monitor for use with RunKeeper Pro. I couldn't resist as eliminating my iPod Nano from the equation would make my life easier. I received the Sensor Key about 10 days ago and did my first run the next day. RunKeeper Pro is a decent app that handles everything my Garmin ForeRunner 405 did and more.

    I thought that the weight of the iPhone 4 on my arm would be a problem (I also bought the case that Wahoo Fitness sold), but it isn't that bad. The Sensor Key does exactly what it is advertised to do; it connects Ant+ devices to the iPhone. RunKeeper Pro integrates the heart rate monitor fairly well, but displays the current heart rate in a very small part of the display (almost unreadable). The iPhone is a bit unreadable in bright sun, but the large display is nice.

    After a few runs with the iPhone, I can't see going back to my iPod Nano and Garmin ForeRunner 405. One of the best features that just came to light today was when I was happily running and the narrator of the book's voice started fading and the phone rang! I was quite surprised, but saw that it was my boss (technically my boss's boss) calling, so I slowed to a walk and answered the call. I don't get many phone calls, so being able to get a call when I take a midday run is a great feature of using the iPhone for running.

    If I had been running with my iPhone last month, I would have been able to take a picture of the guy who had put a rope around his Christmas tree and dragged it behind him to take it to the recycling place instead of putting it on the roof of his Ford Explorer!

    I'd like for RunKeeper Pro to add the ability to bulk export the files and then this combination would be perfect.

  • Mystery of poor iPad battery life

    Last week I started noticing that my iPad would go from 100% to about 10% battery life in one day with very minimal usage. This had me confused, so I decided to try 2 things to see if I could get the battery life back up. Unfortunately I tried both things in conjunction, so I'm not sure which one of the two made a huge difference. The first is I restarted the iPad. This sounds like a no-brainer, but I usually don't reset my devices. I noticed that I couldn't complete a call on my iPhone the other day, so I restarted it and it felt a lot more responsive; so I gave the iPad a restart to see if it would help.

    The second thing I did, which is kind of a "duh" is I turned off push notification, removed 1 email account, and switched to checking data every 30 minutes. The push notification system keeps a connection constantly open with Apple's server so that if a notification comes in, it can be sent down the already open pipe. This, of course, takes power to maintain this connection. However, I leave push on for my iPhone and I don't see a huge drop in battery life. There are, of course, many differences such as the size of the battery and I charge my iPhone every night.

    Well, my battery life is back up to several days of light usage and turning off push notification isn't a huge deal on the iPhone. I'm not sure if the reset or the push notification was the problem. If you start see declining battery life on your iPad try one or both of these tips; it might just help.

  • 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.