Wednesday, December 9, 2009

Drag and Drop

For Caroline's Cat Game I need to be able to implement some basic drag and drop actions. The game is a basic dress-up. So, to take things, like a bow (UIImageView *bow) off of the cat, I need to drag them over to the icon of the dresser (UIImageView *dresser) and drop them in.

if (CGRectContainsPoint(dresser.frame,[touch locationInView:self.view])) {

bow.image = nil;


I have this code in my touchesEnded event. The CGRectContainsPoint takes two arguments. The first is a rectangle and the second is a CGPoint. If the CGPoint is in the rectangle then it returns true. When the statement returns true, I make the image invisible by setting it to nil. Instead of using the location of my finger, I could use which is also a CGPoint describing the middle of the bow image.

Tuesday, December 8, 2009

Vive La France!

A purchase from France today! The downer of all of these international purchases is that I have to earn $250.00 in a country before Apple will transfer the money to me. Regardless, I think I will add a coin in honor of my French customer. Now the question becomes: do I photograph a Euro coin or one of my old Franc coins.

Sunday, December 6, 2009

Why Move to Blogger from iWeb?

As any of you who look over the rest of my site there is a blog over there as well. It's prettier than this one. So, why bother to put the blog over here? iWeb is too hard to use for quick iterations. iWeb is beautiful, iWeb makes my kids able to publish web pages, iWeb is for home use.

In order to get a new blog post up on my iWeb powered blog, I have to: write the new post in iWeb, tweak the title and then "publish" the website. Then I open SEO iWeb Tool so that I can re-apply the tracking javascript and other SEO modifications I've made to titles, photos and graphics. Then I can upload the files to my webhost.

That's too much work for a 300 word blog posting. So, I'm moving the blog portion over here. It's easier to update so it will be easier to create something with fresh content. Also, the iWeb created blog doesn't have a comment feature which in some ways defeats the whole purpose.

Step one was to create a subdomain in my DNS and point it to my blogger blog. Blogger gives instructions for how to accomplish this task. Next post will be about Step 2, making the template look like the rest of my site so that travel back and forth is seamless.

Saturday, December 5, 2009

First Canadian Customers for Carter's Coin Flip

In the latter half of November we had not one but two purchases from Canada! Yippee!
In honor of that, we are looking for a nice Canadian coin to add to the choices of coins in the application. As a reminder, you can always switch between coins by double-tapping on the coin image on the first screen.

Saturday, November 21, 2009

Google Chrome OS How To and First Impressions

Twitterstract: Walter installs Chromium OS and realizes that it's a lot like the Chrome browser. He offers a few tips if you are wanting to take it for a spin.

It feels like this has been my Google week. Saturday again, and it's been Google Wave, Chromium for OSX, App Engine and now Chromium OS (I even set up my Google Voice account). Here's a quick how-I-made-this-work post for the Chromium OS virtual machine.

I first saw that someone had taken the time to compile the code into a virtual machine from this post on Lifehacker. I think without this, I wouldn't have bothered. At this point, Chrome OS is really just a concept, dancing bearware.

I started out by venturing over to The Pirate Bay and grabbing the virtual disk image via Bit Torrent. FWIW I still haven't embraced the whole Bit Torrent thing. I've spent too many hours watching P2P take bandwidth from my company's connection while my boss or some other Important Person is screaming about how slow the network is going.

The disk image I pulled over was called chromeos-image-999.999.32309.211410-a1.vmdk.bz2 and was just under 300MB compressed. There are already a number of files on TPB that say they are chromeos images. After I downloaded the image. I unpacked it and then started up Virtual box. As an aside, I'm really starting to like Virtual box as a Parallels and VMWare replacement for home use.

In Virtual box, I mounted the disk image and created a new machine. First, I used the Virtual Media Manager (File -> Virtual Media Manager) to Add the vmdk file as a hard disk image. To do this, click on the Add icon and navigate through the file system to find the .vmdk file. Now we are ready to create the machine. From the main Virtual Box screen I click on the New icon to start the wizard. On the first screen of the "New" wizard, I told it that the Operating System was of type Linux and version Debian. I've read conflicting forum posts in various places on what to set here, but Linux/Debian works for me. I kept the defaults for memory. Then at the Virtual Hard Disk screen, I selected "Use existing hard disk" and chose my image from the drop down.

Then I started up the system. At the login screen I entered the username of "mark" and no password and pressed the enter key on my keyboard. This part seems to be causing lots and lots of consternation on the forums as people miss this point. As he says in his release notes, Mark used the local account name of "mark" for the system, not chromeos and not my real Google credentials. As each person builds an image, they must have to supply some credentials during the build. Once the ChromiumOS loads then we will be able to use our own credentials to get our own information from Google. On subsequent starts of the machine, I've found that I can use my regular Google account login to start the machine. When I do this, it loads with my Gmail and Calendar right away which is nice.

And voila. We are looking at the home page of Google Chrome OS or Chromium-os or Chronos as some are calling it. A couple of points if you're actually following along: once Virtual box captures your mouse, you release it by holding down the key sequence shown in the bottom right. For me it's a Left - command key

Another thing is that if you've been using Chrome, you've seen all of this before. You've also seen it in a much more stable way. I'm getting regular crashes of the virtual machine. There are a few differences though: the home screen of applications which is accessed by the icon on the top left of the window is one. Even this home screen isn't actualy on the machine. It's served up by an AppEngine robot. You can tell by the language it gives you if you are not logged into Google. If you've ever developed with AppEngine you've seen this screen.
This is truly a net computer then. You can use any device running this OS and get at your information. It seems that it's caching a little bit of my profile, but not really expecting to spend a lot of time reading and writing local files. The final piece of the OS that makes it different from Chrome is the system tray looking set of icons.

The triangle icon and the wrench icon below it expand to show the exact same menu. This duplication is because on some screens (right now only the Welcome screen) the wrench and other parts of the browser menu bar go away. The icon in the middle that resembles a wine cup tells me that I am connected to the network via wire and that my WiFi is turned off. The gray plug icon shows that I am plugged in.

If you're one of those people who needs to see the man behind the curtain, you can get a glimpse of the file/folder structure by changing the download location which will open a standard X file dialogue box. Use either the wrench or the triangle menu select "Options" then choose the "Under the Hood" tab. In the Downloads section choose "Other..." and you can poke around to at least see the folder structure.

The folks over at Google are posting a lot of their philosophy on this project over at so I would recommend you visit there to learn more. The videos and User Experience documents are accessible to most everyone. A lot of the other stuff is going to make your brain hurt at first.

Wednesday, November 18, 2009

"Compiling" Javascript Code

Look what I found this morning. It's a "compiler" for Javascript code. Since Javascript is interpreted instead of compiled it's not truly a compiler but it does something similar: makes the code readable for the machine and takes out all of the extra fluff that a carbon based life form needs for comprehension.

I have tested it with some of the javascript that I use on my personal sites and got about a 25% average compression.

I looked at the largest piece of Javascript on the home page. It is the jQuery UI javascript code at 188K. It compressed down by 11%. The other way to really compress the Javascript is to use gzip. Here is a blog post by someone else about it (he also mentions some other utilities for doing what Google closure is doing). Basically, you zip the Javascript and then, since it runs in the visitor's browser anyway their browser expands the file to run the code after they've downloaded it. Gzip is achieving near universal installation, so this method of compressing Javascript has less risk of breaking than it did a year ago.

In essence, what the Closure "compiler" is doing is removing all of the whitespace and pretty variable names that we use so that we can read the code. It's very much like the "Optimize for Web" settings for image programs which remove all of the color descriptions for unused colors and the like.

The home page for the Closure compiler is here and it also explains the philosophy behind what they are doing. It works in conjunction with Page Speed. I've started looking at these things recently because I was reviewing the analytics for our organization's web site and noticing that people are still hitting the site with dial-up. I'm also noticing an uptick in mobile visitors who might be using EDGE or other slower networks to hit our site. Living in an urban area with good G3 coverage and broadband in most places, we forget the costs associated with Flash effects and high-res widget graphics. The 2007 Census numbers show that 10% or so of Americans with home Internet access were using dial-up.

As long as any of those people want to be a part of our organization, we need to make sure they can access our information. Besides, a flashy website is not necessarily the only sign of organizational quality. Take a look at this company's website for instance. The look is dated but clean and speedy.

Monday, November 16, 2009

Why Google Wave Might Change the World

I got my Google Wave account over the weekend and spent some quality time with the documentation and the software. At first, I had a similar feeling like when XML first came out: so what. Most of the features of Google Wave are familiar to anyone who has used email or any of the other Web 2.0 sites over the last year or so. You can leave messages to people and collaborate on documents and there is a rich multimedia component. Ho hum.

At its most basic, the Google Wave concept is that the message/document is the object. In a regular system each email or tweet or update is it's own object and it is up to the user to string them together. Here, the entire conversation is the object. There is also the cool notion of playback so that someone who is added to the Wave conversation later can go back and step through all of the iterations that the wave has undergone.

"So It's just a fancy wiki" said my tech savvy kids. It appears that way, but there can't be this much hype for that...

But, then I had the revelation about why this is oh so much more than a wiki/blog/teamsite/twitter client: federation. Google's vision is that the system is distributed, not centralized. Like every domain has an email server, Google envisions that every domain will have a wave server. This helps with survivability of information as no single server needs to have all of the information. We read about twitter and Facebook and even Gmail going down which is a reason businesses shy away. However, if those types of services are replicated across the servers of all participants then we are back to the type of survivability that the original email and Internet designs promised.

In the subsequent days, my team and I also began to look at Google's robot api. Basically, you add a robot to your recipient list of your wave and s/he monitors the wave for keywords and actions and then does something in response. Having a robot who maintains a web page in response to the content of a wave is one pretty interesting use.

Next post will be about why this will never catch on or scale. I think that Google is onto something revolutionary. I also think that there are lots of ways that we normal people can screw the whole thing up.

Sunday, November 1, 2009

Touch Events and the iPhone SDK

There are four events for touches in the iPhone.

(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event


(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

In the excellent Stanford ITunes U course CS193P they mention that two important things about touchesCancelled cause a number of calls to Apple support: “Cancelled” has two letter L’s in it and touchesCancelled gets called at times when a developer may think that touchesEnded might be called. So, as a safeguard, I now just call touchesEnded from touchesCancelled as a default using this code:

[self touchesEnded:touches withEvent:event];

In general, touchesCancelled will be called when a phone call arrives or when the user presses the home button on the phone to quit the app. If your application needs to do something special there, then be sure to put some code in touchesCancelled. Examples of things you might want to put over there include returning your application to its default state.
Right now, Isabel and I are working on a game that has an NSTimer and also responds to UITouch events. I’m experimenting to see if the timer frequency and the event loop frequency can be set to values that conflict. I’m guessing that we probably can, but I’m also guessing that normal people cannot move their fingers fast enough to make a difference. However, people who drink a lot of Sun Drop....well, that’s another story.

Friday, October 16, 2009

Carter's Coin Flip Version 1.5 Submitted to the App Store

By Carter:
In the new version my dad and I have put a new toolbar that is easier to use.
We have also chosen two new coins along with the Franc one. We added a Spanish coin with a soccer ball on the tails side of it for soccer fans. We also added a one pound piece from Great Britain, with queen Elizabeth on the heads side.
The new game has also added numerals to the statistics mode, so you now that flip number 1520 was heads and the 40000th was tails
I enjoyed making the new version and I hope that you enjoy using the new version to decide whether to do this or that.

By Dad:
In the original version of CCF we made the transition from the coin view to the statistics view using the “card flipping” motif and a button in the top corner of the screen. However, we discovered that we were mis-using the UI element. People kept expecting that the statistics screen and the coin screen were somehow related. The biggest change in the 1.5 version is to move to a tab bar view to indicate that the two modes are not related.

Thursday, October 1, 2009

Single Tap and Double Tap iPhone

By Dad:
We decided to use a single-tap and double-tab pattern to have Carter’s Coin Flip decide if the user wanted to flip the coin (single tap) or change to a new coin (double tap). Knowing that tapcount was the property of touches that we wanted, the touchesBegan method started out something like this:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

UITouch *touch = [[event allTouches] anyObject];

if (CGRectContainsPoint(coin.frame,[touch locationInView:self.view])) {

if (touch.tapCount == 2) {

[myCoin changeCoin];


[myCoin onFlip];



//Code to change the background image since the user

//tapped outside of the coin image.


So, the code above WANTS to call the changeCoin method of the myCoin object (the UIImageView holding the picture of the coin) when the user taps twice or call the onFlip method if the user only taps once.

This code almost works.

When the user does a double tap the coin does change, but only after it flips. So, on a double tap, it is clear that the first tap of the double tap is counted as a single tap and then the second tap of a double tap is counted as the double tap. This is not what I was expecting.

A few quick Google searches turned up curious threads on the standard coding discussion boards. Click through if you must, but the themes are the same: this double tap isn’t as straight forward as people expected:

The last board I visited suddenly brought everything into clarity. It is an RTFM question. ( Message Thread). I should have known, that Apple would not have expected us to use timers or strange masking of objects or something. They would have laid it out, right in the very first document that all new developers should read through, the iPhone Programming Guide.

In essence, the iPhone Programming Guide says that if you are looking for 2 or 3 or 4 taps you will need to delay the code for the touches below your number. So, at one tap you call a function with a slight delay. If a second tap occurs within your specified timeframe (a few tenths of a second), you cancel the call and initiate a call to the function that handles two touches. This pattern is repeated for 3 and 4 touches etc. So, the current (v 1.5) Carter’s Coin Flip application incorporates this code:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

UITouch *touch = [touches anyObject];

if (touch.tapCount == 2) {

[NSObject cancelPreviousPerformRequestsWithTarget:self];



- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

UITouch *touch = [touches anyObject];

if (touch.tapCount == 1) {

if (CGRectContainsPoint(coin.frame,[touch locationInView:self.view])){

[self performSelector:@selector(onFlip) withObject:nil afterDelay:0.3];


//I change the background image here


} else if (touch.tapCount == 2) {

[theCoin changeCoin:coin];



Notice that I have some code in touchesBegan and the rest in touchesEnded. I think I could have put it all in touchesEnded, and still given the same illusion to the user. However having it in both locations made it easer for me to read the code. I got a little confused by the part of the performSelector command’s withObject requirement. At first I thougth the withObject would be optional given my reading of the documentation. However, the code didn’t work until I added the withObject parameter. I think it has something to do with the fact that the afterDelay parameter is there. In .net coding, any of the optional parameters can be omitted, but it seems that in ObjectiveC you need to list the optional parameters and just pass in nil.

Sunday, September 13, 2009

Snow Leopard 10.6.1 Update

The 10.6.1 update seems to have resolved the Save As crashing I was having with Neo Office and improved's ability to get email from the Exchange server.

Thursday, September 3, 2009

Snow Leopard and NeoOffice

Even with the newest patches in place, I'm having trouble getting Neo Office v 2.2.5 or 3.0 to save files into different formats. It keeps crashing when I try to save a .odt file as a docx and when I try to save a file as an rtf. I'm watching the NeoWiki on the topic since it's possible it's just me having the problem.

Wednesday, September 2, 2009

Snow Leopard and Canon Image Runners

My UFR II printer drivers don't seem to work with Snow Leopard. This is sad, because the UFR II system is pretty cool. After reading these posts I spent some time trying to get things working as it seems that Canon may take their time getting an updated driver into the world.

First, I just used the IP# of the ImageRunner and the generic PostScript and PCL drivers. This got my document to print, but on 11x17 paper instead of 8.5x11. Then I decided to try the old school approach of installing the PPD's and going that way. I found the PPD's here and then ran the installer.

This time, when I set up the printer (again using IP#) I found some Canon iR drivers that weren't there before including the one for my model. NB: There is only one printer in the big list that says "ImageRUNNER" in it, all of the others either say just "Canon IR" or "Canon IRC" and the model number.

Finally, success! Things print on 8.5x11 and I can duplex. The standard Apple print dialog boxes have all of the features I normally use on the printer, they're just in a different place than the old UFR II screens, so I have to hunt around a little.

Now, on to fixing the Juniper VPN client that doesn't seem to like Snow Leopard. with Exchange

The connection to our Exchange 2007 server from is still not super reliable. This morning the "Activity" window of shows the Opening mailbox..., Adding Messages, and Fetching new mail tasks all frozen. If I kill all three tasks (clicking on the Stop sign for each) and then click the "Get Mail" icon from the main window, it updates my inbox and now I seem to be in business.

I'm going to watch my account via and OWA today to see if I can see any pattern. Yesterday, at least once I had to jump over to OWA to get messages as wouldn't update.

Monday, August 31, 2009

Snow Leopard in the Enterprise

During my lunch hour on Friday, I ran out to get a copy of Snow Leopard to test out. Our Creative Services department has suffered with Entourage for some time. The integration of Mail, iCal and Address Book with our Exchange 2007 environment is the compelling feature.
The initial setup was flawless and the computer recognized our Exchange server and automagically brought over my email, calendar entries and addresses. When I went home over the weekend, the system even realized that I was no longer in the domain and grabbed my email.

Unfortunately, this morning, back in the office, my messages are not being updated into It is synchronizing my folders, just not the InBox folder. Oh well, back to Parallels to get some work done.

Features I am going to be looking for when I have time: how does handle shared mailboxes; since iCal uses different "calendars" to render different colors, how will Exchange translate those; how will I convert my pst's to mbox format.

I'll keep you posted.

Friday, August 21, 2009

Google Apps for Our Chapters - An Experiment

Twittastract: The basics and best practices I have discovered while moving to offer email forwarding via Google apps to some of the chapters that my Association supports.

The problem with Google Apps especially for non-profits is that they make it so easy and appear to be providing a service for no cost that I don't trust them. So, I continue to move forward deploying their stuff, but grow increasingly wary that it is too good to be true.

My latest venture is to deploy Google Apps for mail forwarding for our chapters. For a while now we have been partnering with some of our chapters to give them website hosting and vanity domain names. There is a lot of overhead associated with this venture that we try to hide from the chapters. A downside of this, is that when they ask for something that seems to be a quick add to them and we say "no" they don't understand and the whole experience sours a little for them.

Mail forwarding is a good example. To save a chapter from having to maintain their own domain, DNS and associated registration costs and headaches, we make a sub-domain for each chapter. For instance, our Valley of the Sun chapter is now The website is hosted on our SharePoint farm in our domain. They get to shed these costs and their admin staff gets to be shielded from the spam that we endure by having our contact information associated with the domain registration. In return, however, they have to rely on our staff for all dns and domain changes. This has made mail forwarding a problem since we don't want to use our internal mail servers for their forwarding (they are undersized for such a volume) and the chapters don't have their own mail servers.

We first looked at Google Apps a while ago but due to some brain lock on my part, I couldn't figure out how to set up the domains to make it work. Finally I saw the light and remembered that can point to an entirely different place on the Internet as

Blah, blah blah, I know. I need an editor. Anyway, the how to:
1) Create an account for the chapter on Google Applications. Since we may have to do this for all of our chapters eventually, we're using a similar "master" username and password for each. This account will be granted Administrator permissions.
2) Decide on the kind of account. Some of our chapters are actually 503 corps, so they qualify for the special "Google non-profit" version of Google Apps. Others are not so organized, so we are setting up each one using Google Standard Application accounts (limited to 50 named users). The chapters who want to can upgrade the account whenever they need to.
3) Verify domain ownership. This one took some trial and error. We finally went with the "CNAME" route since we use Sharepoint. Sharepoint and some other cms' don't actually have straight html files. A way to verify ownership is to modify the main html file on your server and then let Google find it. The modification is an html comment, so inserting it shouldn't change the look of your page. If you don't have html files on your server this won't work so you have to use CNAME.
4) Active the mail by adding a set of MX records pointing to Google to your DNS. This will actually do the relaying of mail. In essence a piece of mail will arrive at your DNS and ask the DNS the name of the actual server that has the email program. The DNS will send them over to the Google email servers.
5) Create the "users". Because we are just doing mail forwarding and relays, we are only creating one or two users. The chapter leaders will do the forwarding by creating a number of "Groups". See below for why.
6) Create a sub-admin account for the chapter to use. This way the chapter can manage their own forwarding and we can step in when they forget the password or have some other kind of leadership turnover and need our help. If the chapter truly breaks everything, we can just eliminate the MX record and CNAME record in our DNS (which would cut the Google Apps account off from the domain name) and start over.

Google actually has very good documentation on how this all works on the site, complete with pictures and Wizards to step you through.

So, why we are using Groups instead of creating a separate user for each? For the most part, the Chapter Leaders just want the email to forward to their home or work account. The easiest way to do this is to create a group with only one person ( for example) and set it to forward to an external email address. Also, creating a group does not count against the named users. The downside of this method is that the person does not get the Google spam protection and must rely on whatever they use at home. Additionally, when they reply to the message it will come from their own account, not from the alias account. Another reason to set up groups for the aliases is that it doesn't require us to set up a new password and account for each alias. For example, we could set up as an actual user of the system and then give her the credentials to log in. This would give her the spam protection and give her the ability to send and receive from the account. The downside of this approach is that setting up the forwarding is more complicated and the risk that we have password issues at the end of the term of office goes up causing more work for us on the back end. With potentially 160 chapters using the service and all of them changing officers in January, we just couldn't scale that.

So far, this has been well received. If you would like me to walk you through how to do this for your organization drop me a line. Also, I'll post a follow up in a few months about how we change our process in response to more chapters using the service.

Thursday, April 2, 2009

Tribes by Seth Godin - Review

First off, this book can be read in under 4 hours. Not common for business books. Secondly, Seth Godin draws from his own experience of creating tribe for his blogs and websites and discussion groups. Finally, he repeats his message enough times that even if your mind wanders, you're destined to read the core message a few times.

Tribes characterizes your customers as tribal units who want to belong to a community. As Associations, I think that our members form even stronger tribal bonds than the groups who might make up the community of a standard group of customers. Unlike a normal company's customers who purchase a product to join the tribe, our members share a common world view and are willing to pay yearly dues and attend meetings or join chapters. I think that Tribes is more important to us in the Association world than it is to those in for-profit endeavors.

Godin makes the point that business has changed from a factory model to a more communal, tribal one. The sense I take from this book is that command and control is not the most powerful way for my team and organization to work to meet the needs of our customers anymore. It feels stale to them, it feels fake to them and they don't respond by buying our books, attending our conferences or supporting our campaigns. He cites mediums like Twitter and Facebook and forums as ways that the workers in an organization can make connections with customers that are much more powerful and meaningful to the organization that the connections a CEO can make.

The call to action here seems to be that the individual should be allowed make powerful connections with small groups on behalf of the organization. Their variation of the core message of the organization will resonate with their peers and tribes much better than anything a marketing department might craft for a broad audience. This kind of marketing is much cheaper than buying TV spots and is much more likely to reach the target market anyway.

Throughout this book I had flashbacks to the connector and mavens ideas in "Tipping Point". I also hear echos of the sentiment in the "Cluetrian Manifesto" and "Waiting for Your Cat to Bark". I don't know that I will read this book more than one or two times, the repetition of message get's tired by the end of the first reading, so I can't see reading it cover to cover very often. I made a fair number of marks and notes about websites and people he mentions, so those may draw me back into the book at times. His blog is definetly going onto my RSS list.

Monday, March 30, 2009

Aimless Surfing Gadget - Still Waiting

I am still waiting for approval from Google for my gadget (or rejection or any response at this point). Today, I learned about an link lengthening service. That will make any url much longer. It got me to thinking though, you could probably encrypt a bunch of good data into a meaningless string of characters and let them hang out on a visible URL. Your data is "safe" because the string can't be decrypted and it becomes difficult for the user of the url to try to modify the variables he is passing to our web service....what a great idea....I bet someone has already thought of it and has already made their millions.

Monday, March 23, 2009

Aimless Surfing Gadget Update

I'm still waiting for Google to review my Aimless Surfing submission. In the mean time I'm making small tweaks and finding interesting results. I decided that having a default of 4 characters in the string was giving links that are too old. I switched the default to 5 in the code I have stored via the GGE widget. I was interested to see that my gadget didn't update automatically. However, the next day, the default was 5 and not 4. Clearly there is some caching going on. I need to see if there is a published update schedule somewhere.

This can make for interesting coding updates. You make your bug fix/update and users get the fix on their machine at some unknown future date.

Sunday, March 22, 2009

Vendor Relations

About 2 years ago I moved for a company who always chose "build" in our build v. buy discussions to one that always chooses "buy". Part of this is a byproduct of the respective sizes of the two companies and the two IT departments. Needless to say, I've learned a lot about vendor/outsourcing relationships. Maybe I can help you with a few rules I've invented.

Rule #1: Find out what the outsourcer is good at. If you ask your vendor to do something they don't know how to do well, they may try to do it anyway (the customer is always right). Also, always ask about the SOP for the vendor and try to work within it. The risk for them to mess up is high if you are making them do something out of the ordinary for them. I've run into good vendors who will say "no" or who will suggest a way to meet my need via another means. However, this revelation will only come about if you take time to talk about your needs and keep an open dialogue. This takes some time, be patient.

Rule #2: Know the SLA. Nothing causes more tension than expectations mismatches. If a service defenciecy is within the SLA and you blow your top, you can gain a reputation as being unreasonable. On the other hand, if you approach a vendor who has not met their SLA and cite the SLA and give data about how far they missed it, they are likely to be willing to make it up to you. During these discussions, I always try to be prepared with a short list of actions they might take to patch the relationship.

Rule #3: Let the vendor make money. There are times to negotiate a price and there are times to let the vendor charge what they need to. Pay attention to hourly rates and equipment costs in the SOW's that a vendor gives you. When they change, have a discussion about what is going on. Also, do your best to pay attention to the business of the vendor, who are the other customers (can you meet them?), how is business going in general (are there going to be capacity issues). Are there any HR or market issues that may impact the vendor's ability to meet their obligations to you.

Rule #4: Get to know the workers. With most outsource relationships, you are assigned a customer advocate or something similar. It can be really helpful to also meet and know some of the people who work on your projects. All of the skills you have for managing your own employees can be applied here to build loyalty. Over time, you can even get the better employees at the outsourcer to be assigned to your projects, especially if you're asking for them by name.

Rule #5: Don't surprise them. Keep your outsource vendor up to date on the other big projects and thing on the horizon even if you are unlikely to use that vendor for the project. They are more likely to be able to support you or engage you if they know what you are doing.

Rule #6: If it's a crisis, ask for help. If you are truly in a bind and have a good relationship with the outsource vendor, they will work with you. It's in their best interest, and the good ones know this.

The best distillation I can offer for these rules is to treate these people like they work for you and are part of your team. Let them be partners with you. Recognize when they are the experts but don't hesitate to be the expert in your field either.

I think that not all of my vendor relationships follow these rules. Some vendor relationships are full of distrust on our side (and likely for them as well). If you cannot become a partner with your vendor, you should probably try to figure out how you can do without them. Sometimes this can be hard (like if your company uses a proprietary piece of software). However, if only one or two of your vendor relationships are difficult you will have a lot more energy to devote. If all of the relationships are contentious, you will be very tired.

Wednesday, March 18, 2009

Aimless Surfing Google Gadget Part 2

Twitestract: Getting my Google Gadget prepared to put into the Google Directory and more on how it's constructed.

This is part 2 of a 3 part series on my Aimless Surfing gadget. Part 1 can be found here.

A Google Gadget is simply an XML file that contains the code needed to run the Gadget. The simplest files have some header information and then one Module node. Within the Module node is the metadata for the gadget (user prefs, the title, url for screen shots, the author's contact information, etc.) and the code itself in the Content subnode. More complex gadgets will add UserPrefs section to store end user preferences and other state data. The most basic "Hello World" gadget looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<ModulePrefs title="hello world example" />
<Content type="html"><![CDATA[
Hello, world!

Pulling this apart, we have the first line which just proclaims that this is a piece of XML. In XML files, you tend to see every object encapsulated between an open and close tag. The main object in the Google gadget model is enclosed between a <Module> at the beginning and a </Module> at the end. The Content node is where you place your javascript and html code that will render your gadget. If you've ever created an RSS feed or disected an iTunes feed you will have seen the CDATA tag before. CDATA is used when you have a big chunk of unstructured stuff that you want to put inside your XML document. Unlike everything else in XML is gets wrapped in square brackets. Once you are working in the CDATA part of the gadget, it's the same as building any other web page. You can add <script> tags for your javascript and HTML forms and image tags and whatever else you want.

Google provides a wonky little gadget to help you write basic gadgets and preview them. The Google Gadgets Editor(GGE) always loads itself with the little "Hello World!" code above. It is part of Google's extensive documentation pages on gadget writing. One thing to note, Google is in the midst of migrating from this simple gadget interface to a more complex (and more full featured) instruction set. So, you will see reference in the Google documentation to "Legacy" gadgets. The Aimless Surfing gadget and any gadget you create via the Google Gadgets Editor are Legacy gadgets.

I call the gadgets editor wonky because more than once, it overwrote my changes or my changes wouldn't save. I don't know if it's a byproduct of using Firefox/Mac but if you start writing serious gadgets, you may want to go a different route. By the end of the Aimless Surfing project, I was writing everything in Text Wrangler and then just uploading the files to the GGE for testing. I continued to use the GGE for previewing and because you can publish your code to the Google world and the Internet from the GGE directly. I can see from the documentation, that as you write more complex things, Google expects you to set up a Subversion system (code control). However, they are happy to host the code. When I write my "real" gadgets, I will likely either go this route or host the code at my work domain.

Publishing the code was surprisingly easy. Google asks that you add in some extra meta fields into the beginning of your XML document and they even have a nice set of tricks to keep the act of inserting your email to a published file from increasing your flood of inbound spam. After adding the requested fields to the <Module Prefs> section of my file, I was able to publish via the menu in the GGE. Publishing was simply reading an agreement and supplying the url where my XML file lives.

Once I get confirmation that the gadget is accepted to the directory, I'll post the last in this series and discect the code.

Sunday, March 15, 2009

Open Source Business Model Thoughts

Twittestract: Sunday Musing is about using open source software in a business setting. It's not really free, but it has its place.

For anyone who is trying to maximize the value of their IT expenditures, the notion of free software is attractive. As Microsoft and some of the other vendors like to point out, "free" does not really mean free. In many cases, the licensing costs (the free part of open source) are only a small part of the total cost of a project. The consulting fees, infrastructure and labor costs to implement the software can dwarf the licensing, even when working with a traditional vendor.

The message here is that we still have to look at the total cost of the projects. There will be times when paying the licensing fees for the comfortable, well known software is the best and safest way to get our organization back to its "real" work.

In particular situations, though, going with open source is still attractive:
  • If you truly have no cash money: the trade off with open source has always been time. Red Hat and other early pioneers in the field discovered that consulting and paid support for free software was a valid business model. There is a large population of people for whom technology is still a hobby. They are more than willing to test software, to improve that software and to tinker. These people are not going to pay for support, but the will invest large chunks of time to get things working. And they are likely to publish their findings in a public place. If you or your organization have no cash but can find time to invest, you can have stable, world class systems for "free"
  • If you are anti-big business: some organizations need to be open source because it supports a philosopical part of the mission. It gives your organization credibility with those who believe that the big business software companies are evil. Be careful here though: IBM, Microsoft and Novell spend money to support open source initatives. Any message you craft around your open source usage can sound hypocritical to those who know about this relationship.
  • If you control the whole organization or are starting from scratch. By control, we are speaking of the computers and the software that runs on them. Many organizations who want to explore open source find that they have one or two pieces of software that do not have open source equivalents. This makes an open source implementation more difficult or at least less comprehensive (e.g. just replacing the email software instead of the whole operating system).
  • If the hardware is old: which is especially true of operating systems. In general, though, open source software packages run at an acceptible speed on older/less powerful hardware. Hardware does have a finite life, though and will fail at some point. Take proper precautions to protect data.
  • If you're collaborating using main stream standards: email, html, pdf, etc. An early development when open source software became a viable alternative was that it could read and write the documents produced by proprietary software systems.
Hopefully some ideas to help you think about this issue. For most organizations, a mixture of open source and paid license software is probably best. As IT matures as a business function we need to focus on business problems. The tools we use to solve those problems are unimportant to the organization. By considering all alternatives, though we can be sure that we are presenting the best solutions.

Tuesday, March 10, 2009

The Aimless Surfing Google Gadget

I think this will be probably a multi-part series on this gadget and how I went about writing it.

Twittestract: A Google gadget that creates random url's and then provides a link to their destination. This should help people surf the web more aimlessly.

As I was completing my recent discussion of link shortening, I became curious about what would happen if you entered a random set of characters after the url. Sure enough when I did that, I was sent to a random site. This gave me an idea for a Google Gadget. I need to create some Google gadgets anyway for work, so I thought this would be a great way to learn how to do them. The idea was to create a random string of characters between 1 and 5 characters in length and then redirect the user to that site. I was wondering how many times I would encounter a dead link when I stumbled upon this site about tinyurl whacking which answered a lot of my questions about how the strings are formed. The tinyurl whacking site was doing what I wanted the Google Gadget to do but manually. So, my idea wasn't original at all, but I am improving something. The author of that site cautioned that you never know what is on the other side of a link. After a few missteps of my own, I realized that you don't really want to be tinyurl whacking with your mom watching over your shoulder.

The gadget itself has two controls, a drop down list for the number of characters in the random string and a button to generate a new random string. TinyUrl allocated all of the one character strings and then the two character strings and is now populating 5 and 6 digit strings. Since there are 62 possible characters per place I think that means that TinyUrl is referencing over nine hundred million links. Hopefully, that is enough to give you a truly random experience.

So, as often happens with software, the Gadget got a little more complicated when I added the preview function. I now wanted to not only create the url for tinyurl but preview the url it points to out in the big wide Internet. Thankfully, someone has already done some work here as well, so using Embiggen and dissecting that to get to Dapper , I was able to utilize a web service that would grab the tinyurl preview link and let me display it. So, that's what I've done. If you are just interested in grabbing the Gadget and don't care about how I created it, you can grab it from the link below. A big warning, though. Big warning: there is some nasty/offensive/virus-laden content on the other side of tinyurl links sometimes. If a proposed link looks suspicious, then use the "Make Another" button to generate a new link. Here is the screenshot (I've also added the gadget itself to the sidebar for the time being).

This is a link to the "Add this Gadget to my Webpage" and one to "Add the Gadget to my iGoogle page"

If you're interested in how I created this or want to follow my progress of adding this gadget to the Google Directory, check back in a few days and I will explain the code and some of the issues I faced writing the gadget. This little toy aside, I think I have the basics down now for creating some useful Gadgets to use on my website or to distribute.

Thursday, March 5, 2009

Link Shortening and Traffic Monitoring

Twittstract: How to use link shortening to track traffic to your site and to track who clicks on all of those links you've been posting to other sites.

Link shortning services are starting to become pretty important to sharing. With the advent of twitter, (perhaps the original) seems to be a waste of characters when services like and save those last few characters so that you can make your witty point or to get your message out to your members/followers.

In normal person terms, a link shortener is just a redirect to your site. Instead of some long, crazy link such as you can present your twitter followers or your email blast recipients with a nice or even a nice which can fit better into your blog post or email blast or twitter update (see my caution about "readable string" below). When someone clicks on your link, they are taken first to the redirecting site and then off to the link you want them to see. If you are fortunate to work for an organization with a short domain name, you can even create your own link shortening service for use by your staff or customers. I mean, which would you rather look at:


Technology wise, a link shortening service is just a webpage, a database and a random character generator.

It used to be that you could embed javascript into a tinyurl which was handy for tracking codes or other intersting tricks. But, over time I guess that "feature" was abused so, now it's url's only. However, there are still ways to use link shorteners to derrive some information about who clicks your links. For shortened links that you want to direct back to your Google Analytics based site, it is pretty easy. Google makes a link building tool, that will embed information that shows up in your analytics reports to help you know where a click-through originated. Using that tool, I made a link that looks like this:

Disecting the link (the interesting stuff is after the ?) I have told Google that I want the link to appear as if it came from twitter, that the campaign name is Test and that the medium is web. After I put this link through the website it becomes and it goes to the homepage of this blog (apologies if you are reading this in a few months and you get redirected to a more current post). However, the underlying tracking data is retained. This becomes really powerful if you want to test different marketing media. For instance, no one will type this long url:

if I have printed it in the March magazine but they might be willing to type (use the "Optional Custom name" feature) which will not only take them to the blog, but will record that they came from the ad in the March magazine. Note well, the link shorteners work on the principle that 6 character long strings of 60 combinations per character is a gigantic number of combinations (I think there's a factorial involved). However, now that I've taken the character string of "MarchMag" over at, you cannot use it. So, pretty soon, this feature may become worthless for this purpose. Go ahead, click on the links, and then I will post what the Campaigns section of the Traffic Sources reports looks like.

The other way to use link shorteners is to find a way to track the traffic that you send to other sites. Remember that each click will first go to the link shortening site and then off to its destination. If you want to measure the effectiveness of various campaigns or word phrases to get people to click a link then measuring traffic at the shortening site can be valuable. However, unlike the previous example, you aren't getting any traffic on a site you own, so you cannot see the traffic. Fortunately, people smarter than I have decided this is important and already offer the ability to track the redirects. The site we've used in the examples, does it. Other sites that offer similar tracking features are,, and (I'm sure there are more, why not leave a comment with your favorites). Notice something about and that they don't end in .com or one of the familiar 3 character endings. Turns out that each country has been granted a 2 character extension for URL's. In America, we have .us but it is overshadowed by .com, .org and .net. The .ly code that uses is the country code for Lybia and the .im code is for the Isle of Man. Using two character country codes to make intersting url's is probably a whole blog post in itself.

Note to early readers of this post: go ahead, click on the links. It will help use create some pretty graphs to insert into the post so that people can see how all of this works.

Saturday, February 28, 2009


Twittersummary: Researching Collanos, Google, Drop Box and other free tools to implement cross platform Microsoft Groove type features.

Although Microsoft offers generous pricing to non-profits like mine, they are still an expensive alternative and they still design for a world of fat desktops running Windows with IE as the browser. As a recent example, I set up a small Microsoft Groove environment for us to collaborate with some of our volunteers and chapter members on a small project. Given the peer to peer sharing aspect, we even had visions of this being a way to strengthen our COOP. We chose to set up our own relay server, but we could have certainly used Microsoft's systems to drive costs down. If we were able to avoid a few conference calls and travel, the startup costs would pay for themselves with only one project. Groove is really robust, it offers document collaboration and versioning, chat, calendar, tasks, discussion groups and hooks into the rest of the MS Office suite.

The trouble was, key members of the project team either didn't want to or could not load the Groove client (Windows only). The whole thing fizzled out as we found that we didn't really want to duplicate our email, calendar and chat features within the workspaces. We don't even use the system internally anymore, and as I write this, we are dismantling the infrastructure.

As an IT manager, the struggle continues for me: Microsoft makes some of the best software in the world as long as you drink their Kool-Aid and have only Microsoft products in your environment. As soon as you add one Mac, one Linux box, one Firefox install; things begin to become more complicated.

So, as we realized that Groove might not solve all of our problems I started to search for some replacements. I was looking for a way to collaborate with people who may not have much technical skill (install had to be easy), who didn't have Windows, who needed some security for the documents and who didn't have access to my Enterprise network. I'm not going to give an exhaustive review of each system below (I do have links at the bottom to other reviews that do this). Just a few quick sentences to give you some ideas about what I liked.

As a little side note, using these systems and the other systems that are appearing on the Web requires an account/password for each one. With all of the accounts I've created over time, it's getting impossible to keep track.

Collanos. They don't say it in their lead paragraphs, but Collanos might as well call themselves "Groove for everyone else". Users of Groove will recognize lots of the features (file sharing, discussions, group calendar, presence). The two big differences are that Collanos doesn't have hooks into my Office applications and Collanos has clients for the three leading OSes. Collanos is written in Eclipse (Java) so cross platform becomes easier to execute. Like Groove, Collanos is using a P2P model and regularly replicates when participants in the workspace are connected, so that one can go offline and continue to have access to the local copy of the workspace. I had a few issues with an early version crashing, but I've since used a more modern version and found it to be quite stable and usable. If you want Groove but can't use it for some reason, I would look at this first. Free to use, and they seem to be moving into the "pay for an SLA and better support" model. I like that model. The basic-for-free-pay-for-advanced-features model seems to be catching on in Internetland. It's a nice change from pay-upfront-and-you-can't-return-the-software-because-you-opened-the-box model.

Google Suite. I've been watching the Google suite develop it's offline parts. I can cobble together a good set of document collaboration and some groupware features using Google Docs, Google Calendar, and of course GMail, Chat and Google Groups. Google is not P2P (that means it requires the Google servers to be available to work). However, I'm watching the expansion of the Google Gears project that lets people keep offline copies of their documents. Maybe P2P features are on the horizon? If you don't want to have the people on your project download something to their browser, this can be a nice alternative as everything is web based and there's nothing to install on the client. Maybe it's because Google has so many apps now or maybe it's because there isn't a rich way to see the modules as a dashboard (though iGoogle is getting close) that this feels like a bunch of apps rolled together rather than one app that does many things.

DropBox. Sometimes, less turns out to be more. DropBox is actually what we are now using for our collaboration. After all that time, and exploration, we came to realize that in our case we already have pretty good calendaring and email capabilities. We really need a way to share files and update those files both at work and home. Drop Box meets that need pretty well. On my Mac and on Windows machines, the local replica of the online documents inserts itself pretty well in the File system (Finder and Windows Explorer). Drop Box has a nice feature where users can access the shared folders via a web interface if they are at a computer that does not have the client installed. Some people get confused by the fact that they can see the files on the website and see them locally so we've had some issues at work with file duplication.

Little things to think about:
- if one person backs up their local copy of the workspace then you have some DR built in
- simple text files in the workspaces can take the place of status and bulletin boards
- the person on the team with the worst connectivity and oldest computer is likely to impact what you are capable of using

Drop Box
Google Apps

Other Reviews of these products:

Drop Box

Groove (these reviews were the hardest to find)

Google Apps

Other products that look like they might be of interest if you are trying to solve this same problem.