Saturday, April 28, 2007
Minor Update to Notebarn
There was small focus-related bug that would manifest when the user returns to Notebarn after an Exchange sync. I thought it had passed a test earlier in the week (before the initial release) but I must have gotten distracted and messed up the test, because the bug was back. It passes the test now, and focus works the way it's supposed to. Honest.
It allows over-the-air update-in-place ... that is, you just run the new CAB file from the project page on your device, and Windows Mobile replaces the old version with the new one.
Tuesday, April 24, 2007
Free Smartphone "Notes" with ActiveSync/DirectPush Support
So I decided to write a little notes application that would sync with Exchange. If you like this idea and want to try the app, but don't want to hear any more geekspeak, you can get the app and instructions straightaway from here.
If you're still reading, here's what I did... The Pocket Outlook Object Model, which is the first stop for manipulating Outlook/Exchange data on the Smartphone, does not support note items. I wasn't sure if the Windows Mobile MAPI APIs covered notes, and I didn't really want to go that route as a MAPI novice, having heard many MAPI integration tales, none of the pleasant.
The Outlook Web Client accesses notes via AJAX, hence there is a web service endpoint of some flavor that can manipulate notes (Outlook can obviously get this data via HTTP too, since it can be instructed to operate in that mode). I could have sniffed/scraped that interaction ... but I wouldn't the get DirectPush I was jonesing for.
I took an easier route, and chose to store my notes as delimited strings in the body of a Task called "My Notes"
Since Exchange, Outlook, ActiveSync, and DirectPush take care of syncing my Tasks folder, I don't have to worry about that. And Tasks are first-class entities in the Pocket Outlook Object Model, so reading or writing one in C# is about 3 lines of code.
This approach worked well. I built a UI for the Smartphone using TextBoxes, put in the parsing logic, and I was set. On the Outlook side (or Outlook Web), I just open up the task called "My Notes" and there are all my notes, delimited by the same string. I can edit them, save, and the changes are propagated.
Only two wrinkles showed up.
The first is that Outlook 2007 is lazy about syncing the Tasks folder with Exchange, at least when it's set up to connect over HTTP. I cut my app out of the loop completely when testing this, by running Outlook 2007 in one window, and Outlook Web Client in another window. Web client read and committed changes to tasks immediately, while in order to refresh tasks in Outlook, even restarting Outlook did not always work. So, bummer... for now, it's an FYI.
The other interesting bit was the syncing logic in the phone client. The goal was to have the data saved and restored (when updated from the Exchange side) as automagically as possible. I've commented the relevant code, most of which lives in the Notebarn_Activated event handler, so you can take a look at the source if you like.
Any time you switch away from the app, or edit a note in full screen mode, your notes are saved, and any time you switch back, if Exchange has updated the Task data but you haven't, your notes are reloaded from the Task. I've tested various approaches and this one has worked the best for me.
I hope it works for you too. The project page (with source) is here.
Thursday, April 19, 2007
When "All-You-Can-Eat" is the Wrong Plan: a Plea for Metered-Rate Software
Why can’t I license productivity software on a metered-rate basis?
I had a mini-project that required vector-art manipulation. The assets I was using were Illustrator files, and I felt Illustrator would be the best tool for the job. But I didn’t have a license for Illustrator. I’ve always wanted Illustrator, but not enough to lay out the big bucks … after all, I would only fire it up a couple of times a month. Ditto for things like Photoshop, QuarkXPress, Premier and lots of other neat tools. If only I could install them and license them on a usage basis!
Without this sort of licensing, the options include:
- Use some substitute app which might not be as good, as useful, or industry standard
- Obtain a cracked/pirated copy of Illustrator
- Find someone with a licensed copy and go use his
- Install a new trial copy into a virtual machine (kinda gray-market, and a bad option for heavyweight apps anyway)
With metered licensing, here are potential advantages:
- I get to use Illustrator, becoming (hopefully) more productive
- My company benefits from my productivity and from lower licensing costs than if I needed to buy a full license
- Adobe benefits because I develop my skills on their app, strengthening its hold in the market, and I don’t go install my 90-day trial of this
- Adobe receives revenue from me where otherwise they would not
The metered approach is a total no-brainer: I can have all the apps I want installed permanently (not 30-day trials) on all my computers. At a cost of few cents or a couple dollars, it’s easy to pay as I go… and if start using the app heavily, the bills add up to the point that it’s clearly cheaper to buy. Maybe the publisher is even nice enough to apply some rent-to-own logic, so once I’ve dropped a few hundred buck, I am offered a discount to buy a permanent license.
It makes no sense to charge the same amount for Premier or Final Cut Studio regardless of whether the customer only edits a couple of videos a year, or is a professional editor who makes a living with it. One approach is for a publisher to create lots of SKUs at different price points for different user levels (Visual Studio Express Editions, Standard, Professional, Team System, Tools for Office) but that puts a huge burden on the publisher. Just let the users install the Ferrari version, and charge ‘em for what they do with it!
The infrastructure is already there — most of these apps are available on some kind of trial basis, and the entire install can be downloaded from the publisher’s site.
The per-copy tracking infrastructure is there for many publishers — activation codes are commonplace for expensive software.
Micropayments? Aggregate the charges on my “Microsoft” or “Adobe” or cross-industry-pay-per-use account, and bill me every quarter or whenever the total is high enough to justify it.
Tracking my activity in the app? That’s easy enough (LexisNexis has done this for a long time). Don’t charge me per minute or session, that encourages me to shut down the app, and makes it really expensive for a newbie to learn. Charge by use case: if I do something that every freeware clone also does, it’s cheap… but if I’m hitting the killer differentiating feature, whatever that is, make me pay.
This is free money for software publishers. Folks who absolutely need the app will already have it (hopefully legally), while pirates just bittorrent a crack. The metered system works for all of us in between, and I think that’s orders of magnitude more people than the publishers even imagine.
Tuesday, April 17, 2007
O'Reilly Web 2.0 Expo: Thoroughly Unimpressive == Very Encouraging
- The show floor was obviously, painfully small, even for a one of the smallest rooms in Moscone
- Some of the BigCo sponsors seemed detached and irrelevant
- The "food and libations" where hard to find, hard to pry away from vendors, and generally in short supply
- The genuine web 2.0 plays seemed like they weren't sure why they were here; they weren't adept at engaging those of us who wanted to learn stuff that's not obvious from 5 minutes on the website
- The tooling companies got a ton of attention, and were not prepared to leverage the attention... I went back to one tooling booth no less than four times to try and get a demo and conversation, but they were in long one-on-ones and had no bandwidth and no "backup chatters" (the ones who typically try to engage you at a show, triage you, and then if you seem important go the extra mile to find you the Chief Architect or the VP of Foobar to talk to)
- The companies trying to sell services (consultants) have not figured out how to get attention and relevance
Instead, I realized that web 2.0 and the traditional tech conference are at odds conceptually. They don't make sense together, and the fact that this was obvious so fast means the web 2.0 ecosystem has not in fact been corrupted by so much froth that it starts looking like 1999.
I was really thrilled to see that by this yardstick there's a whole lot more runway for web 2.0 innovation before this plane floats up and away.
Lemme run through that list another time and tell you exactly what I liked:
- Small show floow? Who needs a show floor? Web 2.0 exists on the -- gasp -- web! It's good to talk to the humans at these companies, but booth square footage is unimportant.
- Big corps seemed irrelevant? well, many of them are irrelevant ... a web 2.0 meme is they became irrelevant as this wave of innovation took hold: Pricey license to get started? Whatever. Enterprise web stack with more classes in it than my app has lines of code? (I'm not exaggerating, this is a true story!) Get real. Proprietary SDK with a restrictive license agreement? No thanks, buddy.
- Not enough free food and drink? This means there isn't hot and cold running money just yet, and the folks who absolutely must have hors d'oevres aren't there. Web 2.0 is more about Promax bars and BevMo (or Costco) than about catering.
- Real web 2.0 plays seem flatfooted in the "traditional conference setting" -- of course they do. The traditional tech conference is really a marketing-oriented event. These companies were on the cluetrain from the beginning -- their marketing is via their users, and their web forums and wikis (with employee participation) are the best part of a tradeshow everyday, without the nonsense. Their schwag is the free service you can use right off their website.
- Tooling is going to be increasingly important, and the best tooling companies will get their stuff together as the market matures. I think these companies got caught a little by surprise, and still have to work out a way to charge enough to stay in business, without charging too much to... stay in business.
- Lastly, the consultants. I believe there is a place for consulting in the new web world (after all, I work for a consulting firm) but the traditional pitch is going to have to change. There are a number of themes I think make real down-to-earth sense around web 2.0 consulting, but they'll have to wait for another post.
When JavaOne went small, it was a symptom of a serious illness. But then the virus took up a home in web 2.0 like some kind of endosymbiont and here we are.
Monday, April 16, 2007
Out of the Naming Shadows
At first it seemed that the Microsoft branding group got defensive, citing trademark issues, cultural sensitivity, etc. as reasons to steer away from stronger names. But now it looks like they’ve come around: first we found out that Expression Interactive Designer would be called “Blend” – this doesn’t redline my engine, but it’s definitely a step up.
Now “WPF/e = Windows Presentation Foundation Everywhere” has the much sexier name “Silverlight” which makes me want to go grab a wizard’s cloak and conjure something. That’s a pretty encouraging reaction for a technology like this one. Besides the fantasy association, there’s also the sound of “silver screen” cinematics or a spotlight, which works for this product as well.
Saturday, April 14, 2007
GrandCentral Heralds VoIP Apps (Fer Real This Time)
GrandCentral is rockin'! OK, their "Beta" is a genuine beta -- I've had some calls drop, calls not go through, voicemail never pick up... they have some bugs in the software and some issues in ops. But it's still a fabulous service. And when something does go awry there's a real live human on the other end of a chat widget. She's helped me a couple of times and is a real pro. Not to mention the longer the beta goes on, the longer you can enjoy the full power of GrandCentral, including unlimited calling into the PSTN, for free!
The "one phone number to rule them all" concept has been around a long time. The question is when to stop being a skeptic and when to start believing. Photorealistic graphics, good color printing, network-based apps with rich interactivity... all were promised several times and several years before becoming everyday reality. I'm not perfect at figuring out just when "this time around" becomes the time it really works. If I were, I'd be a VC instead of a developer. But I believe the time is now for VoIP and advanced apps for VoIP. Why? Besides Skype, and corporate adoption of VoIP, I think when Verizon sues Vonage over questionable patents in order to put the brakes on, and people actually care, then the time has come. Just like mobile apps had clearly crossed the chasm when everyone worried about NTP shutting off their Blackberries.
I tried to go "all in" by making the GrandCentral number the only one on my business card (due to a clerical error it didn't completely work). With my desk and my cell phones both ringing for business calls a client or coworker would be guaranteed to find me whether I'm in a conference room, at my desk, or out for a coffee -- plus I wouldn't need to check my office voicemail remotely, or force a client to deal with "I got voicemail... I'd really love to get feedback on this issue now, but is this really important enough to call his cell?"
For me, the remaining question isn't whether these services can be hits. They can. The question is how to manage an enormous number of communications accounts each with its own fees. I have a landline (originally for DSL, now because it's still cheaper for local by nearly an order of magnitude than cell or VoIP calls); a cell phone with minutes and a seperate data high-end data plan; a Gizmo phone that offers some free calls, but mostly charges 1.9 cents per minute (if you're keeping score, that's lower than a cell phone but higher than a landline); and GrandCentral, which is free in beta but plans to charge for connections into the PSTN. And this doesn't even include the cable modem account that gets IP to my house.
Each of these services plays a specific role and they all dovetail together to keep me connected to pretty much whatever I want. But there has to be some way to simplify this picture for mass adoption. Unfortunately, the only players in a position to do this are large telcos or cable companies, and they aren't known for innovation or customer service. In the Bay Area, for example, Comcast -- which offers "bundles" of cable Internet, TV, and VoIP -- bought radio time to hawk photo sharing as their great new thing. This is San Francisco in 2007, for godsakes, gimme a break. I'm not taking sides with AT&T either, who would also probably be happy to take $200 a month from me to sell me around half of what I need.
The other question is how number portability applies to the new services, in case this time around turns out to be more like the last time around.
Wednesday, April 11, 2007
ASP.net DB-backed Micro CMS in 50 Lines and 5 Minutes
There are great lightweight CMS apps just for this, such as wikis. But with asp.net and SubSonic, I put this micro-CMS up in about 5 minutes. If you need a little area with WYSIWYG editable web content and binary uploads (images, PDFs, etc.) you might find it useful. n.b.: for my site, the created pages are meant to be be publicly readable and writable. If you want to restrict access, you will need to make some adjustments for that purpose. So here's how to brew it up:
Step 1: Create a table in SQL Server 2005
CREATE TABLE DataObject (
[ID] [uniqueidentifier] NOT NULL CONSTRAINT [DF_DataObject_id] DEFAULT (newid()),
[TextContent] [ntext] NULL,
[ImageContent] [image] NULL,
[MimeType] [nvarchar](50) NULL,
[CreatedOn] [datetime] NULL,
[CreatedBy] [nvarchar](50) NULL,
[ModifiedOn] [datetime] NULL,
[ModifiedBy] [nvarchar](50) NULL,
[IsDeleted] [bit] NULL CONSTRAINT [DF_DataObject_IsDeleted] DEFAULT ((0)),
CONSTRAINT [PK_DataObject] PRIMARY KEY CLUSTERED ( [ID] ASC ) )
You'll notice a number of convention-over-configuration moves that let SubSonic do some of my work: Created/Modified On and By as well as IsDeleted.
The main data fields are TextContent as ntext (i18n clob), ImageContent (blob), and MimeType. The PK and ID is an autogenerated GUID.
Step 2: Create a web page for editing and uploading content. Grab FreeTextBox for WYSIWYG HTML editing. Then toss in controls:
<FTB:FreeTextBox ID="FreeTextBox1" runat="Server" Width="600px" />
<asp:Button id="SavePageButton" runat="server" Text="Save"
OnClick="SavePageButton_Click"/>
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button id="Upload" runat="server" Text="Upload"
OnClick="Upload_Click" />
<asp:Label ID="LabelForNewURL" runat="server">(none)</asp:Label>
Add line breaks and formatting to taste.
Step 3: Add some code-behind to save the page.
protected void SavePageButton_Click(object sender, EventArgs e)
{
object id = Session[Globals.PAGE_EDIT_ID_CONSTANT]; // add some code in
// Page_Load to grab this out of the request,
// and load it into the FreeTextBox instance
DataObject o;
if (id == null)
o = new DataObject();
else
o = new DataObject(id); // this is SubSonic foo...
//read all about SubSonic, which rocks!
o.MimeType = "text/html";
o.TextContent = MyHtmlUtilities.CleanUpHTML(FreeTextBox1.Xhtml);
// Remove anything we don't want, like scripts
o.Save(User.Identity.Name);
LabelForNewURL.Text = "URL is http://www.mysite.com/Object.ashx?id="
+ o.ID;
Session[Globals.PAGE_EDIT_ID_CONSTANT] = o.ID;
}
Add some more code-behind to save an uploaded file.
protected void Upload_Click(object sender, EventArgs e)
{
if (IsPostBack && FileUpload1.HasFile &&
FileUpload1.PostedFile.ContentLength < MAX_LENGTH)
{
String fileExtension = System.IO.Path.GetExtension
(FileUpload1.FileName).ToLower();
if (allowedFileTypes.ContainsKey(fileExtension))
{
DataObject o = new DataObject();
o.MimeType = allowedFileTypes[fileExtension];
o.ImageContent = FileUpload1.FileBytes;
o.Save(User.Identity.Name);
LabelForNewURL.Text
= "URL is http://www.mysite.com/Object.ashx?id=" + o.ID;
}
}
}
This code omits the definition of MAX_LENGTH, a limit to the length of uploaded files, and allowedFileTypes, a Dictionary<string, string> that maps allowed file extensions to MIME types, like so: allowedFileTypes[".png"] = "image/png";
Now you have file-upload, database storage, and WYSIWYG editing in around 20 lines of code and 5 markup tags!
Step 4: Create the Object.ashx handler that serves these pages and objects. Add a new asp.net request handler like so:
<%@ WebHandler Language="C#" Class="Object" %>
using System;
using System.Web;
public class Object : IHttpHandler {
public void ProcessRequest (HttpContext context) {
DataObject obj = new DataObject(context.Request["id"]);
if (string.IsNullOrEmpty(obj.MimeType))
context.Response.ContentType = "text/plain";
else
context.Response.ContentType = obj.MimeType;
if (!string.IsNullOrEmpty(obj.TextContent))
context.Response.Write(obj.TextContent);
else
context.Response.BinaryWrite(obj.ImageContent);
}
}
That's it! Of course if you wanted to build in more features here, it's easy to do all sorts of stuff, from adding an attribute for a document/file name, to sorting or searching the database table to generate product thumbnails, automagic menus or site maps, etc. Ok, including all the SQL, asp.net markup, and the C# (except braces) that's at least 51 lines.
Addendum: I had to monkey with line breaks to keep the code readable outside of RSS readers, so never mind the line counts, I think the code is fun and the point is made anyway.
Monday, April 09, 2007
Mobile RIAs with FlashLite - Evaluation
Wow. That's great. So how well and how easily does it actually work? I set out to do a quick evaluation of getting an interactive network connected app up and running on Flash Lite.
For my target platform, I picked Flash Lite 2.1, 320x240, on Windows Mobile, for these reasons:
1. Since this spec lies toward the high end of the Flash Lite ecosystem, I knew that if major things failed on FL2.1 and a 200MHz+ processor, they would be very unlikely to work on downversion FL
2. Real HW-level emulators are freely available for Windows Mobile, something that's not true for many mobile phones
3. I own a compatible device, and when working with devices, at a certain point there's just no substitute for the real hardware
For my "application," I wanted to see if I could implement a couple of use cases for a mobile 2.0 site for ordering food. This seemed like a reasonable real-world use for a Flash Lite application outside of entertainment; the use cases involve retrieving an order list from the web site, letting the user choose one, and then retrieving relevant destination restaurants where the order could be sent.
First I sketched out a simple Flash app which used the MX components for the onscreen text boxes, lists, and buttons, as well as for the SOAP web service client. I targeted Flash 7 (FL 2.x is essentially Flash 7), and built. After debugging on the PC, I tried it in the
WM 5 Smartphone emulator (best enjoyed splashed over this SDK).
No joy. The movie starts to play, but then seizes up and the standalone Flash Lite player gives this error message: "ActionScript stuck" in both the emulator and real device. The culprit seems to be the mx.controls.List class, which is either too complex for the runtime to handle, or else triggers some low-perf detection code meant to ensure movies stop running altogether before they run badly. My web service connection via mx.services.WebService and SOAP was causing a similar problem.
This wasn't looking good, since those components date back at least to Flash MX 2004, and the hope was that a FlashLite 2.x app could be authored more or less like an MX 2004 app. Googling around, I found that the MX UI components do not, in general, work on Flash Lite 2 (a few do, but the kit as a whole cannot be assumed to work). This leaves the old-school approach of custom writing the UI widgets as part of the movie (not a bad approach for something so small) or finding widgets that would work. Since I wanted to complete this evaluation quickly, I looked for a widget kit for FL, and found Jesse Warden's Shuriken Components (see also his presentation here). For my purposes, this was perfect. Easy to use, and ran without a hitch on FL 2.
Next I needed web service connectivity. By adding this
<webServices>
<protocols>
<add name="HttpGet"/>
</protocols>
</webServices>
to an ASP.net app's web.config, you can turn on (Lo)RESTful behavior in addition to SOAP. (This switch enables not just GET but a simplified XML response format.) Next I used XML.load in ActionScript and gave it the appropriate URL to GET. This worked great on the emulator and device.
Then I added a couple of lines of "business logic" in AS, to allow additional dynamic interactions, so that I could bang on it without worrying about caching in the Windows Mobile HTTP stack or in Cingular's WAP-gateway-proxied network.
So far, so good. These patterns (movie-based or Shuriken UI + XML.load for web services) should work well on the high end of FlashLite (Windows Mobile devices range from about 166 MHz to 520 MHz; I was using a 220MHz OMAP). The next step will be to find some more constrained implementations that still support a the FlashLite "application" content type (e.g. a Nokia S40 device with FL 2.0) and try it out.
Thursday, April 05, 2007
Samsung Brings Software Game?
I want to talk about the interesting partnership to be observed among the companies bringing this product out.
Samsung brings fabulous hardware to the device, which is pretty much what we expect from Samsung. Cingular brings the marketing and enough data bands (GPRS/EDGE/UMTS/HSDPA) to allow limited simultaneous voice and data, which is a genuine differentiator and makes an impression the first time you receive and respond to an email while you're on a voice call. Microsoft brings WinMo 5 Smartphone AKU 3+.
Samsung, though, has gone beyond the usual OEM manufacturer role. In addition to the promotional web site and the basic drivers for the hardware, they've bundled a set of apps carefully chosen to complement the Windows Smartphone OS and improve the value and usability of the phone.
User feedback has identified a number of weaknesses in Smartphone, some of which are addressed now in WinMo 6, some not. For example, in the past, users have screamed that the core app set is missing some basic PIM apps like a notepad. Never mind that you can get notepads online -- that's a step beyond a lot of consumers. So Samsung hops in with a mini productivity suite to fill in the holes: an enhanced filesystem browser, a notepad, calculator, and bunch of other stuff.
The stock Smartphone home screen has taken a lot of heat, so Samsung codes up a handful of alternates with different information densities and usability features. Need to read PDFs or Office docs? Samsung has licensed and supplied a version of Picsel Viewer -- frankly the video quality and smooth experience on this product is better than the Smartphone shell; maybe Microsoft should buy those guys!
The partners seem to be bringing their A game to the overall ecosystem around this device too: according to CrunchGear, Cingular will unlock this GSM device for free; Microsoft is working with Cingular to release an OS upgrade to WinMo 6 this year; and Cingular jumped all over early battery complaints with a pretty straightforward process for snagging a free extended battery.
Without being overly optimistic and wondering if a major shift is happening in the smartphone world, why does everyone seem to be trying so much harder than usual in this particular collaboration?
Tuesday, April 03, 2007
Why Does Software Suck? Why Do You Think?
I want to add two words to the "software sucks" discussion: organizational dynamics. If you start every conversation about software quality, process, security, predictability, etc. with these two words, you'll be on the right track.
Look at technology as just one competency of an organization, then zoom out and look at the whole organization. Now ask "do I believe that in an effort demanding some amount of precision, control, and predictability, this organization can execute?" With many organizations it's immediately obvious that the answer is "no."
If that question seems too vague or unfair, then zoom back in and take a look at specific capabilities inside the company. Look at product management. Look at marketing. Look at HR. Can you keep a straight face while they talk their talk?
Put it this way: think of a company where you have observed "software is crap" in action, whether it's a software product they sell, some line-of-business software they rely on (managing their type of widget or service), or a horizontal product they use to deal with the world (CRM, accounting). Now think of their customer service, or marketing or another department. If you can't take their marketing seriously, or they preach "great customer service" while delivering something else (maybe of great value, but in any case accompanied by awful customer service), then as an organization they are fostering cognitive dissonance at a group level.
The ability to tolerate cognitive dissonance is necessary for most organizations in order to allow flexibility and to prevent entropy from creating constant crises. But more than the "magic amount" of such tolerance just translates to being too comfortable with corporate doublespeak and BS.
In any case, dissonance and software is a bad thing because the machines that run software are remarkably anal. Compilers are adamant about not tolerating dissonance in the scope of a specific application. You can slip some shenanigans in when you're working in a scripting environment, but eventually the gap will manifest somewhere. And when an "enterprise app" is made up of various subsystems and databases, organizational cognitive dissonance leads to "HAL Syndrome" -- the ailment of the computer in 2001 which eventually starts doing undesirable things because it has been secretly given two sets of logically incompatible inputs.
Basically, a necessary (not sufficient) condition for software not to suck is that the organization producing it must have the capability to know when it is being hypocritical or producing conflicting messages, to recognize there is a problem, and to set some priorities which can resolve organizational discontinuities. Without that self-reflective and real self-modifying capacity, the software output may sometimes work, but has no chance of being predictable, reliable, high quality.