The Old Blog Archive, 2005-2009

Blog Moved

I tried Tumblr and I liked it. So my new blog entries are over there now. Here’s link.

Which also means this blog will no longer get updated. But I’ll keep the entries.


I: “I should shop a good chat app on the App Store so that I can talk to you more often.”

She: “I thought you already have a phone?”

That 1904 Thing

When we were planning for TapExpense 2.0, we have made the decision to make Excel® spreadsheet export the No. 1 priority. This was harder than we had thought.

An expense tracker without export function is quite a dead box. That’s why almost every iPhone expense tracker you find in that category provides CSV export. CSV stands for comma-separated values. It’s a very simple, plain-text format. Each line of the file represents a row, columns of which are in turn separated by commas, hence the name.

Different iPhone expense tracker provides different way of exporting. TapExpense mails the CSV to you as the body text of an email. This requires no installation of other third-party software (as some competitors do). On the other hand, you need to open the email client on your desktop computer, copy-and-paste the body text into another text file, save it as a .CSV file, then open it up in your spreadsheet program. It’s a bit of work.

That’s why we decided that the best way is to export directly to Excel spreadsheet file, mail the file to you. You can then open the file in your spreadsheet program, preview it in your or Mobile Mail, or if you use Gmail, you can view and use the spreadsheet directly. CSV does not have such convenience.

If you’re a Windows iPhone user, that’s the end of the journey. If you’re a Mac user, using Microsoft Office for Mac, you might want to read further to understand a curious design in Excel called the 1904 problem. This is important when you try to copy-and-paste the exported spreadsheet into one of your existing workbook.

A Very Short History

As it turns out, Excel actually has two date systems. One is the 1900 date system, another the 1904 system. Why there are two systems is purely historical (see this Microsoft article for details). When Excel first came out on PC, it had to support the date system that was used by Lotus 1-2-3, then the most popular spreadsheet program (later dethroned by Excel). Excel for Mac was not designed to have such compatibility in mind, so the 1904 date system was used instead. A detailed (and more technical, programmer-oriented) explanation can be found in this excellent blog entry by Joel Spolsky.

So How Does It Affect Me?

Excel’s two date systems have an inconvenient consequence: You cannot copy-and-paste the dates from a spreadsheet using the 1900 date system to another spreadsheet using the 1904 date system (and vice versa). To make things worse, there is no way you can save a 1900-based spreadsheet file as another 1904-based file (and vice versa). There are both legitimate and historical reasons for Excel not to do the conversion for you, so we are not here to blame any one at Microsoft.

Now here’s the thing: TapExpense exports 1900-based Excel spreadsheet files.

Because a majority of Excel spreadsheets in the world are created by Excel on Windows, and if you’re a Mac users, chances are that you open up a lot of Excel files created by Excel on Windows. To ensure the maximum interoperability, we have decided to use the 1900 date system.

But! If you want to integrate the data on the exported file to your own workbook created by Excel for Mac, you’ll immediately notice that every date that is pasted to your workbook is advanced by 4 years and one day. That’s no good! (Click for enlarged version of picture).

Pasting 1900-Based Date Data to 1904-Based Worksheet: The Problem

The Solution

Fortunately, all is not lost. If you are pasting data from TapExpense-exported worksheet to your workbook that is created by Excel for Mac, and you found the dates are incorrectly advanced, here’s what you need to do:

Step 1. Enter the value 1462 in an empty cell (any place will do). It may appear as 1/2/08, which is fine (click for enlarged pictures).

Pasting 1900-Based Date Data to 1904-Based Worksheet, Step 1 & 2

Step 2. Select the cell, the press CMD-C or click on the menu Edit > Copy.

Step 3. Select the dates you want to correct. Then click on the menu Edit > Paste Special.

Pasting 1900-Based Date Data to 1904-Based Worksheet, Step 3.1
Pasting 1900-Based Date Data to 1904-Based Worksheet, Step 3.2

Step 4. A Paste Special dialog box shows up. Click the option Values, then click on the Substract option.

Pasting 1900-Based Date Data to 1904-Based Worksheet, Step 4 and 5

Step 5. Click Ok.

Step 6. You can delete the 1462 cell now.

Pasting 1900-Based Date Data to 1904-Based Worksheet, Step 6

This in essenece substracts 1462 from every pasted date cell. 1462 is the difference between 1900/1/1 to 1904/1/1. That’s it!

(Some of you might have noticed that 1462 = 366 + 365 + 365 + 366, but 1900 is not a leap year! You’re right, but that’s an unfortunate bug in Lotus 1-2-3, it’s a fait accompli and the 1900 date system will stay that way.)

The above-mentioned Microsoft article also has step-by-step explanations on how to work with the two different date systems.

What We Have Also Taken Care of

The Excel spreadsheet that TapExpense exports from your income/expense records uses the regional settings on your desktop computer. These regional settings are observed by all major spreadsheet programs (Excel, Numbers®,, etc.) So if your use the German format in Germany, the amounts will be in the format of 1.234.567,89 (period for the thousand separator, comma for decimal point). The dates are also properly formatted (so 12/31/09 in the US format becomes 31.12.2009 with the configuration above).

In fact, if you prefer the CSV format, you’ll notice that TapExpense 2 also does the CSV right–dates correctly formatted, amount numbers using the right separators, and your Excel or Numbers will understand it when you also use the same regional settings as your iPhone or iPod Touch. These are some of the details we have taken care of when we were working on TapExpense.

We’d Like to Hear From You

So in short, if you are a Windows user, or if you work with Windows-created Excel spreadsheets (you can also set your Excel for Mac to use the 1900-base as the default date system), there’s nothing you need to do when you copy the date from TapExpense-exported sheets. If you need to copy date to a 1904-based workbook, just follow the simple steps above, and all will be fine.

That’s pretty much about it. Do you have any suggestion that we can make it better? We have thought about an option (such as “export 1904-based workbook”) in TapExpense, but given the length the extra explanation might have to get into, that does not seem to be a good design. Or does it? We’d like to hear from you.

TapExpense 2.0.1 Available

TapExpense 2.0.1 is now available on the App Store. This is a minor update but fixes a nagging bug that caused trouble when you tried to add a new category (or currency, group etc.) to a reordered list. This is now fixed.

It’s good to see our app come back to the market after first a hiatus then some long weeks of rewrite. We’re doing well on App Stores Italy and Japan (TapExpense is now in the Finance Top 20 Paid Apps List in both stores), and now in the Top 5 Financial Paid Apps List on App Store Taiwan (it’s actually in the Top 100 Paid Apps, All Categories list, too). Still, software development does not stop there. Unlike a finished book or a recorded music, software is organic in the sense it continues to grow after a release version is pushed out of the door. We’ll continue working on TapExpense to make it better.

TapExpense: The Making of a 2.0

After months of working and reworking, I’m happy to announce that TapExpense 2.0 is now available on the App Store.

TapExpense is an expense tracker for iPhone and iPod Touch. Version 1 started with a simple design. It supported multiple currency (a major feature) and could export data as CSV-formatted email text. Version 2 is a rewrite. It now exports XLS spreadsheet files. It also supports income categories, vendor/payee/source field, and group/trip field. It now uses a numeric keypad to speed up entering records, and has a passcode lock that lets you show off your other iPhone apps while keeping personal finances discreet.

All the new features, while keeping the fundamental design that aims to keep the balance between workflow simplicity and feature richness.

And we have a gorgeous icon too!

The road to 2.0 was a long journey. My colleagues and I have learned a lot from the process. TapExpense 1.2 was the expense tracker I enjoy using everyday. TapExpense 2.0 is a software product I’m proud of and I want to tell everyone about it.

So if you’re an iPhone or iPod Touch owner, and if you’re looking for an expense tracker, reading this blog entry, be sure to check it out and give it a try.

We even have a lite version that has every feature of the paid version and is fully functional. It neither expires or annoys. The sole limitation is that it only shows, reports and exports the latest 7 entries in any given date range. And you can continue using it adding as many entries as you like. Later, if you decide this is the application for you and you buy it, you can always transfer all your entries in the lite version to the paid version. It’s just that easy.

In the coming weeks I’m going to write more about TapExpense 2.0, about the new features in detail, about the nuance in the decisions of adding or dropping a feature, and about what we have learned from our users and our own usage.

Before then, find out more on the App Store: TapExpense, TapExpense Lite. And Lithoglyph company website. The paid version is USD 4.99 (or the equivalent of it in Europe and other stores). Existing user gets free upgrade.

And let us know how we can make it serve you better too.

Thank you!

Installing gitosis on Mac OS X

Garry Dolley’s guide to gitosis installation is excellent and to the point. For those who don’t know, gitosis is a nifty tool that helps you host git repositories via one shared SSH account. gitosis manages access control for you, so you no longer need to rely on the capricious UNIX permission/group settings which is the major headache for hosting your own git repository using ssh://.

Garry’s guide is written mainly for Linux users. For Mac OS X developers, there are a few minor things to take care of, and a few others to skip. For example, /usr/local/bin is not the default path on OS X. On the other hand, you don’t need to install Python. Creating user account is a bit different too.

So here’s a short step-by-step instruction on how to setup gitosis on Mac OS X:

  1. I assume you already have git installed. If you don’t get the latest git for Mac OS X. The quickest way is to get the binary package prepared by Tim Charper and gcheshire. Get it here. Consider getting gitx too.
  2. Find a working directory you like on the target server, then check out gitosis:

    git clone git://

  3. Install it (you need to sudo):

    sudo python install

  4. Now, create a new user from System Preferences > Accounts. Add a standard user will do. There’s no need to make it an admin account. Let’s call it “git”.
  5. Login with the just created user account. Create .bashrc, fill in the line below:


    This is because on Mac OS X, /usr/local/bin is not in the system’s default exported path setting. We need path access to the directories above.

  6. Now, assuming you’ll be the first user and the admin, you want to use your own public SSH key to access the shared account (that’s the whole point–more on this later). Get your onto the target server, or generate using ssh-keygen -t rsa on your local machine. If you don’t know what I’m talking about, read some tutorial on SSH authentication. A quick guide like this is a good start. Be sure you already know that before you move on–this is the crucial part of using gitosis.
  7. After you get your onto the target server, login to the server with an account with sudo access (which you don’t with the standard user account we just created above). Then do:
    sudo -H -u git gitosis-init < [path of your]

  8. Now login with the standard user account “git”. In your home directory there is already a repositories/ directory, in which you’ll find gitosis-admin.git
  9. Make sure the post-update hook is executable. Do this:

    chmod 755 ~/repositories/gitosis-admin.git/hooks/post-update

From this point on, read Garry’s guide to understand how to manage the admin repository. This is where gitosis is brilliant–you also use git to fetch and update the admin settings! Once you have finish creating your first gitosis-managed repository, the rest is easy. In fact, in our cases, we simply just moved all our bare repositories to under the standard user account’s repositories/ directory. We updated the gitosis config and we got it up and running well.


A couple of veteran Mac developers have come up with the idea of OpenRadar. Anyone who has ever filed a bug to Apple through their bug reporting system (“Radar”) knows its close nature. It’s understandable that you don’t want to disclose your reported bugs on unreleased software from Apple, neither do you want to reveal a bug that has to do with your own unreleased software. So Apple chooses to make it close on fair grounds.

On the other hand, there are situations where you want to make your filing public. I often encounter these two: (1) you have a feature enhance request, but it’s rejected on the ground that it’s a “dup”, but you don’t know if it’s really so, or you want to seek some support from your fellow developers; (2) you want to discuss openly about a bug or a fix which may benefit all.

At any rate this is community spirit at work. It’s amazing to see how Google’s App Engine is used. Will we be seeing a desktop client for that soon, too?

Update: Tim Burks, the person behind the idea, blogs about it in his own words.

Random thoughts, C++0x, transactionable GUI

In-between the problem of structuring your GUI application at higher order has caught my attention. The glaring problem of multi-core multithreading is trapping us developers. We are bound to the limitations of modern graphics system design–to our amazement window systems are themselves very complicated beasts. But while our computation and heavy-lifting parts are migrating to the multithreaded world (hey even network connections are in that area already too), GUI code is still confined to either main thread or the thread that created the component/widget in question. You don’t, can’t, dare not, ought not, may not pass them back and forth between different threads. How quaint.

In other news C++0x shows its promise with all its new syntactic constructs (many of them condensed form of popular idioms, esp. template metaprogramming) and its inherent support of modern threading control objects. And talk about lambda and better type inference. Hey but a working compiler is still years ahead. And will we be still using gcc?

(But I guess I’ll still have problem doing GUI stuff with such a strongly-typed language.)

The real challenge is how to formulate, in my opinion, GUI event and graphics model as trasnactionable operations. Animation frameworks like CoreAnimation show the way, but it doesn’t seem to have become that much generalized yet. GUI programming is in a desperate need of new models that can catch up with the already more advanced, more sophiticated way of (esp. networked) data modeling and manipulation. It’s such a scandal that database operations can be thought as series of rollbackable transactions but GUI ops cannot.

I’ll be happy to see the death of the decade-old event-loop model and its rebirth as a higher order construct. Although that seems a call for declarative UI design but perhaps we’re still far away from that.

[ANN] InputMethodKit Backporting Component for OS X 10.4 Tiger

InputMethodKit Backporting Component, or IMK-Tiger for short, helps
input method developers backport their IMK-based input method apps to
OS X 10.4 Tiger. It is what we use to backport the latest OpenVanilla,
a popular input method toolset in Taiwan, to 10.4.

I’ve posted more details on Cocoa-dev.

Some Updates

Going to be a really short update.

Now you know that I work for (and actually own) Lithoglyph, and we’ve just released a new version of Mondrianum, a color picker plug-in that leverages Adobe kuler color theme resources. And this being a few things that we are working on.

At the same time we’re still thinking hard and moving at a slow pace on giving TapExpense an upgrade. We’ve learned a lot three months after the App Store went live, and we are working on putting them in practice. Redesigning, reforming or simply refactoring an existing app is hard, as it turns out. But we are not yielding to the difficulties any time soon.

I really want to apologize for my slowness at doing anything related to mobilesync-inspect. I believe there are (or should be, but I didn’t do research) other tools that perform somewhat same tasks, hopefully with better UI. I really don’t have time to do all the testing and try out the replace-and-restoration scenario myself.

Apparently mobilesync-inspect belongs to some of the worst kinds of the open source software, that it can’t attract enough developer interest to carry on its development, plus that the original developer (that’s me) simply doesn’t have the resource (time, energy, committment) to improve it further…

ObjectiveFlickr, on the other hand, seems to fare better. There are lively discussions on how to port OF to iPhone–cutting off the NSXMLDocument dependency that is. And I’m glad that there are people interested and enthusiastic enough to do it. My own take would be scrapping XML parsing using NS stack entirely and use libxml2 to render Flickr’s XML response block a simple dictionary. But again that takes some time to re-do a few things.

OpenVanilla is under some major overhaul. Zonble and I are working on a nearly rewritten version of the OS X loader, this time entirely based on InputMethodKit. One interesting challenge is to backport IMK-based loader to Tiger, as it turns out that the market we want to support (Taiwan mainly) still has 50%-55% users hanging on with their Tiger installations. And we actually have found a solution for that, first applied in some in-house projects that we have at our company. The solution will be released as an open source library shortly.

Next Page »