Found: The Best iPhone Development Book So Far

Want to write your own iPhone applications but Objective-C, XCode, Interface Builder, and the steep learning curve of Cocoa getting in the way? Have I found the book for you.

Warning: long and geeky post follows — iPhone wanna-be developers, read on!

Beginning iPhone Development - Exploring the iPhone SDKI’ve found it, finally, the best iPhone development book so far! Read on to see why.

Fairly recently, I decided to turn my attention to native iPhone application development, but I found the arena a little sparse when it comes to what I’d call good documentation.

For some perspective, I’m a software developer of 20+ years with background in Unix and Windows; I’m very well versed in C, C++, C#, and Java, among a good number of other higher-level languages, having produced a number of enterprise applications.

You’d think that picking up Objective-C and the Cocoa Touch frameworks would be a fairly simple task. However, the moment you step foot into the pool, you’re get a cold shock at how much you don’t know and it can feel daunting enough to want to retract back to familiar territory.

Don’t give up. It is easy.

Looking forward into the unknown presents a much more gloomy impression than when you’ve taken a few steps and looked back to see just how far you’ve come and in such a short period of time.

Here’s what’s happening: The Apple Frameworks represent a large and mature collection of some impressive code. The closest experience I’ve felt to it, and this is admittedly a horrible analogy, is Ruby on Rails.

With Rails, there’s so much going on by convention that you have to sling very little code to get impressive things to happen. This makes it hard to understand: there is no code to trace.

Same way with the Apple Foundation classes that are based on NeXTSTEP — a lot is handled for you, and often in new ways you might not have thought about because of limitations of other platforms, so that very little code is required to do something quite impressive. The problem is figuring out what that code is you’re supposed to write, and more importantly how’d you know to go about doing that in the first place. Hint: knowing the Foundation Framework is important to understanding the Cocoa Touch Framework.

This leaves one in the lurch that the sample code appears rather sparse, and the framework documentation overwhelming, with little guidance on how all the pieces fit together into a simple, cohesive whole. The problem is all too common.

My biggest gripe with many frameworks, especially Java and it’s auto-generated documentation, is that all you’re really presented with is a list of method signatures with very little discussion about what they do, purpose and limits to the input values, discussions of side effects, the importance of call order, and so forth. With other languages, you’re lucky if you can find the header file to include or the library file to link against. It’s all just expected that you somehow know this, and that doesn’t work when you’re learning a framework, though it’s fine if you just need a reference.

Apple’s online documentation is certainly comprehensive, but the reality is you’re going to be watching videos and reading tons of documentation, picking up crumbs of useful bits as you go. The cohesive moment of comprehension will come, but it will be a long and slow ride. You want something faster.

If you’re learning Objective-C at the same time, the ride is extra bumpy, because not only are there just a few language extensions sitting on top of C, but the ObjC library is actually doing some clever work that you want to know about, and this has additional implications because there’s a lot of convention going on as well. Further obscuring things is the fact that, due to historical reasons, the terminology you are most likely already familiar with doesn’t map nicely. A nice look under the hood solves this. Objective-C isn’t just some new keywords, it’s new application behavior.

What’s Wrong With Other iPhone Books At The Moment
As of early 2009, you’re going to find few iPhone books out there. Most of what exists is for the hacked version of the iPhone, and while that may even sound useful, the tearing apart of the SDK is rough and incomplete, not to mention the implementation to call is painful. This just isn’t applicable to the real world constraints of native mode development.

Think you can get by with a slightly out of date copy of a Cocoa book? Think again. The UIKit framework is just different enough that your approach needs to be slightly different. Tight, efficient, resource management becomes very important.

Also, unless you already know and understand Interface Builder, it can be a hard time following along when your book doesn’t match your software version. Apple keeps modifying Interface Builder, making it better, but the changes can come across as so dramatic, interface-wise, that to the new comer it looks like a totally different application each revision. Once you “get it” the sweeping changes are cognitively transparent. The iPhone SDK includes, you guessed it, a new XCode and Interface Builder.

What few modern iPhone books there are out there jump straight into a technical feast of SDK details, leaving the reader with a learning curve that’s as vertical as a brick wall.

What’s needed is a book that introduces only what you need to know, when you need to know it, explaining tips and tricks along the way, delving into the philosophies of why things are the way they are, what the developers were thinking, how the frameworks are structured, what the conventions are, and when those conventions aren’t followed. And, instead of showing you the end solution all refactored into a neat package, take the long way, when needed, to introduce you to what’s going on and then evolve into the optimal solution.

I’ve Found Such A Book!
The book, by Apress, is called Beginning iPhone Development – Exploring the iPhone SDK by Dave Mark and Jeff LaMarche. This book is about the fundamental concepts you need to understand in order to make the frameworks do their magic.

Its tutorials are very well constructed, easy to follow, and are specifically designed to teach the framework in such a way as you understand what’s going on and learn to fish for yourself.

This is in stark contrast to substandard books that merely cover a framework’s capabilities with cut’n’paste examples that have little bearing to real applications. This alone gives is five out of five stars by my standards.

My only complaint is a minor nit that there are a small handful of typos, and unfortunately, they happen in the code examples. However, they’re glaring, and you won’t get tripped up by them. (For example, on page 85, the tutorial is about UIImage. And, UIImage appears four times in a six line sample. The first one, however, says “jmUIImage” and the indentation is off. It looks like a macro expansion, a note, or the mangled initials of one of the authors. The code won’t compile with it, and it’s obvious from context what it should be.) To me, this is forgivable. Especially since it’s rare.

Tagging 1430216263I want to show you something.

I have a habit of tagging my books when I find an exceptional piece of information that I haven’t found elsewhere. I give a book high marks if it earns somewhere between three to seven tags, as the majority of my collection never gets any tags. Tagging, for me, is not note taking — it’s rare event.

I think the picture speaks for itself.

For Example…
So, at this point, I present for my own edification and future reference, some of that tagged content. Who knows, maybe something you see here might just get you traction on the learning curve.

– In Objective-C, colons are a legal character of the method identifier, they are not syntactic sugar.
– Even though a number of macros translate to nothing, void, zero, or null under the hood, their presence provides important hinting for data types and method calls.
– The NIB’s File’s Owner is a place holder for the class that loaded the NIB file.
– The NIB’s First Responder is the object the user is currently interacting with.
– The application icon is a 57×57 .png file, see Info.plist’s Icon File.
– The iPhone specially optimizes .png files so this is the best format.
– Reset the iPhone Simulator by deleting its directory from ~/Library/Application Support
– You want to use @property (retain, nonatomic) as often as possible.
– Interface Builder uses your defined accessors to properties, which use retain; that means you do need to deallocate Interface Builder objects, even if you didn’t instantiate them.
– There are four control states on a control, often you want UIControlStateNormal.
– Learn to use retain/release, there is no garbage collecting on the iPhone.
– It’s better to init/release than using factory methods; factories use autorelease pools, and while this will work, it often keeps resources around longer than you intend — avoid autorelease pools.
– Hog too many resources, whether CPU or memory, and the phone will reboot.
– Everything from UIApplication on down will fire messages to Delegate objects at certain well-defined times, you need to learn what these times are and what messages are sent; it’s not just subclass avoidance.
– You can Option-Click on a class or interface name in XCode and go right to the documentation.
– You can press ESC to cause auto complete to happen immediately.
– Command-equal_sign will size a control to fit.
– When you’ve got a lot of control hierarchies going on, use the View Mode button to see them as a list.
– Scaling an image takes computational overhead, avoid if you can.
– Set the Alpha slider to 1.0 in order to optimize the drawing sequence, it skips looking at the underlying background and factoring it in — it applies to the image drawn.
– Also set the Opaque checkbox in order to optimize the drawing sequence, it skips drawing the underlying background for the parts where the image is transparent.
– The Tag control allows you to assign a numerical identifier to controls to locate them later.
– You need to handle the Did End on Exit event in order to make the keyboard go away.
– You may also need a huge, invisible, custom button as well to make the keyboard go away.
– In XCode, use Option-Command-up_arrow to toggle between a header and its source file.
– In the Interface Builder, move the cursor over a view and hold down Option to see how many pixels there are between the item and its superview.
– Option-dragging a control in Interface Builder makes a copy.
– Nifty buttons are actually stretchable images, and Apple has buried a ton of them free for your use in the UICatalog sample code on their site.
– There are three different ways to handle layouts when rotation happens: autosize, reposition, and view swapping.
– The rotation callback passes you the orientation the phone came from, you need to use other means to get the current orientation.
– If you want to use Core Graphics, for things like view transitions, you need to link the framework into your application.
– Some frameworks, like Core Graphics, have one version for the iPhone hardware and one version for the iPhone Simulator.
– If you use the correct parameters, XCode’s build process can play games with the path and always target the right framework (use Relative to Current SDK, and do not select Copy items).
– Right-click the Resources folder and use Add / Existing Frameworks… to do this process in a safe way.
– If a view isn’t shown, it’s superview is nil.

…there’s plenty more, but you get the idea. The book is jammed with all kinds of useful things to someone who is new to iPhone development. This presentation of material makes the learning curve very approachable.

And, once over that hurdle, all those other books that I said were problematic suddenly make a whole lot of sense.

This book is the best first step I’ve seen in the journey to writing iPhone applications. Period.

Walt gives “Beginning iPhone Development” two thumbs up, five stars our of five starts, and a head nod of appreciation to the authors. Well done, guys. Well done.

OS X Mail’s Strange Log Messages

A while back I installed a pretty neat Mail extension called MailTags, which was used to tag mail messages with additional information. Cool concept.

However, at the time the usage I was personally getting out of it didn’t warrant the price for the app, and I uninstalled the application after the trial period was over.

Unfortunately, things didn’t end there, because I kept getting repeated log messages like this when I looked at the console:

1/1/09 2:52:05 PM Mail[362] Cannot restore width of table column with identifier 24

It was really obvious (and annoying), as I use GeekTools to monitor my console on my desktop in order to keep a bird’s eye view on what’s happening in the background.

I found out that I was not the only other user having this problem, and the MailTags site had a solution invoked from the Terminal:

$ defaults delete com.apple.mail TableColumns

I’d done this before, but the problem resurfaced. Not sure why. And, doing it again seems to have fixed the problem, again. My log is back to normal.

Meanwhile, I discovered that that MailTags has a new version out, and perhaps I’ll give them a second chance.

I just tend to get worried when an extension appears to go deep, especially when we know Apple is about to revamp things with the next release of the OS, and cruft somehow got left behind before.

Garmin WebUpdater

I own a Garmin GPSmap 60CSx in order to geoencode my photography using HoudahGeo.

Garmin now has a means up updating the firmware in their GPSs by using a WebUpdater, of which I use the version for the Mac.

I Got Myself Into Trouble
In retrospect, I got myself into trouble by starting the program, it failed to detect the GPS, to which I turn on the GPS, and plugged it into the USB port. While the WebUpdater saw the device and went to update, it stayed in the “Erasing… Do Not Unplug” state for about two hours before I got brave.

What I Did, And Boy Was I Lucky
I couldn’t cancel. I couldn’t Quit. So I had to Force Quite by using Command-Option-Escape, that at least got WebUpdater to stop. The GPS was still stating “Loader Loading…” when I pulled the USB, and when that didn’t change anything, I turned off the power to it. I wasn’t so sure I was going to see much of anything when I powered it back on.

I got lucky. I turn the power back on and I was still at the old revision. Then plugged in the USB to the computer. Then started WebUpdater, which again noticed the GPS version, downloaded the firmware again, and had no problems installing it. Seems doing things in this order works just fine.

My Plans If I Was Unlucky
Over on Bill Turner’s site, he’s written an article about Fixing a Dead Garmin GPSMap 60CSx. It seems he’s learned holding down the Power Button and the Up Arrow at the same time while starting the WebUpdater software (I think he has three hands to pull this off), he’s able to force the GPS to identify itself to the updater. Problem is, according to his instructions, you have to keep holding down these button chord during the update; some comments on the blog state it isn’t necessary, and there’ve been mixed results as to whether this works universally or not.

I’m not sure I would have had the bravery to just go killing processes plain outright, but since Bill did such a nice job of providing an alternative, I felt it was worth the risk — even if I didn’t have to go that route. Thanks Bill for blogging your GPS recovery notes.

LIBLDAP2 Not Installable

Unable to find a solution related apt-get failing on Ubuntu while trying to upgrade packages depending on the libldap2 (>= 2.1.17-1) package, I figured out what was causing the problem… additional repositories in my /etc/apt/sources.list file. Here’s what I did to finally be able to upgrade cleanly.

Warning this is a very geeky entry aimed at apt-get users of Ubuntu, readers seeking humorous content should skip this post. Remember, this is a technical blog.

If you’re still with me, then I suspect you’ve just been plagued by the message:

Depends: libldap2 (>= 2.1.17-1) but it is not installable

I’m using Ubuntu 8.04 LTS Server Hardy Heron, specifically on a 64-bit AMD system.

Normally, when I do an $ sudo apt-get update things go very smoothly, but not today. Here’s what I got.

The following packages have been kept back:
alpine dovecot-common dovecot-imapd dovecot-pop3d libpq5 postgresql-8.3 texlive-base-bin trac

The following packages have unmet dependencies:
alpine: Depends: libldap2 (>= 2.1.17-1) but it is not installable
dovecot-common: Depends: libldap2 (>= 2.1.17-1) but it is not installable
Depends: libpq4 (>= 8.1.4) but it is not installable
libpq5: Depends: libldap2 (>= 2.1.17-1) but it is not installable
postgresql-8.3: Depends: libldap2 (>= 2.1.17-1) but it is not installable
texlive-base-bin: Depends: libpoppler0c2 (>= 0.4.2) but it is not installable
trac: Depends: python-genshi (>= 0.5) but it is not going to be installed
E: Broken packages

Unfortunately, where ever I went, I didn’t find a solution. [1] [2] [3]

The ‘recommended’ solution is: $ sudo apt-get -f install
This did not work for me, nor others.

Neither did: $ sudo apt-get dist-upgrade

At this point, I went on an apt-get remove and apt-get autoremove binge. This didn’t help either.

This got me into a horrible loop, where packages sysvinit-utils, sysvinit, and initscripts needed to be installed, but could not because:
Unpacking sysvinit-utils (from …/sysvinit-utils_2.86.ds1-47~bpo40+1_amd64.deb) …

dpkg: error processing /var/cache/apt/archives/sysvinit-utils_2.86.ds1-47~bpo40+1_amd64.deb (–unpack):
trying to overwrite `/usr/share/man/man1/mesg.1.gz’, which is also in package sysvutils

I even tried manually installing packages one at a time. Didn’t work. I was even so desperate as to move the file mesg.1.gz elsewhere. That didn’t work.

Then I tried the following and things got a little better:

$ sudo apt-get clean
$ sudo apt-get autoclean
$ sudo apt-get check
$ sudo apt-get purge
$ apt-get -f upgrade

But I now had a problem where packages, specifically alpine, depended on on libdlap2, and it was telling me that it couldn’t install it, so upgrading wasn’t possible.

I made the mistake of $ sudo apt-get remove alpine, which would not let me undo that mistake by reinstalling.

My hunt brought me to libldap2-dev, but while this installed, it didn’t help alpine’s dependencies.

Even with the super-duper do-everything command, nothing helped:

$ sudo apt-get update && sudo apt-get upgrade -y && sudo apt-get dist-upgrade -y

Then it dawned on me, perhaps some of the repositories that I added to /etc/apt/sources.list were giving conflicting dependencies. Luckily, I annotated heavily what I had ever added to this file.

There were only two things: Subversion, and Mono. Here they are. You want to comment out these lines:

## Subversion obtained from https://edge.launchpad.net/~clazzes.org/+archive
deb http://ppa.launchpad.net/clazzes.org/ubuntu hardy main
deb-src http://ppa.launchpad.net/clazzes.org/ubuntu hardy main

## Mono added by request of FogBugz installation
## http://www.fogcreek.com/FogBugz/docs/60/topics/setup/UnixGettingYourServerRead.html#deb
deb http://www.backports.org/debian etch-backports main contrib non-free

Then, I did a $ sudo apt-get updatee, followed by a $ sudo apt-get dist-upgrade, then a $ sudo apt-get dist-upgrade.

All of my problems were solved. No package dependency problems what-so-ever, and I was able to install alpine, and all the others, bringing me up to the latest and greatest.

Finally, I uncommented my sources.list file back to the way it was and tried the upgrade again. No errors. Everything was fine.

The solution was that something, and I don’t know which one, was causing conflicts. Reverting back to the virgin sources.list file state was enough to get Ubuntu happy to do the upgrades.

Unfortunately, since re-commenting the lines didn’t reintroduce the problem, I’m unable to tell you which repository caused the problem in the first place.

Hibernate Schema Update Problems

For a while I’ve been having problems trying to get a SchemaUpdate working with Hibernate. Turns out the problem was me, not Hibernate. Newly created tables had a blank ACL, and I just needed to set them.

I’ve been using Hibernate for relational persistence for a while now, and I have to say it’s been working out pretty well.

That was, until I went to do a SchemaUpdate.

The moment I did an alternation of a table, or created a new entity, things went sour, and I was unable to read my old data. Was it me, or was it Hibernate?

could not initialize a collection
PSQLException: ERROR: permission denied for relation newtablejustadded

It was me.

Turns out Hibernate’s update was working just fine. There was no magic versioning or class hashing going on, detecting the change to the database.

The problem was the ACL was blank for the newly created entity table (I was using Postgres).

By issuing this command, all was fine again:

GRANT INSERT, SELECT, UPDATE, DELETE, REFERENCES ON newtable TO GROUP agroupIwasusing;

Since it took a while to figure out what was going on, I thought I’d post this to help others that follow a similar, yet frustrating, path.

Jaw Dropping Photo Retouching

Put aside everything you think you know about photo retouching, as here are some serious resources for doing it just as the pros do.

In addition to capturing the perfect image and having the perfect lighting, you also need to know how to do photographic retouching.

While many of these sources revolve around Adobe’s Photoshop, you can also use Corel’s Painter, Gimp, GimpShop, or even Pixelator.
Yes, you know to shoot in RAW mode.

You may even know about Raw Developer, to eek out what your photo editing software can’t.

Huey Pro by PantoneYou might even know about the Pantone Huey Pro, which is the dual-monitor color calibration device.

Forget everything you know or think you know, here are the sources you need for high-end professional photo retouching!

Color Correction


A good photo has to take into account its color space, and it turns out the simple color wheel model is actually fairly simplistic. A color space looks more like a stretched and distorted multi-dimensional field. By deliberately contorting the color space, it’s possible to do everything from white-balance to invoke moods to increasing contrast.

Additionally, your camera has the ability to pick up more detail that you’re able to discern or your monitor can display. By stretching and twisting the color space, you can draw out more details in areas where you need it.

Instead of using the Levels control, building a strong command of advanced Curves will do wonders. Curves can be used on different channels. And, with selective masking, it’s possible to create images that are physically impossible for a camera to capture.

Curves effectively do a translation, but instead of linear relationship, the change can be dramatic in some places, less so in others. Think of it like a color spectrum on a rubber band, you can stretch portions of it.

The eye dropper tools in the Curves dialog help identify what should be considered white, what should be considered midtone, and what should be considered black for transformation. It may come as a surprise that it might not be ideal to have a pure black or a pure white.

Mastery of Curves allows you to deal with under exposed, over exposed, and color casted images. With a well exposed picture, it will help make the subject pop. It also affords some very clever use of creative coloring. And let’s not forget controlled desaturation can lead to many splendid images.

Once you learn how to really use Curves, you’ll have no need for Levels.

Certain color-space models play off of different strengths. Color need not be RGB.

Print, for instance, looks great when CMYK is used.

It turns out that for drawing out detail, LAB color space makes a world of difference.

LAB space is magical because it puts the luminance on it’s own channel. The tradeoff is that red/green become opposites on the ‘a’ channel, and blue/yellow become opposites on the ‘b’ channel. This works well, as often it’s the brightness you want to affect without washing out the color. For instance, LAB mode can remove unwanted fog and haze, magically pulling color out of seemingly nowhere.

Additionally, the Unsharp Mask can be applied to just the luminosity channel, pulling out extra details. If there’s noise in an RGB’s blue channel, one can covert to LAB, apply the Dust’n’Scratches filter to the B channel, and convert back. Blurring A and B will hide imperfections.

The A and B channels can be used to accent color. And if an image has an unwanted color cast, moving the curve out of A’s or B’s center point removes it.

LAB also has another amazing use: getting amazing selection masks from the channels.

Color Enhancement


Scott Kelby, a Photoshop guru, has identified that there’s really only seven steps needed to really push an image to the limits. This can make a horrible picture acceptable, and a well exposed image astounding.


  1. Use Open the file in RAW mode, even if it’s a JPEG, and pre-process there.
    Fix the white balance, and then do things like warm it up. Fix the exposure and twiddle the details. Information that’s clipped can be brought back into the color space.

  2. Perform the Curves adjustments.
    Bring out detail.

  3. Adjust the Shadows and Highlights.
    Pull out more detail, and set the mood. Good contrast makes a dramatic photo.

  4. Paint with light.
    Layers, gradients, and layer blending can simulate camera filters. A neutral density, for instance, can bring out the blues in your skies. In a more controlled sense, this is non-destructive dodging and burning.

  5. Channels Adjustments using LAB color space.
    By applying an image to itself with soft light, in LAB mode this produces aesthetic contrasts.

  6. Use Layer Blends and Layer Masks.
    Often the whole image won’t need uniform changes, this step brings all the elements together.

  7. Sharpening with the Unsharp Mask and fading the Luminosity afterward.
    Extra sharpness can be pulled out to provide what looks like a really in focus image. Doing it this way removes color halos that may appear.
You don’t apply every step for every photo, and it’s important to recognize less can be more. The cumulative effect of these steps is what get results. Also worth mentioning, the order is important.

Professional Retouching


Most retouching instructions inadvertently make a model’s skin look like plastic. They focus on the Gaussian Blur filter, screening layers, and use the Clone tool, and the Spot Heal Brush. This might be acceptable for small web images, assuming you want that look.

It’s not what the professional do.

Why not? Those activities destroy information in the image. That means the image looks fake and retouched when viewed up close or when it appears in print.

To do things right, you need a solid command of color spaces, the Healing Brush, the History Brush, Dodge/Burn brush, Warp/Liquify tools, and Unsharp Mask. Most changes are made with Adjustment Layers, so the image is actually a composite of small, controlled alterations. This is time consuming and can be tedious if you don’t know the numerous shortcuts of your post-processing application.

To make a clean image, one uses the Healing Brush with sampling from all over the image. Reshaping parts of an image requires the Liquify tool, and to alter the whole image the Warp tool is used. These activities can damage data, which is why after using them cleanup with the History Brush is necessary. The goal is to preserve detail and remove imperfections.

Since the magic of photography is in capturing the light, not the subject, having controlled contrast makes an image stand out from the rest. What makes a good professional photo retoucher isn’t the blemish removal or pushing of pixels, it’s the re-sculpting of the image in 3D.

In this context, I’m not talking about modeling tools like Poser, Blender, Animation:Master, or DAZ:3D. No, I’m talking about the illusion of depth created with shadows and light.

Face Painters are do this to reshape the face, using smooth gradient blending and edges to create fantastic illusions. The dodge and burn tools, along with an decent understanding of human anatomy, will let you get a model closer to that perfect body.

The insight comes when you realize things that are further away are darker, and things that are closer are lighter. By performing slight emphasis on naturally falling light, shadow, and edges, it’s possible to enhance the perceived depth of the photo’s subject. By adding or removing light, it’s possible to alter the shape of the subject in very flattering ways that are not perceptible unless you compare the image to the original.

Total reconstruction is possible when sampling can be used to build the right textures, hue and saturation can set the right colors, and dodging and burning can create the right shadows to convey a shape or edge.

Bringing It All Together


The name of the game is contrast and sharpness, and with the resources above, you’ll be able to produce some jaw dropping images.

Mind you, there’s no magical automated formula. One image can take literally hours, but the results are worth it.


Photo by Walt Stoneburner

Firefox Slow Page Load – Solved

Firefox 3 slow? 20 second page load times? Figured out why. And how to fix it.

A co-worker showed me an interesting problem with Firefox today. He loaded a page from our application (running on localhost) and the page content loaded instantly, but the page load itself didn’t end until a time out 20 seconds later. Literally.

Everything we saw a measured from the browser or from the sending application showed that the content was sent in milliseconds, and the page load was just sitting there doing nothing. We were even using the latest Firefox beta.

Other browsers had no such problem.

Turns out, we figured out what was going on using the Tamper Data add-on.

Turns out there was a Connection: keep-alive in the header. When we changed it from keep-alive to close, the browser behaved as expected. That is, it loaded the page instantly.

A little web investigation showed that when you use the keep-alive attribute, you must also use Content-Length: header, which the sending application wasn’t doing.

A quick application tweak to send the content length, and everything ran super spiffy.

Now, if you don’t have access to the application that’s sending you web pages, you can twiddle with the about:config and change the network.http.keep-alive setting to false.

SQLite Functions

I was trying to figure out how to display an integer as a date and time in SQLite3. And it’s documented, and documented very, very well. Problem is, so is the code base, so when I looked for time conversion functions for SQLite, even browsing the Wiki, I kept getting the developer pages, not the SQL core functions. But, I found them. And now I’m documenting where so I can get to them at a later date.

Seems silly, but I’ve been using SQLite and was having the darnedest time try to convert an integer into a time. Problem was, I knew the functions for Sqlite3 had to be out there, but all I kept getting from search engines and exploring the developer Wiki were the C/C++ API functions, not the ones needed for SQL. I guess the way the pages are indexed, the source pages score higher than the user manual pages.

Anyhow, located the SQL functions and wanted to document their location for myself so I could locate them again later.

Seems they are called Core Functions.

They hide under the language expression page, which is under the SQL language page.

I was thrilled to find that the SQLite C Interface allowed the creation of your own functions. Brilliant!

Turns out, that the date and time functions were hiding in a different part on the Wiki.

The magic I wanted, given a time stored in an integer, was:
SELECT datetime(timevalue, 'unixepoch', 'localtime');

iChat Problems: Fixed

Got Leopard? Find that iChat isn’t working? Do you run Parallels? Guess what, that may be it. What? You’re not running Parallels at the same time you iChat? Not relevant, Parallels has network services active even if the client isn’t. Here’s the workaround to get you chatting…

iChat and Parallels
While trying to iChat using Leopard to a system running Tiger, I ran into a problems that I never had using OS X 10.4 before: bad video quality to downright refusing to connect.

With a little research, I ran across this article and that was enough to resolve the problem.

Here’s how to get iChat working on OS X 10.5
…if you’re running Parallels.

See, turns out that Parallels, I’m using 3.0 Build 5582 (Dec 5, 2007), appears to be running some services, even when the virtual machine is active, that gets in the way of iChat.

Get out of iChat.

Go to Apple / System Preferences…, select Network, and click on Parallels NAT and change the Configure drop down to Off; then go to Parallels Host-Guest an change the Configure drop down to Off. Press Apply.

Get back into iChat and try again. For me, it instantly fixed the problem.

Why Managers Hate MS-Project

Managers ditch project management tools when they start getting unexpected behaviors. Here’s some things that cause unexpected behaviors and what you can do about them.

Did you hear the Microsoft was making a new Office bundle available? It is designed for specifically for software development planning, including only PowerPoint, Excel, and Project; it’s called MS-Fiction for Managers.



Almost every manager I’ve known shakes their fist at project management tools. And while pretty Gantt charts, views of progress reports, and tasks lists appear in presentations, most of it is trickery. That is, all the real work is done by hand on paper or in a spreadsheet, and once figured out, is transcribed to a project tool to product the pretty charts.

What gives?

Project isn’t a drawing tool; it’s supposed to give and track useful information, not get in the way.

Isn’t project management software supposed to let you enter in your task list, assign resources, and produce an optimal schedule?

Well, yes. And, frankly, most people can get past that part. The problems kick in after that point.

Leveling Issues

Managers ditch project management tools when they start getting unexpected behaviors.

I’ve identified several problems that crop up frequently. Here’s some things to be aware of to help reign in the gremlins that like to scramble your projects.

Loss of Historical Information


If your project tool moves a completed task to a new point in the timeline, then it’s broken. You’ve found a bug. Completing a task anchors it in time.

Mysterious Chronological Task Reordering


When you list tasks, unless you explicitly state otherwise with a direct dependency, the software is allowed to reorder when a task begins. The software you’re using may have a different take on what makes sense.

I often see this problem happen when a time estimate is replaced with a more discrete breakdown of the task. For instance, deleting a 3 day task and replacing it with three 1 day tasks. Because project tools often assume you plan today and do tomorrow, you can sometimes end up with a hole in the schedule you want backfilled and that’s when the trouble starts.

In some cases, the software may decide to move one task from the end of the task list up to the front to fill in the hole; the justification is that it’s better to move one task than shuffle the whole schedule back. This may, or may not, be what you want.

More realistically, if you find tasks being shuffled out of order, the problem has more to do with when a task starts. Some software will force a task to start at a particular date in order to coerce the schedule; the problem is, if you’re unaware it’s done that, and you change some tasks, it might have imposed a schedule requirement upon you that isn’t real. You need to be diligent about such conditions.

Very intelligent schedulers will recognize the difference between a start constraint that you mandated, versus one that it derived.

Around the trouble spots, make sure that the tasks are set to be scheduled as soon as possible, depending on their assigned resources, and not an arbitrary date.

Never Trust Undo


While undo is supposed to put things back the way they were, it can be tricky to get right. Some operations may affect the properties of the tasks on your schedule. When you undo, it might undo what you’ve done, but keep the changes and constraints that it made.

A mature product will implement undo perfectly, but it never hurts to save a historical copy.

Put another way, just because the tasks return to their original positions after an undo, does not mean that new dependencies and criteria were properly cleared from the task properties.

Too Many User Supplied Dependencies


A dependency should only reflect inter-task dependencies, and that means you should use only the minimum required.

If you are using dependencies to force an ordered sequence to tasks that have no relationship, just to get them done in a certain order, you’re doing it wrong.

If you are using dependencies to coerce the software into producing a schedule ordering you want, you’re doing it wrong.

The problem with these two hack-it-til-it-works approaches is that when the schedule changes and you need to re-level it again, some dependencies are real and others are bogus. The software will account for all of them, and that will cause the scheduling algorithms to make bad decisions.

Any others spring to mind? Please write me.