Developers should iPhone-optimize their sites

A while ago I wrote how the Dejal site is iPhone-optimized: when you view it on an iPhone or iPod touch, the website content is reformatted to fit neatly in the 320-pixel-wide display:

I would suggest that any developers who write iPhone software should do this too. So here's some technical info on what I did. This isn't necessarily the best solution, but it works for me, and isn't very difficult.

Firstly, of course, you need to be able to detect whether you're running on an iPhone or elsewhere. The standard way to do this is by looking at the "user agent" value of the HTTP session. In PHP, you can simply look at the $_SERVER['HTTP_USER_AGENT'] global variable. I have the following function in a utility PHP file included on every page (via the header code):

    function getIsIPhonePlatform()
        global $private_is_iphone_platform;
        if (isset($private_is_iphone_platform))
            return $private_is_iphone_platform;
        $user_agent = $_SERVER['HTTP_USER_AGENT'];
        $private_is_iphone_platform = stristr($user_agent, 'iPhone') || 
            stristr($user_agent, 'iPod') ||
            stristr($_GET['platform'], 'iPhone');
        return $private_is_iphone_platform;

This function returns whether or not the user agent is an iPhone or iPod touch, either by returning the state if already known, or determining it if not. It also allows testing the iPhone-optimized pages from your Mac by adding "platform=iphone" to a page's URL parameters (try it; it's fun!).

Not everyone would want the pages optimized, though: a great thing about the iPhone is MobileSafari does an excellent job of rendering "real" web pages. So I also added a checkbox at the bottom of every page to toggle iPhone-optimized mode off and on. The state is recorded in cookie. So I have another function to read that, on the iPhone platform:

    function getIsIPhoneOptimized()
        global $private_is_iphone_optimized;
        if (isset($private_is_iphone_optimized))
            return $private_is_iphone_optimized;
        $private_is_iphone_optimized = getIsIPhonePlatform();
        if ($private_is_iphone_optimized && isset($_COOKIE['iphone_optimized']))
            $private_is_iphone_optimized = $_COOKIE['iphone_optimized'];
        return $private_is_iphone_optimized;
Then the checkbox is actually output (in the footer's include file) via somewhat messy code that uses PHP to output the JavaScript to set the cookie and reload the page when the checkbox is toggled, and the checkbox itself:
    function outputIPhoneOptimizationCheckbox()
        if (getIsIPhonePlatform())
            $query_params = $_SERVER['QUERY_STRING'];
            if ($query_params != '')
                $query_params = '?' . $query_params;
            echo('<script type="text/javascript">' . "\n");
            echo('<!--' . "\n\n");
            echo('function iphoneOptimizedToggled()' . "\n");
            echo('{' . "\n");
            echo('  document.cookie=\'iphone_optimized=' .
                !getIsIPhoneOptimized() . '; path=/\';' . "\n");
            echo('  window.location.reload(true);' . "\n");
            echo('}' . "\n\n");
            echo('-->' . "\n");
            echo('</script>' . "\n\n");
            echo('<p><input type="checkbox" id="iphone_optimized_checkbox"
            if (getIsIPhoneOptimized())
                echo(' checked="checked"');
            echo(' /><span id="iphone_optimized_label"
                Display site optimized for iPhone</span></input>' . "\n");
And finally, the getIsIPhoneOptimized() function is called in the header to use iPhone-optimized or normal style sheets. This is actually a simplification; it actually uses several style sheets, including some common ones and some platform-dependent ones. It also sets the viewport appropriately for each platform — that is a key aspect for iPhone optimization:
    if (getIsIPhoneOptimized())
        echo('<link rel="stylesheet" href="/iphone/header.css"
            type="text/css" media="all" />' . "\n");
        echo('<meta name="viewport"
            content="width=device-width, user-scalable=no" />' . "\n");
        echo('<link rel="stylesheet" href="/mac/header.css"
            type="text/css" media="all" />' . "\n");
        echo('<meta name="viewport" content="width=900" />' . "\n");
Of course, configuring the CSS appropriately is another story, but not too difficult... and very site-specific. Feel free to explore my CSS files if desired: I hope this is helpful. There are a number of other aspects, like fitting images in the available space, supporting movies that can play on the iPhone, and more. If there's interest, I might write more about this in the future.

Dejal products are tweeting!

If you haven't been living under a rock, you've probably heard of Twitter, the service where you can post updates on what you are doing in 140 characters or less, and follow "tweets" from whomever interests you.

If you've been following this blog for a while, you probably also know that Dejal is on Twitter — I post tweets about company topics, product releases, and personal events — pretty much any topic, though typically not very often.

Well, it seems that three Dejal products have developed some personality of their own, and have snuck onto Twitter! You can follow them to learn about releases, usage tips, and whatever else they have to say. Probably best not to ask them for support (the Dejal Forums remain the best avenue for that), but hopefully they'll be worth a follow. You never know, they might just drop hints about updates and future ideas on occasion.

There are a couple of other Twitter accounts, too:

Apple, please support iPhone trial apps

iPhone App StoreThe new in-app purchasing feature in iPhone OS 3.0, as discussed in the keynote, promises to be a great addition. But it seems one of the most popular uses of this feature has been deliberately blocked: a shareware-like trial model.

They said in the keynote that "free apps will always be free"... which sounds good on the surface, but eliminates one of the most popular software distribution models.

It would be great if users could download an app for free, try it for a while to evaluate (perhaps with feature restrictions or a time limit), then use in-app purchasing to buy the full edition.

Apple and developers would still get paid, but users would be able to better evaluate whether or not they want to purchase the product. With high quality products, that would lead to more overall sales — and people would vote with their dollars to encourage quality apps.

Without such a mechanism, the only way to let users try a product before buying is to release two editions, e.g. a free Lite edition and a paid Pro edition. While that has some merit in itself, it adds additional hassles for the users (e.g. transferring data between the two apps, since each app sandboxes its own data) and having to find the Pro edition, buy and download it, re-configure it, and probably delete the Lite edition.

With in-app purchasing available, there should be no technical barrier to allowing free trial apps that can be purchased after trying them out.

Developers, if you want this option, please tell Apple — file a bug report duplicating mine, rdar://problem/6699761 (this link only works for Apple employees).

App Store Reviews Now Distinguish Versions

TidBITS just published an article discussing how App Store Reviews Now Distinguish Versions. A recommended read.

I was quoted for this article. My full comment was:

I think that is a most welcome enhancement. Often, reviews mention deficiencies that are addressed in subsequent versions, but without a version number (and to a lesser extent, a date), potential customers have no real way of knowing if that comment is still relevant. For example, for my SmileDial Pro app, I had two reviews for version 1.0 saying it was a little slow to navigate, so I addressed that in version 1.1. Now, it is clear that those issues were with an older version.

(You can check out SmileDial via its product page.)

Mac Bundle Box 4 ends soon!

Mac Bundle Box

The Mac Bundle Box promotion ends soon. Get in quickly to avoid disappointment!

The bundle includes several great applications for just $49.00! An amazing deal. Plus 5% of each sale will be donated to Charity: Water.

My own BlogAssist is also included as a free bonus. BlogAssist is a very handy app that I use daily when writing blog posts and forum replies. It very easily adds HTML markup around text on the clipboard, or highlighted text in an app.

Visit the Mac Bundle Box site today to take advantage of this great deal, while it lasts!

Cool augmented reality

"Augmented reality" is a technique where a 3D model appears on-screen connected to something you're holding in reality. GE has a nifty example, where one of two models appear to pop out of a piece of paper you hold. You can move the page around to move the model.

You can try it yourself if your computer has a webcam. You may need to upgrade the Flash plugin.

Mac Bundle Box 4 now available!

Mac Bundle Box

The fourth Mac Bundle Box, a collection of 13 great applications, is now available!

$333.82 worth of software for the low price of just $49.00! An amazing deal. Plus 5% of each sale will be donated to Charity: Water.

The bundle includes my own BlogAssist as a free bonus. BlogAssist is a very handy app that I use daily when writing blog posts and forum replies. It very easily adds HTML markup around text on the clipboard, or highlighted text in an app.

Visit the Mac Bundle Box site to take advantage of this great deal, while it lasts!

SmileDial Pro special price ending soon

When I released the version 1.1 update to SmileDial Pro, my fun iPhone app to call or text your favorite people, I also reduced the price from $3.99 to $1.99.

This was a temporary experiment, to see what would happen — would the reduced price be offset by increased sales volume? That has not eventuated; sales stayed about the same. So next week I'll be raising the price back to $3.99.

There has been much discussion on the intertubes recently about iPhone app pricing. It's recognized by most that $0.99 "ringtone apps" is not a sustainable pricing level for long-term success. While a few developers can make large amounts of money at such price points (mainly for really popular games), for most developers it simply doesn't work.

I am determined to continue supporting and improving my apps, so have to price them accordingly. If an app is too cheap, it doesn't justify the time it takes to improve it. So I can't support $0.99 or $1.99 prices, other than for quick "one day event" apps like Valentines.

Anyway, I thought I'd give notice of the price increase, so if you are considering buying SmileDial Pro, you can still get it at the special discounted price for another few days. Don't delay too long, though!

To learn more about SmileDial Pro, including seeing a video of its features, check out the SmileDial website!

Simon 2.5.1 released

Thanks to a post in the Simon forum this morning, I've traced and fixed a bug in the new SMS notifier plug-in. Plus a couple of other tweaks:

  • Fixed a bug that could sometimes prevent the new SMS notifier plug-in from loading.
  • Minor tweak to the SMS plug-in UI layout.
  • Removed the Spanish localization, since it hasn't been updated (if anyone wants to take over maintaining it, let us know).

Sorry for a bug-fix update in the same week as the general release... I wish we'd caught this during the beta cycle. But I felt it was an important enough issue to get a fix out immediately.

Download Simon 2.5.1 now!

Simon 2.5 released

Announcing the release of Dejal Simon version 2.5. Simon is my flagship Mac app, a very flexible server monitoring tool.

This update includes lots of great improvements. Some of the highlights include:

  • New SMS notifier plug-in, to send text messages via Clickatell or e-mail.
  • New Web notifier plug-in (like the Web service) to post to a web-based script.
  • Added S.M.A.R.T. Status, Drive Status, and Pulse services.
  • Added a Post to Simon Wall notifier.
  • Several enhancements to the reports features.
  • Added a Convert Domain/IP command to change a domain name into the corresponding IP address, or vice versa.
  • Plus many more improvements and fixes; see the release notes for details.

This is a free update for licensed Simon 2 customers.

Download Simon 2.5 now!

Secret screenshot tips

I take a lot of screenshots while documenting my products. I used to use Ambrosia's Snapz Pro, but it started misbehaving (losing its hotkey), so I stopped. Nowadays, I find Apple's built-in screenshot tools quite adequate.

Firstly, of course, is the Grab application, located in your /Applications/Utilities folder. I only tend to use that when I need a timed screenshot, e.g. to record partway through an animation. It is quite useful for that, though: you activate the timed screenshot function, wait for the timer to run out, and it takes a shot of the whole screen in whatever state it is then. It can take a few attempts to get the precise animation frame I want, but it allows taking a shot while clicking and dragging, something the built-in screenshots can't. That was admittedly one of the strengths of Snapz Pro, too.

Built into the OS is the whole-screen screenshot hotkey, Shift-Cmd-3. This will save a PNG image of the whole screen (or multiple pictures if you have multiple screens) to the Desktop. (You can change the file format via a utility like Secrets if you wish. You can also change the hotkey via the Keyboard & Mouse system preferences.)

Perhaps slightly less well known is Control-Shift-Cmd-3, which saves the screenshot onto the Clipboard. Very handy for pasting into emails and such.

The one I find most useful is Shift-Cmd-4, though. This displays crosshairs with a coordinate display, and when you click-and-drag out a selection, the coordinates change to the selection size. Very handy. This saves the selected area to a PNG file.

Similarly, Control-Shift-Cmd-4 saves a selected region to the Clipboard.

These selection screenshot options are even more flexible than that, though. After invoking them, but before dragging a selection, you can press the Spacebar to highlight the window under the crosshairs. Clicking will then take a shot of that window, including the border.

While dragging a selection, there are more options. You can hold the Shift (Shift) key to constrain one axis — to keep the height the same while adjusting the width, or vice versa.

You can also hold the Option (Option) key to adjust the size around the center point, instead of from the point where you started dragging.

And you can hold the Spacebar in selection mode to reposition the whole selection, keeping the size the same. Very handy.

Finally, you can cancel the screenshot simply by pressing Escape. This can be useful on occasions other than just changing your mind: you can use the screenshot tool as a ruler, measuring the number of pixels of an object by dragging out a selection and reading the size display from the crosshairs, then hit Escape to exit without taking a shot.

Very useful. If anyone knows of any other tricks with the screenshot tools, please let me know!

History of the internet

A fascinating animated video on the history of the internet:

History of the Internet from PICOL on Vimeo.

Introducing Valentines for iPhone

Introducing Valentines, a fun app to help celebrate Valentine's Day. It is now available on the iPhone App Store!

Valentines enables you to create any number of fun Valentine messages with your own text and a photo within a heart-shaped frame. The photo will have a slightly pink tint — see the world through rose-colored glasses. :) You and your valentine can view it on your iPhone or iPod touch, or you can save it to your photo library:

Flipping over, you can edit the message and choose an existing photo from your library or take one with the iPhone's camera:

You can also display a list of all valentines, and add new ones, rearrange their order, or delete them:

Valentines is available on the App Store for just $0.99. A limited number of promo codes are available for reviewers; if you are a journalist or blogger and want to write a review of Valentines, contact me for a code.

Imagining the ten dimensions

Fascinating, in a mind-bending kinda way:

Watch Imagining the ten dimensions in How to Videos  |  View More Free Videos Online at

SmileDial 1.1 released

My first iPhone applications, SmileDial Lite and SmileDial Pro, have been updated to version 1.1.

Note: currently as of this writing, SmileDial Lite 1.1 hasn't yet appeared on the App Store, but I expect it soon. SmileDial Pro 1.1 is available.

Version 1.1 adds some new features, along with performance improvements:

  • Added a Settings option to Display Person's Name: if on, the person's name appears at the bottom of their photo. It is on by default.
  • Added a Settings option to Convert Numbers: if on, a number like "1 (800) MY-APPLE" will be converted to the numeric equivalent, "1 (800) 692-7753". This is off by default.
  • If a number from a Contact contains letters (e.g. "1 (800) MY-APPLE"), and isn't converted via the above setting, it is not auto-formatted, to avoid stripping off the letters.
  • Scrolling between multiple people (in the Pro edition) is now faster.
  • Flipping to and from the Edit Person view is now faster.

Check out the SmileDial website for more information, including a movie demoing the main features (though it hasn't been updated for version 1.1 yet). You can see some of the new features in the screenshots. You can also find links to the App Store on those pages.

Sneak peek: Valentines for iPhone

I've just submitted my second iPhone app to the App Store... well, really my third, since SmileDial Lite and SmileDial Pro are separate apps.

Introducing Valentines, a fun app to help celebrate Valentine's Day. It is currently in review by Apple, but hopefully will be available on the App Store before Valentine's Day itself!

You can get a sneak peek of this new app on the Valentines website. It enables you to create one or more Valentine messages with custom text and a photo within a heart-shaped frame. You can tap a camera button to save the result to your photo library, or just show them to your valentine on your iPhone:

Flipping over, you can edit the message and choose an existing photo from your library or take one with the iPhone's camera:

Valentines will be available on the App Store for just $0.99. Since it's so simple and cheap, there's only one edition; no need for a free Lite edition to evaluate.

Speaking of SmileDial, I recently also submitted version 1.1 of both editions, which includes some much-requested improvements. They should also be available shortly.

Introducing FinderFront


Adam C. Engst, publisher of the excellent TidBITS newsletter ("Mac news for the rest of us"), called out to the Twitterverse for help with a pet vexation. He wanted to be able to simply click on the Desktop and have all Finder windows come in front of all other windows. Normally when you click the Desktop, the Finder is activated but its windows may be obscured behind those of other applications.

And thus FinderFront was created. It is a simple — and completely free — tool to bring all Finder windows to the front when you click anywhere on the Desktop. If the Finder is already active, it does nothing, to avoid blocking selection of any icons on the Desktop.

It doesn't show any windows or menus when launched, and doesn't appear in the Dock, so it'll be practically invisible. If you find it useful and want it to keep working after you restart your Mac, add it to your Login Items in the Accounts pane of your System Preferences.

Download FinderFront now! It's free!

Simon 2.5b2 released

Simon version 2.5b2 has now been released:

  • Added a Drive Status service. A script service to check drive capacity threshold, S.M.A.R.T. status, and RAID health. A more comprehensive check than the S.M.A.R.T. Status service. Results in a failure if a problem is detected. Kindly written by Scott Haneda.
  • Added Automatically add www. and .com if omitted checkbox to the Web plug-in's Service options. It is on by default, but you can turn it off to disable this automatic formatting if you need to enter a URL without a top-level domain, e.g. for WebDav.
  • Fixed a bug in the previous beta where a URL was incorrectly required in the New/Edit Service window for the Web plug-in.
  • Fixed a bug with loading new default services and notifiers, where they could vanish after relaunching if no changes were made manually after updating. If you deleted any of these, they may re-appear with this update; just delete them again, and they won't re-appear.

Download Simon now!

Happy birthday, Mac!

Saturday is the 25th anniversary of the introduction of the first Macintosh.

I first used a Mac back in high school in New Zealand, where I volunteered as head student librarian. The school had mostly Apple IIe computers, but bought one of the newfangled Macintosh computers in 1984. It was an original 128K Mac, with a single internal floppy drive. Back then, the OS, an application, and data fit on a single 400K disk. We used MacWrite for letters and other documents, MacPaint for occasional graphics, and the OverVUE database for some records... though not a full book catalog.

I bought my first Mac four years later while at university, in 1988. It was a Macintosh Plus, one of the new platinum-colored models. And I even had a second 800K floppy drive and a dot-matrix printer! Later, I added an external hard drive (I think it was 10 MB, though I could be wrong).

Those were the days... working on a 9-inch 512 x 342 pixel monochrome display... which is actually not much more than the iPhone screen resolution, to give some perspective.

Later I bought a Macintosh II, which I subsequently upgraded internally to be a Macintosh IIx. Then I used a number of other models provided by a Dejal client.

When my wife and I got married, Apple gave us a PowerBook 150 as a wedding present, since we had met while using Macs with the fledgling internet. Our wedding was covered on local TV news and newspapers. Yep, meeting over the internet was a novel concept back then.

Just before we moved to the US, we bought a clamshell iBook G3, which we still have, though I only use it for Mac OS X 10.3.9 compatibility testing. Then an iMac G4, which sadly seems to have passed away, a PowerMac G5 that I still use for Mac OS X 10.4 testing and as a music server, and lastly my current machine, a 17" MacBook Pro.

(We've also had a few other Macs: a Mac mini we use with our TV, a MacBook I bought to take to WWDC before I got my MacBook Pro, then subsequently gave to my wife's mom, and my wife has had a couple of 15" MacBook Pros.)

All in all, it's been a great 25 years. I've enjoyed using and owning the various Macs over this time, and look forward to many more years. Happy birthday, Mac!

Simon 2.5b1 released

Simon, my flagship product to monitor websites and servers for changes and failures, has been updated to version 2.5b1, the first beta release of a feature update.

This update includes several great improvements:

Services and Notifiers:

  • Added a SMS notifier plug-in to send Simon notifications as text messages to your phone. It has two modes of operation: via the Clickatell SMS gateway service, or via email to your phone provider. For both methods, this plug-in enables you to easily add multiple phone numbers to send messages to, and you can pick them from your Address Book if desired. Clickatell is a paid service; you need to sign up for an account with them, and they charge for each message. The email mode is free, other than any charges you may incur for receiving text messages. This plug-in was kindly written by Daniel Ellis.
  • Renamed the Basic plug-in as Web, and extended it to also act as a notifier. So you can now use it to get or post to a web page when a change, failure or recovery occurs, e.g. to run a PHP script to log a failure or perform some other action.
  • Added a S.M.A.R.T. Status service. This script checks the S.M.A.R.T. status of all mounted disk volumes, ignoring volumes that don't support reporting S.M.A.R.T. status. Results in a failure if a problem is detected.
  • Added a Pulse service. This script simply causes every check to result in a change. This can be useful, for example, to have Simon email you (via a change notifier) at a desired frequency, to reassure you that Simon is on the job.
  • Added a Post to Simon Wall notifier. This is a demo of the Web plug-in operating as a notifier. It does a Post to the Dejal website, adding a line to the Simon Wall page. You are welcome to use this notifier if you wish, or can duplicate and modify it to post elsewhere.
  • The E-mail notifier now alerts you if the To or From fields aren't filled in, since that is a common cause of issues.
  • Changed the E-mail notifier plug-in when using the Automatic method to connect to the sender's SMTP server instead of the recipient's, since that is more correct.
  • Fixed a bug in the Web plug-in's handling of the parameters and cookies tables, where an exception could prevent adding new ones when editing existing tests.


  • Changed the URL display in the Save Locally report plug-in to be an editable URL, like in the Upload to Remote Server one. This enables you to edit the URL if you have a domain name for your local machine, or want to use a different variation of a file:// URL, perhaps to use localhost instead of the machine name. Clear the field to go back to an automatically determined URL.
  • Changed the Save Locally report plug-in to replace any periods in the machine name with a dash, to avoid an invalid URL.
  • Added LastChangeTextWithHTML and LastChangeTextWithoutHTML report variables for the Test block, so you can display the full text of the test output (between the Start and End Smart Change Detection blocks, if any).
  • When a report is deleted, it now immediately stops outputting and removes its timer to avoid reporting again, as you'd expect.


  • Added a Convert Domain/IP command to the Edit menu. If a field with a domain name or IP address is active, this command will change the domain name into the corresponding IP address, or vice versa. If there are multiple possible matches, a menu is displayed to enable you to choose the best one. Note that converting a domain to an IP then back to a domain may result in a different domain, if it is on a shared hosting server.
  • Changed the Add/Remove buttons below tables in the Preferences, Web (HTTP) and Script plug-ins to use small square buttons instead of round ones, to fit with the modern convention.
  • Fixed a rare issue where some plug-in settings could be unexpectedly modified when canceling an editor.
  • Fixed an issue with the Preferences window, where edits might not be saved when quitting with the window still open (specifically when an edit is still active).
  • Removed the old crash reporter, since it doesn't support Leopard crash logs.
  • Updated the built-in Kagi purchasing tool to the latest version, which fixes some issues with Leopard.

Download Simon 2.5b1 now!

Syndicate content