Apple Design Awards 2009 Winners
The winners of the Apple Design Awards 2009 have been announced. To my excitement, two applications whose UI, design, and functionality I love were among the winners: Things and Versions.
The winners of the Apple Design Awards 2009 have been announced. To my excitement, two applications whose UI, design, and functionality I love were among the winners: Things and Versions.
While browsing through the Tap Tap Tap blog, I found a great article on 10 useful iPhone tips & tricks. Many of the shortcuts I already knew about, but there were several new ones that I found quite useful!
We just passed 1234567890 seconds since 1 January 1970!

Just a quick note: WebKit has reached revision 40000!

If you pass parseInt a number with a zero in front of it, such as “020″, without specifying a radix, you may get funny results…
There may be times when you want to get the path to a user’s home directory in your Dashboard widget. If, like normal, the widget is located in the user’s local Widgets directory (~/Library/Widgets/), we could extract the path from window.location.href. However, this approach is pretty limited, because it requires the widget to be located somewhere in the user’s home directory. What if, for some reason, the user moves our widget into the main Widgets directory (/Library/Widgets/)? This is unlikely, but it is possible. Also, this approach won’t work when we run the widget in Dashcode, because Dashcode temporarily stores the widget in a system folder that isn’t located in the user’s home directory.
Luckily, there’s a solution…
If you’re working with images a lot in your dashboard widget, you may notice that Dashcode caches them between runs. This is not very kind of Dashcode because this doesn’t happen in Dashboard itself, and since our widget is destined for the Dashboard, we want to know how it will perform there.
I just noticed that Dashcode’s evaluator has a Terminal-like shortcut. By pressing the up-arrow key, you can insert a previous statement that you entered.
After a long wait, the first public beta of MacRabbit’s new application “Espresso” has been released! You can download it from the Espresso webpage. (I had to reload the page to see the download link, as Safari had the old version in its cache.)
I recently decided that since I didn’t currently have much on my home page (which resides at the root level of my site), it would be better to redirect users to the Console page until I had more to put on my home page. Here’s a mini-tutorial on how to redirect visitors from the root of your site to another page of your choice.
I recently wanted to use Mac OS X Personal Web Sharing on my computer (to test webpages on my iPod Touch across the local network). I hadn’t used Web Sharing for a long time, as I use MAMP for most of my local-web-server-testing needs these days. Unfortunately, getting Web Sharing running wasn’t to be just one-click away…
There are plenty of cases where you might want to check whether a remote file (a text document or an image) exists. We can do this using a HEAD XMLHttpRequest.
Set up your XMLHttpRequest like normal:
var request = new XMLHttpRequest();
request.onreadystatechange = function()
{
if (request.readyState == 4) {
if (request.status == 200) {
[Code to Execute if File Exists...]
}
else {
[Code to Execute if File Doesn't Exist...]
}
}
}
When you open it, however, replace “GET” with “HEAD” (url is the URL of your file):
request.open("HEAD", url, true);
Finally, send it like normal:
request.send("");
This is very good way to quickly determine if an image exists—it’s much faster than creating a new Image object, assigning it a src, then setting up onload and onerror handlers.
If you are going to need to test for files often, I’d recommend that you put the code into a function:
function testFile(url)
{
// Setup options
var options = arguments[1];
if (!options) { options = {}; }
// Create the request
var request = new XMLHttpRequest();
request.onreadystatechange = function()
{
if (request.readyState == 4) {
if (request.status == 200) {
// File Exists
if (options.onSuccess) { options.onSuccess(); }
}
else {
// File Doesn't Exist
if (options.onFailure) { options.onFailure(); }
}
}
}
request.open("HEAD", url, true);
request.send("");
}
Then you can call it like this:
testFile("http://quintusquill.com/anImage.jpg", {
onSuccess: function() {
alert("File Exists!");
},
onFailure: function() {
alert("File Doesn't Exist!");
}
});
Since we’ve set up the function to use “options” (see here for more on options), you don’t have to provide either the onSuccess or onFailure callbacks (however, you won’t get any answer if you don’t specify at least one of them).
A handy feature in Safari which you may not know about is Window > Merge All Windows. As the command name suggests, this command merges all the windows and tabs that are currently open in Safari into tabs in a single window.
I’ve finally released “Dazzle”, a “check for updates” JavaScript framework for Dashboard widgets. It was inspired by Andy Matuschak’s Sparkle framework for Cocoa applications.
Dazzle uses appcasts to determine if a new update is available, and if there is, displays an alert box to the user, telling them that a new version is available and giving them the option to download the update or dismiss the alert box. Dazzle currently uses Safari to download and install the update, and so, by default, opens the URL in Safari regardless of the user’s default browser (you can change this, however).
Dazzle also can display a link to the release notes for the widget in the alert box, although the link is hidden by default.
I’ve tried to make Dazzle customisable, so that you can tweak Dazzle’s behaviour without actually modifying the Dazzle code.
There are instructions on the Dazzle main page on how to get it working in your widget. There is also a “Guide” page to show you Dazzle’s features (and how to use them), and a “Reference” page, which lists all of Dazzle’s methods/options with a brief description of each.
Finally, here’s a screenshot of the demo widget included with Dazzle, “DazzleDemo”:

There are various times when you might want to know the version of the user’s operating system when performing some operation in your Dashboard Widget. While you can find it using AppleScript, there is a better way: the sw_vers Terminal command (which is located in /usr/bin/).
This is the output of the command on my computer at the time of writing:
ProductName: Mac OS X ProductVersion: 10.5.4 BuildVersion: 9E17
Obviously, we need to extract the “10.5.4″ part.
I have done this by firstly extracting the “ProductVersion: 10.5.4″ part using a regular expression, and then deleting the “ProductVersion: ” part.
The resulting code is as follows:
widget.system("/usr/bin/sw_vers", function() {
// Note that the "match" method returns an array.
// The matched string, which is what we want,
// is the first element in that array:
var versionString = this.outputString.match(/ProductVersion:\t.*/)[0];
// We delete the "ProductVersion: "
// part by replacing it with nothing:
var version = versionString.replace("ProductVersion: ", "");
});
Dashboard widgets have a certain width and height (often specified in your Info.plist file). If your widget content moves outside this region (such as it might during an animation), it will get clipped.
One way to solve this problem is to specify large width and height values in the Info.plist file. However, this results in a gigantic ripple effect (much bigger than the widget itself) when the widget is launched—a bad user experience.
Luckily, there is a much better way to do this, which doesn’t involve hacks or a bad user experience:
window.resizeTo(width, height);
In your Info.plist file, set the width and height keys to the initial width and height of the widget. Whenever the size of your widget changes, call window.resizeTo(width, height), passing in the new width and height values of your widget. Dashboard will then know the new dimensions of your widget and your content will not get clipped.
There is also a window.resizeBy(width, height) method, where the width and height values are added to the existing width and height values of the widget area.
Note that neither of these methods resize the content of your widget—you have to do this yourself.
Now for some examples:
// Initial Width of Widget = 300; Initial Height of Widget = 200; window.resizeTo(300, 300); // Result: Width of Widget = 300; Height of Widget = 300;
// Initial Width of Widget = 300; Initial Height of Widget = 200; window.resizeBy(300, 300); // Result: Width of Widget = 600; Height of Widget = 500;
Also, you can obtain the current width of the widget area using window.innerWidth, and the current height by using window.innerHeight:
// Width of Widget = 300; Height of Widget = 200; var w = window.innerWidth; alert(w); // Result: 300 var h = window.innerHeight; alert(h); // Result: 200
You can read more about resizing dashboard widgets here.
When you define an enclosure in an RSS feed, you have to specify a length attribute, which specifies the size in bytes of the file attached in the enclosure.
This is actually quite simple: the Finder’s “Get Info” window not only shows how many KB, MB, or GB the file takes up on disk, but also what this is in bytes (this info can be found in “General”).

Simply take out the commas, and there’s the enclosure’s length!
In WebKit, whenever a text field or a search field is selected (focused), a blue glow is drawn around its perimeter. In some cases, it may be desirable to remove this glow. This is actually quite simple: set theoutline CSS property to none.
outline: none;
The above code results in:
Notice that when you select the text field, no blue glow appears around its perimeter (you’ll have to be using WebKit to see it correctly).
Of course, there are very few cases when you would want to do this (or to be more precise, should do this), but its always nice to know its possible…
Namespaces were introduced in order to avoid conflicts with names of XML elements and attributes. For example, say you have a “table” element (thanks to W3Schools for this example). It could apply to either a piece of furniture or an HTML element used for displaying data. If, for some reason, these two pieces of code needed to be combined, there would be a conflict. To avoid these conflicts and to give these elements unique identifiers, we use namespaces.
Throughout this post, I shall use custom (namespaced) RSS elements/attributes from the Sparkle framework as examples.
A namespaced element looks like this:
<sparkle:releaseNotesURL></sparkle:releaseNotesURL> // "sparkle" is the namespace and "releaseNotesURL" is the element name
A namespaced attribute looks like this:
<enclosure sparkle:version="1.0" url="foo.zip" /> // "sparkle" is the namespace and "version" is the attribute name
A URL must also be associated with the namespace. This is usually specified on the root element using the xmlns attribute:
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle"> <!-- Declaring the "sparkle" namespace on the "rss" element --> </rss>
The xmlns URL doesn’t have to be a real URL, as it’s just an identifier for the namespace, but people often use it to reference a page describing/documenting the namespace.
When parsing XML, you may have to parse a namespaced element or attribute.
At first, you might try to extract the releaseNotesURL element like this (where response is the response XML from an XMLHttpRequest):
response.getElementsByTagName("sparkle:releaseNotesURL")[0];
However, this doesn’t work. You have to use getElementsByTagNameNS:
response.getElementsByTagNameNS("http://www.andymatuschak.org/xml-namespaces/sparkle", "releaseNotesURL")[0];
Note here that getElementsByTagNameNS takes two parameters: the namespace URL and the actual element name.
The same applies to attributes. To extract the version attribute from an enclosure element (assuming that the variable enclosure has already been declared):
enclosure.getAttributeNS("http://www.andymatuschak.org/xml-namespaces/sparkle", "version");
An interesting thing to note is that the latest version of Safari supports
enclosure.getAttribute("sparkle:version");
…but it doesn’t support
enclosure.getElementsByTagName("sparkle:releaseNotesURL");
So, for now, it’s safest to always use the namespace methods…
That’s it for now!
In this post, I will show you how to create functions with optional arguments, or parameters, in Javascript. For example, in our demo function doSomething, the user can specify an “onComplete” function to call when finished “doing something”, but doesn’t have to specify one if is not needed.
First, we declare our function:
function doSomething()
{
// Code to do something...
}
Note that we do not include the “onComplete” argument in the function declaration. If we did this, then the user would be required to supply a value for the “onComplete” argument (and if they didn’t, there would be an error).
Javascript has an “arguments” array for each function, containing (logically) all the arguments passed in by the user. We can use this to implement optional arguments, as long as we know the order of the optional arguments (in this case, we don’t have to worry, since there is only one optional argument):
if (arguments.length > 0) {
var onCompleteFunction = arguments[0];
}
Here, we check to see if the arguments array contains anything, and if there is, get the first item (which will be the “onComplete” function) and assign it to a variable named “onCompleteFunction”.
When we’ve finished “doing something”, we can see whether there is an onCompleteFunction variable, and if so, call the function contained by the variable:
if (onCompleteFunction) onCompleteFunction();
Note: Since the if statement only has one line of code, we can omit the opening and closing braces to make it as simple as possible.
And there it is! The final function should look similar this:
function doSomething()
{
if (arguments.length > 0) {
var onCompleteFunction = arguments[0];
}
// Code to do something…
if (onCompleteFunction)
onCompleteFunction();
}
The user can then call it like this:
doSomething();
…or like this:
doSomething(function() {
alert("Done!");
});
Either one of these is valid, and will not produce any errors.
If you add a new text view (NSTextView) to your Interface Builder project, it will have the following text:
Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum Et harumd und lookum like Greek to me, dereud facilis est er expedit distinct. Nam liber te conscient to factor tum poen legum odioque civiuda.
OK, just typical Lorem Ipsum text—what’s so special about that? Look at the second last line…
…Et harumd und lookum like Greek to me,
Looks like someone had a bit of fun there!
Just a quick note: I finally installed the latest version of Apple’s Developer Tools (officially called “Xcode 3.1 Developer Tools”), and one of the things that I noticed after the installation is that I can finally view CSS (Cascading Style Sheet) files in Quick Look.
A subtle, but welcome, addition!
Since I’m going to release my QQTimer class soon, I thought it would be an appropriate time to write a little tutorial on how to create a simple timer in JavaScript.
The idea is simple: we record the current time when the user starts the timer, record the current time when the user stops the timer, and then subtract the two to find out how much time has elapsed.
The trick is to get both numbers into a format on which we can perform standard mathematical calculations. The JavaScript method getTime() works well for this, as it returns the number of milliseconds since 1 January 1970.
First, we create our class “Timer”:
function Timer() {}
We’ll have have three instance variables:
startTime – This will store the time when we start the timerstopTime – This will store the time when we stop the timerstopped – This will store a boolean indicating whether the timer has been stopped or notHere’s what our completed object constructor function looks like:
function Timer()
{
this.startTime = 0;
this.stopTime = 0;
this.stopped = true;
}
Now we’ll add three methods:
start() – This will start the timerstop() – This will stop the timergetElapsedTime() – If the timer has been stopped, then this will get the elapsed time between when the timer was started and when it was stopped; if the timer hasn’t been stopped yet, it will get the elapsed time since the timer was startedclear() – This will reset all the valuesThe start method will simply set this.startTime to the value of the getTime() method:
Timer.prototype.start = function()
{
var currentDate = new Date();
this.startTime = currentDate.getTime();
}
The stop method is almost identical to the start method, except that this time we set this.stopTime to the value of the getTime() method:
Timer.prototype.stop = function()
{
var currentDate = new Date();
this.stopTime = currentDate.getTime();
}
The getElapsedTime method will check whether the timer has been stopped or not, then return either the start time subtracted from the stop time, or the start time subtracted from the current time (respectively):
Timer.prototype.getElapsedTime = function()
{
if (this.stopped) {
return (this.stopTime - this.startTime)
}
else {
var currentDate = new Date();
return (currentDate.getTime() - this.startTime)
}
}
Finally, the clear: method resets all our instance variables. It is exactly the same code as in the initialisation function:
Timer.prototype.clear = function()
{
this.startTime = 0;
this.stopTime = 0;
this.stopped = true;
}
And that’s it. You’ve now created a simple timer class using JavaScript!
Have you ever wanted to make your application not appear in the dock and not display its own main menu bar?
For example, say you have an application which is to be accessed as a menu icon in the Status Bar (where you have the icons, or sometimes, text, for Airport, Volume, Date/Time, Spotlight etc.). This application only wants to be visible in the status bar – it doesn’t want to have its own main menu bar or appear in the dock.
Simply go into the Info.plist file in your Xcode project and add the following:
LSUIElement 1
Save, Build, and Run. Your application should display any windows it is supposed to show at startup, but now it will not appear in the dock or have its own menu bar.
Website * quillWebsite = [[Website alloc] init];
or…
var quillWebsite = new Website();
Welcome to QuintusQuill!