Career

Seemed like a good idea to gather up some info and links about some of the companies in my career that have been important, recent, or both.

bioMerieux

The major company I’d worked for in my career was bioMerieux.

VIDAS

I developed a good chunk of the firmware for the VIDAS instrument.

miniVIDAS

The follow-on instrument, the miniVIDAS, used the same boards and firmware from the VIDAS, but added an onboard computer to allow it to be fully self-contained. I developed all of the firmware for this add-on board, with the exception of the actual biological algorithm “engine” that processed the data points and returned the result. (this code was shared with the workstation software developed by the software group for the original VIDAS instrument)

Developing the firmware for the miniVIDAS was some of the most fun I’ve had in my career, and it’s one of the products I’m most proud to have gotten an opportunity to work on.

Vitek 2

After that, I did a lot of firmware for the Vitek 2 instrument. This was a lot of fun, and a chance to work with a larger team of very talented mechanical, electrical, and firmware engineers.

Vitek 2 Compact

This was a smaller version of the Vitek 2 instrument, with some of the automated sample prep features removed. You’d think that removing hardware would make this a pretty trivial project. Turns out, it was actually a huge development effort.
There were a lot of new features desired for this instrument. Another major factor was the impact to the workflow caused by requiring the user to manually move the samples from the vacuum-filler to the mechanism that sealed the cards and loaded them into the incubator.

Other

I worked on several other projects/products at bioMerieux, including the BactT/ALERT 3D, and the yet-to-be-announced, but very interesting and ambitious development effort I was involved in when I left the company. I’ll save some of those memories for a future post.

Aclara

Recently (2011), I spent some time working for Aclara before deciding the time was right to make a leap of faith and become an Independent Software Developer focused on apps for the Apple iPhone/iPad/iPod Touch devices.
I enjoyed my time there, and the topnotch engineers I got to work with. Cool technology at a good company.

While at Aclara, I spent most of my time working on firmware for one of the transponders that goes into electric meters.

XCode Build Versions

XCode Build Versions

So, one of the things I found myself wanting to do is automatically bump the version of my application. One good reason to do this is when using the amazing TestFlight to distribute beta builds.

Now, we actually have two “versions” to play with. The first is the actual “Version”, and the second is the “Build”. For my purposes, the Build is what I want to change with each release.

This could be an incrementing number, but I’d really like it to be more useful than that. I use Mercurial as my SCM, so what I decided I wanted was to make the Build “number” be the Mercurial changeset identifier. That way (assuming I’ve done a check in of the changes, as I should) the build number will always be different, and meaningful.

What follows is the result of inspiration gained from looking at solutions found by other developers, in particular from the blogs of Bill Woody and Daniel Jalkut.

Script Summary

This script read the changeset ID from Mercurial and writes it to the app’s plist as the build version.

In addition, this script checks to see if we are doing anything other than a “Debug” configuration build with uncommitted source changes, and if so it generates a build error.
(This feature can be customized or disabled as needed)

Script Details

This script could probably be done as a shell script, and certainly could be done using Perl or Ruby. Since Python is my go-to scripting language, that’s what I used.

First, we use the Mercurial command-line program (hg) to get the changeset ID.

We then check to see if the ID ends in a plus-sign. If it does we look at what build configurations are allowed to be run with uncommitted files. Typically, the Debug configuration is the only one you’d want to do with any changes to the source not checked in. This feature can be configured as needed for your particular build style.

Next, we optionally shorten the build version string. You may want to do this if you want a shorter ID. We could take this fairly lengthy hash and truncate it to wind up with a shorter build version that for all practical purposes would still probably be unique.

The path to the build files is created, and then we use the defaults command to update the build version in the plist.
Note that we do this to the plist after it’s been copied to the build products directory. The “source” plist is not modified by design.

Python Script


#!/usr/bin/python
#
# Obtain the current Mercurial version for the local repository, and write this to the
# build version of the XCode project this script is run from.
# Also can check the build configuration and generate an error if uncommited changes exist
# and (for example) a Release build is being made.
#
# This script expects to be run as a build phase between Link Binary With Libraries and
# Copy Bundle Resources.
#

import os
import os.path
import string
import sys


# Set this to true to cause the IDs to be shortened to "XXXX" or "XXXX+"
shortenID = 0

# Configurations that allow uncommitted changes.
# If a configuration like "Release" is not in this list, the script will generate an error
# if there are changes that haven't been committed when a release build is attempted.
uncommittedAllowed = [ 'Debug' ]
#uncommittedAllowed = [ 'Debug', 'AdHoc', 'Release' ]


fh = os.popen( "/usr/local/bin/hg id -i" )  # Ask Mercurial for the global version ID
buildVer = fh.readline().strip()            # Read it from the process, and strip the newline

if buildVer[-1:] == '+':
    # Plus sign at the end means uncommitted changes

    # Check to see if this should cause a build error.
    config = os.environ['CONFIGURATION']
    if not config in uncommittedAllowed:
        # For this configuration, doing a build with uncommitted changes is an error.
        print "ERROR: Uncommitted changes in the repository while doing %s build!" % config
        sys.exit( 1 )

    # Do we want a shorter ID?
    if shortenID:
        buildVer = buildVer[:2] + buildVer[-3:] # First two chars and the last three chars (plus sign)  
else:
    # Do we want a shorter ID?
    if shortenID:
        buildVer = buildVer[:2] + buildVer[-2:] # First two chars and the last two chars

# Build the path to the Info plist in the build products directory.
infoPath = os.path.join( os.environ['BUILT_PRODUCTS_DIR'], os.environ['WRAPPER_NAME'], "Info" )

print "Setting build version of '%s' to PList %s" % ( buildVer, infoPath )

cmd = "defaults write %s CFBundleVersion %s" % ( infoPath, buildVer )
os.system( cmd )

sys.exit( 0 )   # Success

Installation

This can be embedded in the project, or called from the build phase (as shown in the image).
Regardless, it must be placed in the list of build phases between Link Binary With Libraries and Copy Bundle Resources.

Both ways have their pros and cons. If it’s embedded you can’t “lose” it. If it’s located in a common location and called by all your various XCode projects, it’s easy to fix or modify when necessary.
If it was an integral part of the build, I’d prefer having it embedded, but since it isn’t (the project will build just fine if you take it out of the build phases) I’d rather call it.

This script uses the OSX defaults command, and as of this writing (Sep 2011) the man page for that command warns that it will lose the ability to modify plists in this fashion at some point. When that day comes, I’d much rather fix my script once than edit who knows how many projects.

XCode Environment Variables

Environment Variables

When XCode runs a script, it sets a lot of environment variables into the shell environment that the script executes in.

These are some of the most interesting environment variables available to scripts running from XCode.

CONFIGURATION=Debug
INFOPLIST_FILE=MyCoolApp/MyCoolApp-Info.plist
PRODUCT_NAME=MyCoolApp
PRODUCT_SETTINGS_PATH=/Users/donmeyer/Code/ObjC/MyCoolApp/MyCoolApp/MyCoolApp-Info.plist
PROJECT_DIR=/Users/donmeyer/Code/ObjC/MyCoolApp
PROJECT_FILE_PATH=/Users/donmeyer/Code/ObjC/MyCoolApp/MyCoolApp.xcodeproj
PROJECT_NAME=MyCoolApp
PROJECT=MyCoolApp
SOURCE_ROOT=/Users/donmeyer/Code/ObjC/MyCoolApp
TARGET_NAME=MyCoolApp
TARGETNAME=MyCoolApp

A full list can be generated by running (as a build phase) a script consisting of this line:

set >evars.txt

Fax Madness

As part of the start up of Stormgate Software, I’m migrating from a “personal” iOS developer account with Apple to a corporate one. This process has been pretty smooth so far, with Apple’s developer support team being both responsive and knowledgable.

To confirm that Stormgate Software actually exists, they of course want to see some paperwork. In this case, my Certificate of Organization from the state. And how do they want this paperwork submitted? Why FAX of course.

When you fax something, what actually happens is the piece of paper is scanned, turned into bits, and sent to a fax machine on the other end which prints it.

When sending to a company like Apple, it’s a really good bet that what’s on the other end of the phone isn’t a “fax machine”, but rather a computer. And that computer almost certainly just creates a PDF file of the “paperwork”.

Not only is this process (the scan-the-paper part) sort of primitive, but in this case it’s pretty crazy. Why? Because the document I’m sending is a PDF! That’s what the state sent me!

So here’s the process:

  1. State government’s computer generates a PDF (bits)
  2. PDF is sent to me via the internet
  3. I print the PDF onto dead trees
  4. I drive to the local U-Fax-It store (now we add dead dinosaurs into the process)
  5. The paper is scanned and sent via phone line to Apple
  6. Apple’s computer system turns it into a PDF (bits)

Sigh. If only I’d had some 8-Track tapes to listen to during step #4…

New Beginnings

Well, tomorrow is the first official day that I’m devoting 100% of my time to developing iOS applications fulltime. As in, independant software development IS my “day job”.

Exciting and scary at the same time. I plan to use this blog to talk about the process a bit, and then eventually be more focused on our products well as some general programming posts. That might make more sense to spilt up into two blogs, but we’ll see how it goes.

Watching the Final Space Shuttle Landing

Just got done watching the shuttle land for the final time.
Some random thoughts:
Double sonic boom was both louder and quieter than I expected. I know that doesn’t make a lot of sense, but keep in mind I’m running on about 4 hours sleep.

Rolled by fast!

Bigger than I expected.

Wow, lots of media there, and more people than I expected.

Took no pictures or videos of actual landing – happened fast and I’m glad I just experienced it.

Bittersweet that the USA has a period where we don’t have the ability to get men into space.

Can’t believe how much money we’ll gladly spend to blow shit up, and how little in comparison we spend for amazing things like the space program. Space is the future of our race, we are getting there way too slowly.

OSX Lion

Cannot believe that Apple releases OSX Lion on the day I’m headed to Florida! Guess I’ll just have to be satisfied reading John Siracusa’s review on Ars Technica.
It does tempt me to take my trusty old MacBook Air with me, but not sure I want to try downloading an OS over hotel WiFi.
And speaking of MacBook Airs, the upgraded models announced today look really sweet. I don’t need a new laptop, but I sure want one.

The Last Space Shuttle Flight

So a few weeks back, before the launch of the final space shuttle flight, I registered to “win” a chance to see the launch at NASA, as part of a “tweetup”. This was an opportunity given to anyone following NASA Tweetup on Twitter.
Out of thousands of registrations, they chose 150 to attend. I was not one of those 150. I did get placed on the 150-person wait list. So close!

It doesn’t end there though. Last week they announced that they were going to select 50 people from the 150-person wait list and invite them to watch the shuttle landing. My odds were 1 in 3! Friday, the day of the invitation emails, came and went. No invitation.

Cut to Sunday morning, when what do I find in my email inbox but an invitation to see the landing! My assumption is that although I missed the first 50, I was invited to fill the spot of someone who declined the invitation.

After much hesitation, and encouragement from friends and family, On Sunday afternoon I decided I was going!

This Thursday morning at 5:58 will find me, tired but excited, in Florida watching the final space shuttle land.

A Nice Story

Every now and then I see something in the news that restores my faith in humanity.
This nice story about adoption, and what makes a family is one of those.

Why Family Adopted a Grown Man

Southwest Airlines

We’re flying to Denver to visit some friends, and on a nice direct Southwest flight.

I really do like flying Southwest. The entertaining way that their flight attendants have of giving the safety briefings is really clever. Like a good television commercial (think Jack-In-The-Box) you wind up paying attention because it’s funny.

IMG_0846.jpg