<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ClintHarris.net</title>
	<atom:link href="http://www.clintharris.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.clintharris.net</link>
	<description>Thoughts and Tips From a Software Developer</description>
	<lastBuildDate>Sat, 07 Jan 2012 14:35:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>NodeJS 101: Use Buffer to Append Strings Instead of Concatenating Them</title>
		<link>http://www.clintharris.net/2011/nodejs-101-use-buffer-to-append-strings-instead-of-concatenating-them/</link>
		<comments>http://www.clintharris.net/2011/nodejs-101-use-buffer-to-append-strings-instead-of-concatenating-them/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 22:08:15 +0000</pubDate>
		<dc:creator>Clint</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[nodejs]]></category>

		<guid isPermaLink="false">http://www.clintharris.net/?p=878</guid>
		<description><![CDATA[Note: Your RSS reader or email client may block the JavaScript and CSS in this post. If the code samples below do not appear with syntax highlighting and line numbers, you may want to view this post in your browser.Update (1/7/12): According to Ben Noordhuis, one of the core Node.js contributors and author of the [...]]]></description>
			<content:encoded><![CDATA[<div style='background-color:#F3F3F3; border-color:#DDDDDD; border-style:solid; border-width:1px 0; font-size:0.8em; font-style:italic; margin-bottom:1.571em; padding:5px;}'><em><strong>Note:</strong> Your RSS reader or email client may block the JavaScript and CSS in this post. If the code samples below do not appear with syntax highlighting and line numbers, you may want to <a href='http://www.clintharris.net/2011/nodejs-101-use-buffer-to-append-strings-instead-of-concatenating-them/'>view this post in your browser</a>.</em></div><p><em><strong>Update (1/7/12)</strong>: <a href="https://github.com/bnoordhuis/node-buffertools/issues/18#issuecomment-3161866">According to Ben Noordhuis</a>, one of the core Node.js contributors and author of the buffertools module, you don&#8217;t really need to worry about using buffers when it comes to concatenating strings. Apparently V8 is extremely clever, so for example, a statement like a += b + c actually results in no copying whatsoever.</em></p>
<p>Andrew Maurer recently shared <a href="http://www.maurer.me/articles/nodejs-string-building-buffers-arrays-and-concatenation/2011112001/">some test results</a> showing how much more efficient it is to use <a href="http://nodejs.org/docs/v0.6.3/api/buffers.html">Buffers</a> when building strings in NodeJS. Although the value behind using buffers to concat strings was drilled into me over a decade ago while using Java, I&#8217;m embarrassed to admit it hadn&#8217;t occurred to me in my NodeJS work. I think it&#8217;s because, like most people, I picked up JavaScript a long time ago in the context of browser environment&#8211;a place where nobody really uses string buffers, and there aren&#8217;t any built-in mechanisms for doing so. With that in mind, I thought it was worth sharing this personal facepalm as reminder to others. It&#8217;s &#8220;101&#8243; stuff that every Node developer should know.</p>
<p>To make things easier, I recommend using a module called buffertools (<a href="https://github.com/bnoordhuis/node-buffertools">github</a> / <a href="http://search.npmjs.org/#/buffertools">npm</a>) which augments the out-of-box Buffers object and makes it super-easy to efficiently append strings (note that it was written by one of the core NodeJS deveopers). To borrow from the project&#8217;s own documentation, here&#8217;s an example:</p>
<pre class="javascript" name="code">require('buffertools');

// The next three lines are identical to doing "new Buffer('foobarbaz')"
a = new Buffer('foo');
b = new Buffer('bar');
c = a.concat(b, 'baz'); // non-standard function added by buffertools

console.log(a, b, c); // "foo bar foobarbaz"

// static variant
buffertools.concat('foo', new Buffer('bar'), 'baz');</pre>
<p>Note that buffertools won&#8217;t work out-of-box on Windows since it uses UNIX-only native code.</p>
<style type="text/css">@import url("http://www.clintharris.net/syntaxhighlighter/Styles/SyntaxHighlighter.css");</style><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shCore.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushCpp.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushJava.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushPhp.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushSql.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushXml.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushJScript.js"></script><script language="javascript">window.onload = function (){ dp.SyntaxHighlighter.HighlightAll("code"); }</script> ]]></content:encoded>
			<wfw:commentRss>http://www.clintharris.net/2011/nodejs-101-use-buffer-to-append-strings-instead-of-concatenating-them/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How To Use ExtJS 4 TreePanels with Both Static Data and Model Stores</title>
		<link>http://www.clintharris.net/2011/how-to-use-extjs-4-treepanels-with-both-static-data-and-model-stores/</link>
		<comments>http://www.clintharris.net/2011/how-to-use-extjs-4-treepanels-with-both-static-data-and-model-stores/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 11:29:59 +0000</pubDate>
		<dc:creator>Clint</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[Whitepapers/Notes]]></category>
		<category><![CDATA[extjs4]]></category>

		<guid isPermaLink="false">http://www.clintharris.net/?p=801</guid>
		<description><![CDATA[Note: Your RSS reader or email client may block the JavaScript and CSS in this post. If the code samples below do not appear with syntax highlighting and line numbers, you may want to view this post in your browser.I recently needed to build an &#8220;admin&#8221; screen for a webapp using ExtJS 4. The wireframe [...]]]></description>
			<content:encoded><![CDATA[<div style='background-color:#F3F3F3; border-color:#DDDDDD; border-style:solid; border-width:1px 0; font-size:0.8em; font-style:italic; margin-bottom:1.571em; padding:5px;}'><em><strong>Note:</strong> Your RSS reader or email client may block the JavaScript and CSS in this post. If the code samples below do not appear with syntax highlighting and line numbers, you may want to <a href='http://www.clintharris.net/2011/how-to-use-extjs-4-treepanels-with-both-static-data-and-model-stores/'>view this post in your browser</a>.</em></div><div class="wp-caption alignright" style="width: 250px"><img class="  " style="border-style: initial; border-color: initial; border-width: 0px;" title="Wireframe" src="http://img.skitch.com/20110924-33mi7ad45shdq5j3b6mhcsj9d.jpg" alt="" width="232" height="250" /><p class="wp-caption-text">Wireframe showing tree with both static and dynamically-loaded items</p></div>
<p>I recently needed to build an &#8220;admin&#8221; screen for a webapp using ExtJS 4. The wireframe called for a tree to navigate the various admin settings, including settings for individual users (something like what you see at right). To build a tree like this with ExtJS, you usually use the <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.tree.Panel">Ext.tree.Panel</a> class (a.k.a., a TreePanel). Unfortunately I couldn&#8217;t find any examples of how to make a TreePanel with a mixture of both static and dynamic nodes, so figuring it out took longer than it should have. With that in mind, I thought I&#8217;d share what I learned.<span id="more-801"></span></p>
<p>A working example of the solution I came up with is shown below (if the embedded version doesn&#8217;t appear for some reason, you can open it <a href="http://jsfiddle.net/clint_harris/QvaMG/" target="_blank">here</a>). Note that you can actually run the code in your browser and see the results&#8211;just click the play button. Or if you&#8217;d like to modify it, click the &#8220;+&#8221; button to copy the code into your own project on JSFiddle.</p>
<p><iframe style="width: 100%; height: 400px;" src="http://jsfiddle.net/clint_harris/QvaMG/embedded/" width="320" height="240">[Cannot display JSFiddle code example because your browser does not support iframes]</iframe></p>
<p>The first thing the code does is define a basic <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Model">model</a> class for user data, called UserModel:</p>
<pre class="javascript" name="code">Ext.define('demo.UserModel', {
    extend: 'Ext.data.Model',
    fields: ['id', 'name', 'profile_image_url']
});</pre>
<p>The next thing it does is set up a <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.TreeStore">TreeStore</a> to load the UserModel instances:</p>
<pre class="javascript" name="code">var userTreeStore = Ext.create('Ext.data.TreeStore', {

    model: 'demo.UserModel',

    proxy: {
        type: 'jsonp', // Because it's a cross-domain request

        url : 'https://api.twitter.com/1/lists/members.json?owner_screen_name=Sencha&amp;slug=sencha-team&amp;skip_status=true',

        reader: {
            type: 'json',
            root: 'users' // The returned JSON will have array
                          // of users under a "users" property
        },

        // Don't want proxy to include these params in request
        pageParam: undefined,
        startParam: undefined,
        pageParam: undefined,
        pageParam: undefined
    },
    ...
});</pre>
<p>Note that for this example we&#8217;ll be using Twitter as our data source for faux &#8220;users&#8221;; the UserModel fields are set up to match <a href="https://api.twitter.com/1/lists/members.json?owner_screen_name=Sencha&amp;slug=sencha-team&amp;skip_status=true">JSON from the Twitter API</a> (specifically, people who are a member of the &#8220;<a href="https://twitter.com/#!/Sencha/sencha-team/members">Sencha Team</a>&#8221; Twitter list) and we need to use a <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.proxy.JsonP">JSONP proxy</a> to make cross-domain requests (i.e., the demo is hosted at jsfiddle.net but it&#8217;s connecting to api.twitter.com). Here&#8217;s an easy-to-read sample of what the data looks like:</p>
<div class="wp-caption alignnone" style="width: 585px"><img title="Twitter data screenshot" src="http://img.skitch.com/20110924-qkh2t75sunmct4nxti7t2fsc4m.jpg" alt="" width="575" height="323" /><p class="wp-caption-text">The JSON user data we&#39;re getting from Twitter (edited for easier reading)</p></div>
<p>The next part requires a little more explanation. First, let&#8217;s look at the code:</p>
<pre class="javascript" name="code">var userTreeStore = Ext.create('Ext.data.TreeStore', {
    model: 'demo.UserModel',
    ...
    listeners: {

        // Each demo.UserModel instance will be automatically
        // decorated with methods/properties of Ext.data.NodeInterface
        // (i.e., a "node"). Whenever a UserModel node is appended
        // to the tree, this TreeStore will fire an "append" event.
        append: function( thisNode, newChildNode, index, eOpts ) {

            // If the node that's being appended isn't a root node, then we can
            // assume it's one of our UserModel instances that's been "dressed
            // up" as a node
            if( !newChildNode.isRoot() ) {

                // The node is a UserModel instance with NodeInterface
                // properties and methods added. We want to customize those
                // node properties  to control how it appears in the TreePanel.

                // A user "item" shouldn't be expandable in the tree
                newChildNode.set('leaf', true);

                // Use the model's "name" value as the text for each tree item
                newChildNode.set('text', newChildNode.get('name'));

                // Use the model's profile url as the icon for each tree item
                newChildNode.set('icon', newChildNode.get('profile_image_url'));
                newChildNode.set('cls', 'demo-userNode');
                newChildNode.set('iconCls', 'demo-userNodeIcon');
            }
        }
    }
});

userTreeStore.setRootNode({
    text: 'Users',
    leaf: false,
    expanded: false // If this were true, the store would load itself
                    // immediately; we do NOT want that to happen
});</pre>
<p>This doesn&#8217;t look like a &#8220;normal&#8221; <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Store">Ext.data.Store</a>. For one thing, it has an &#8220;append&#8221; event handler that receives &#8220;nodes&#8221;&#8211;objects that have methods and properties from the <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.NodeInterface">Ext.data.NodeInterface</a> class. Secondly, the store has a <code>setRootNode()</code> method that we&#8217;re calling with a config object for NodeInterface. What&#8217;s going on?</p>
<p>The important thing to understand here is that a TreeStore manages <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.Model">Ext.data.Model</a> instances&#8211;just like any other Store&#8211;but it copies NodeInterface methods/properties into every model so that they can be linked together into a hierarchy (i.e., a tree). In this case, every instance of <code>demo.UserModel</code> now has NodeInterface properties like &#8220;leaf&#8221; and &#8220;text&#8221; (which indicate if the item should be expandable when it&#8217;s displayed in a TreePanel, and what text should be shown).</p>
<p>Next, understand that when we call <code>setRootNode({...})</code>, the TreeStore implicitly creates a generic Ext.data.Model instance for us, adds the NodeInterface method/properties, and then makes it the root node; when the UserModels are loaded, they will be added as &#8220;children&#8221; to this node. What we end up with is a TreeStore with models organized into a hierarchy, each one having properties that a TreePanel can use for displaying it:</p>
<div class="wp-caption alignnone" style="width: 584px"><img alt="" src="http://img.skitch.com/20110926-ccut9t5b83qhy54q51xmbagf7r.gif" title="The Node Tree" width="574" height="340" /><p class="wp-caption-text">The &quot;userTreeStore&quot; builds a data structure like this</p></div>
<p>The next thing the code does is create a separate TreeStore with some &#8220;static&#8221; nodes (again, using NodeInterface config properties).</p>
<pre class="javascript" name="code">var settingsTreeStore = Ext.create('Ext.data.TreeStore', {
    root: {
        expanded: true,
        children: [
            {
                text: 'Settings',
                leaf: false,
                expanded: true,
                children: [
                    {
                        text: 'System Settings',
                        leaf: true
                    },
                    {
                        text: 'Appearance',
                        leaf: true
                    }
                ]
            }
        ]
    }
});</pre>
<p>Finally, we get the root of our userTreeStore and append it as a child to the &#8220;static&#8221; TreeStore. Then it&#8217;s just a matter of creating the TreePanel.</p>
<pre class="javascript" name="code">// Graft our userTreeStore into the settingsTreeStore. Note that the call
// to .expand() is what triggers the userTreeStore to load its data.
settingsTreeStore.getRootNode().appendChild(userTreeStore.getRootNode()).expand();

Ext.create('Ext.tree.Panel', {
    id: 'usersTreePanel',
    title: 'Admin Control Panel',
    renderTo: Ext.getBody(),
    height: 300,
    width: 300,
    store: settingsTreeStore,
    rootVisible: false
});</pre>
<p>In other words, you can &#8220;graft&#8221; TreeStores onto other TreeStores&#8211;this is the key to creating tree panels with a mixture of different data sources and underlying Models. The prerequisite, however, is understanding the NodeInterface. Hopefully this post will help others learn how to get started with TreePanels and TreeStores more quickly.</p>
<style type="text/css">@import url("http://www.clintharris.net/syntaxhighlighter/Styles/SyntaxHighlighter.css");</style><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shCore.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushCpp.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushJava.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushPhp.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushSql.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushXml.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushJScript.js"></script><script language="javascript">window.onload = function (){ dp.SyntaxHighlighter.HighlightAll("code"); }</script> ]]></content:encoded>
			<wfw:commentRss>http://www.clintharris.net/2011/how-to-use-extjs-4-treepanels-with-both-static-data-and-model-stores/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>ExtJS and External Template Files</title>
		<link>http://www.clintharris.net/2011/extjs-and-external-template-files/</link>
		<comments>http://www.clintharris.net/2011/extjs-and-external-template-files/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 20:32:08 +0000</pubDate>
		<dc:creator>Clint</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[extjs4]]></category>

		<guid isPermaLink="false">http://www.clintharris.net/?p=785</guid>
		<description><![CDATA[Note: Your RSS reader or email client may block the JavaScript and CSS in this post. If the code samples below do not appear with syntax highlighting and line numbers, you may want to view this post in your browser.ExtJS makes it easy to apply a template to a bunch of data (resulting in HTML [...]]]></description>
			<content:encoded><![CDATA[<div style='background-color:#F3F3F3; border-color:#DDDDDD; border-style:solid; border-width:1px 0; font-size:0.8em; font-style:italic; margin-bottom:1.571em; padding:5px;}'><em><strong>Note:</strong> Your RSS reader or email client may block the JavaScript and CSS in this post. If the code samples below do not appear with syntax highlighting and line numbers, you may want to <a href='http://www.clintharris.net/2011/extjs-and-external-template-files/'>view this post in your browser</a>.</em></div><p>ExtJS makes it easy to apply a <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.XTemplate">template</a> to a bunch of data (resulting in HTML output, for example). Most of the examples you&#8217;ll see show this being done with the template hard-coded as a JavaScript string. That&#8217;s fine, but what if you&#8217;d rather have your template in its own file? I recently had to do this and thought I&#8217;d share the code in case it&#8217;s helpful to anyone else.</p>
<p>First, here&#8217;s the usual example of a template hard-coded as a JavaScript string (click on the &#8220;Result&#8221; tab to run the code&#8211;it may take a few seconds for the output to appear):</p>
<p><iframe style="width: 100%; height: 250px" src="http://jsfiddle.net/clint_harris/GBWXM/embedded/">[Cannot display JSFiddle code example because your browser does not support iframes]</iframe></p>
<p>In this case, the template is pretty small, so having it in the JavaScript isn&#8217;t too annoying. But for the sake of demonstration let&#8217;s pretend that putting in its own file makes it much easier to read/maintain. In this case, I&#8217;ve moved it to a GitHub Gist, which you can see <a href="https://gist.github.com/1235852">here</a>. To use it, we&#8217;ll modify our ExtJS code as follows:</p>
<p><iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/clint_harris/TqeQV/embedded/"></iframe></p>
<p>How does this work? Every ExtJS component has the ability to remotely load and display HTML via the &#8220;loader&#8221; property, which you use to configure a <a href="http://docs.sencha.com/ext-js/4-0/#!/api/Ext.ComponentLoader">Ext.ComponentLoader</a>. The ComponentLoader lets you specify your own &#8220;renderer&#8221;&#8211;a function that handles the server response. What we&#8217;ve done is create our own &#8220;renderer&#8221; function that converts the server response&#8211;our template file&#8211;into an XTemplate. By making it a static function in our utility class, we can easily re-use it throughout the app.</p>
<p>This solution won&#8217;t make sense in every scenario, but if you&#8217;d prefer to keep your template in its own file and don&#8217;t mind the extra network traffic it&#8217;s a nice alternative to coding your templates as JavaScript strings.</p>
<style type="text/css">@import url("http://www.clintharris.net/syntaxhighlighter/Styles/SyntaxHighlighter.css");</style><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shCore.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushCpp.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushJava.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushPhp.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushSql.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushXml.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushJScript.js"></script><script language="javascript">window.onload = function (){ dp.SyntaxHighlighter.HighlightAll("code"); }</script> ]]></content:encoded>
			<wfw:commentRss>http://www.clintharris.net/2011/extjs-and-external-template-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My Wireframing Tool of Choice: Balsamiq Mockups</title>
		<link>http://www.clintharris.net/2011/my-wireframing-tool-of-choice-balsamiq-mockups/</link>
		<comments>http://www.clintharris.net/2011/my-wireframing-tool-of-choice-balsamiq-mockups/#comments</comments>
		<pubDate>Sun, 31 Jul 2011 18:00:31 +0000</pubDate>
		<dc:creator>Clint</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[wireframes]]></category>

		<guid isPermaLink="false">http://www.clintharris.net/?p=642</guid>
		<description><![CDATA[I&#8217;ve been using Balsamiq Mockups to make wireframes for my current project and it&#8217;s been great. There are a lot of tools for doing this kind of thing, and I&#8217;ve tried several of them (OmniGraffle, Visio, plain old Illustrator, etc.). It&#8217;s not perfect, but I&#8217;ve had a better experience with Mockups than anything else I&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignnone" style="width: 430px"><img title="Mockups Example" src="https://img.skitch.com/20110731-ejuqj7fap4wtdq7c9cuepjctyt.png" alt="" width="420" height="314" /><p class="wp-caption-text">An example of a wireframe made with Balsamiq Mockups</p></div>
<p>I&#8217;ve been using <a href="http://balsamiq.com/products/mockups">Balsamiq Mockups</a> to make wireframes for my current project and it&#8217;s been great. There are a lot of tools for doing this kind of thing, and I&#8217;ve tried several of them (OmniGraffle, Visio, plain old Illustrator, etc.). It&#8217;s not perfect, but I&#8217;ve had a better experience with Mockups than anything else I&#8217;ve tried so far. Some perks:</p>
<ul>
<li>at USD$80, it&#8217;s pretty affordable.</li>
<li>all the drawings have a deliberately &#8220;lo-fi&#8221; look. this helps keep you (and your client) focused on wireframing the ideas and not getting bogged down in nitty-gritty design stuff</li>
<li>the library of pre-built widgets is fantastic and pretty easy to configure. there&#8217;s also a website where you can download additional widgets that people have made.</li>
<li>the quick-search bar is fantastic for adding widgets quickly; hit the &#8220;/&#8221; key, type a few letters to select a widget, hit enter, and ZAP! the widget you want is added. much faster than using a mouse to find the widget you want and drag it on screen.</li>
<li>you can insert drawings from other files into your current mockup; changes to those drawings will show up in your mockup, too.</li>
<li>if you need to &#8220;override&#8221; a drawing that you&#8217;ve linked to, no problem. you can make one-off changes to that symbol without affecting the original.</li>
<li>you can make a collection of your own widgets that show up in a library for your current project, or across all projects.</li>
</ul>
<p>Those last three points are huge. For example, I&#8217;ve downloaded a few standard widgets that I want available all the time (Mockups calls these &#8220;Account Assets&#8221;). But I also have the ability to see a library of widgets just for one client or project (Mockups calls these &#8220;Project Assets&#8221;). I can re-use any of those widgets and if I change the original file those changes are reflected everywhere else&#8211;this is a boon to anyone who has copy-pasted widgets around only to find themselves re-copy-pasting changes to that widget later. Lastly, if you reuse a widget somewhere but need to tweak it a bit for that one usage, you can do so without affecting the original. Awesome.</p>
<p>There is a small learning curve when it comes to figuring out how to work with groups, assets, and editing an original widget that you&#8217;ve linked to vs overriding it, but after a couple of hours of poking around and watching some of the video tutorials you&#8217;re pretty much ready to go. Also, it runs on Adobe Air which might explain while it&#8217;s a little less-than-snappy with some operations like switching between files. But on the upside, you can run it on almost every platform. And although there may be times when you crave a more traditional &#8220;drawing&#8221; app if you need to mock up a really complicated/custom widget, you can usually find a way to get the job done in Mockups.</p>
<p>In summary, it&#8217;s not perfect but it&#8217;s probably the best wireframing tool I&#8217;ve used so far.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.clintharris.net/2011/my-wireframing-tool-of-choice-balsamiq-mockups/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ExtJS 4: Configuring the Class Loader for Multiple Namespace Directories</title>
		<link>http://www.clintharris.net/2011/extjs-4-configuring-the-class-loader-for-multiple-namespace-directories/</link>
		<comments>http://www.clintharris.net/2011/extjs-4-configuring-the-class-loader-for-multiple-namespace-directories/#comments</comments>
		<pubDate>Thu, 07 Jul 2011 20:54:15 +0000</pubDate>
		<dc:creator>Clint</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[extjs4]]></category>

		<guid isPermaLink="false">http://www.clintharris.net/?p=608</guid>
		<description><![CDATA[Note: Your RSS reader or email client may block the JavaScript and CSS in this post. If the code samples below do not appear with syntax highlighting and line numbers, you may want to view this post in your browser.I&#8217;m loving the new &#8220;class loader&#8221; mechanism that comes with ExtJS 4. That said, you&#8217;ve got [...]]]></description>
			<content:encoded><![CDATA[<div style='background-color:#F3F3F3; border-color:#DDDDDD; border-style:solid; border-width:1px 0; font-size:0.8em; font-style:italic; margin-bottom:1.571em; padding:5px;}'><em><strong>Note:</strong> Your RSS reader or email client may block the JavaScript and CSS in this post. If the code samples below do not appear with syntax highlighting and line numbers, you may want to <a href='http://www.clintharris.net/2011/extjs-4-configuring-the-class-loader-for-multiple-namespace-directories/'>view this post in your browser</a>.</em></div><p>I&#8217;m loving the new &#8220;class loader&#8221; mechanism that comes with ExtJS 4. That said, you&#8217;ve got to do a little extra configuration work if you have namespaces in difference directories&#8211;thought I&#8217;d share a quick example in case it&#8217;s helpful to anyone else. In this scenario, the ExtJS libraries are in one directory, the &#8216;myapp&#8217; classes are in another, and &#8216;myapp.common&#8217; (e.g., a shared library) classes live in yet a third directory.</p>
<pre class="xml" name="code">
<link rel="stylesheet" type="text/css" href="/extjs/4.0.1/resources/css/ext-all.css" />
<script type="text/javascript" src="/extjs/4.0.1/ext-all.js"></script>
<script type="text/javascript">
// Configure ExtJS class loader where to look for classes defined in the Ext and myapp namespaces
Ext.Loader.setConfig({
    enabled : true,
    disableCaching : true,
    paths : {
        'Ext'  : '/extjs/4.0.1/src',
        'myapp' : 'myapp/app',
        'myapp.common' : 'myapp/shared/js/common'
    }
});
</script>
<script type="text/javascript" src="/myapp/app.js"></script></pre>
<style type="text/css">@import url("http://www.clintharris.net/syntaxhighlighter/Styles/SyntaxHighlighter.css");</style><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shCore.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushCpp.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushJava.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushPhp.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushSql.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushXml.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushJScript.js"></script><script language="javascript">window.onload = function (){ dp.SyntaxHighlighter.HighlightAll("code"); }</script> ]]></content:encoded>
			<wfw:commentRss>http://www.clintharris.net/2011/extjs-4-configuring-the-class-loader-for-multiple-namespace-directories/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using wro4j to Easily Switch Between Minified and Debuggable JavaScript/CSS</title>
		<link>http://www.clintharris.net/2011/using-wro4j-to-easily-switch-between-minified-and-debuggable-javascriptcss/</link>
		<comments>http://www.clintharris.net/2011/using-wro4j-to-easily-switch-between-minified-and-debuggable-javascriptcss/#comments</comments>
		<pubDate>Tue, 31 May 2011 23:14:27 +0000</pubDate>
		<dc:creator>Clint</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://www.clintharris.net/?p=567</guid>
		<description><![CDATA[Note: Your RSS reader or email client may block the JavaScript and CSS in this post. If the code samples below do not appear with syntax highlighting and line numbers, you may want to view this post in your browser.I recently did some work on a large web application that had several .js and .css [...]]]></description>
			<content:encoded><![CDATA[<div style='background-color:#F3F3F3; border-color:#DDDDDD; border-style:solid; border-width:1px 0; font-size:0.8em; font-style:italic; margin-bottom:1.571em; padding:5px;}'><em><strong>Note:</strong> Your RSS reader or email client may block the JavaScript and CSS in this post. If the code samples below do not appear with syntax highlighting and line numbers, you may want to <a href='http://www.clintharris.net/2011/using-wro4j-to-easily-switch-between-minified-and-debuggable-javascriptcss/'>view this post in your browser</a>.</em></div><p>I recently did some work on a large web application that had several .js and .css files. Per industry best practice, I wanted to use something like YUI Compressor or Google Closure Compiler to merge and minify all the JavaScript and CSS into a single .js file and a single .css file. Also, I wanted an easy way to switch from these optimized files&#8211;which are hard to read&#8211;to the original files during development (or to debug an issue in production).</p>
<p>In this case, the JS/CSS needed to be minified at build-time. The project was built via Maven, so it made sense to do this with a Maven project. After a lot of research, I chose a plugin called <a href="http://code.google.com/p/wro4j/">wro4j</a> because it allows you to use an external XML file to configure exactly which files should be minified/optimized. And by making this XML file part of the website itself, you can use the information it contains (i.e., the list of individuals .js and .css files) to dynamically switch from the compressed files to the &#8220;raw&#8221; ones. The main benefit? The list of .js and .css files exists in only one place&#8211;the XML config file. Here&#8217;s what it looks like: </p>
<pre class="xml" name="code"><!-- resources.xml -->
<groups>
 <group name="myapp-all-compressed">
   <!-- The following .css files will be combined to make myapp-all-compressed.css -->
   <css>/css/reset.css</css>
   <css>/css/master.css</css>
   <css>/css/typography.css</css>

   <!-- The following .js files will be combined to make myapp-all-compressed.js -->
   <js>/js/lib/swfaddress/swfaddress.js</js>
   <js>/js/constants.js</js>
   <js>/js/util.js</js>
   ...
 </group>
</groups></pre>
<p>As I said, this configuration is used by the wro4j plugin when it minifies/compresses/optimizes the code at build-time. I won&#8217;t go into the details of how to configure wro4j here; see the <a href="http://code.google.com/p/wro4j/">wro4j website</a> for info on that.</p>
<p>So assuming you have wro4j configured to generate <code>myapp-all-compressed.js</code> and <code>myapp-all-compressed.css</code>, the next thing you&#8217;ll do is modify your HTML doc to use those files:</p>
<pre class="xml" name="code">&lt;html&gt;
  &lt;head&gt;
    &lt;link rel="stylesheet" type="text/css" href="myapp-all-compressed.css"/&gt;
    &lt;script type="text/javascript" src="myapp-all-compressed.js"&gt;&lt;/script&gt;
  &lt;/head&gt;
  ...
&lt;/html&gt;</pre>
<p>So how can we easily switch from these hard-to-read files to the &#8220;original&#8221; files? We&#8217;ll use JavaScript to download the aforementioned XML config file (resources.xml), parse it, and dynamically add &lt;script&gt; tags for each .js and .css file. But first, we&#8217;ll modify our HTML template (in this case, a JSP page) to check for a URL parameter and use our &#8220;dynamic script loader&#8221; instead of the production files:</p>
<pre class="xml" name="code">&lt;html&gt;
  &lt;head&gt;
  <% if( request.getParameter("debug") != null ) { %>
    <%-- DEBUG MODE: Dynamically load individual .js/.css files --%>
    &lt;script type="text/javascript" src="loadIndividualJsCssFiles.js"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;
    myapp.util.loadIndividualJsCssFiles('resources.xml');
    &lt;/script&gt;
  <% } else { %>
    <%-- PRODUCTION MODE --%>
    &lt;link rel="stylesheet" type="text/css" href="myapp-all-compressed.css"/&gt;
    &lt;script type="text/javascript" src="myapp-all-compressed.js"&gt;&lt;/script&gt;
  &lt;/head&gt;
  ...
&lt;/html&gt;</pre>
<p>As you can see, navigating to <code>http://yoursite.com/</code> results in the &#8220;optimized for production&#8221; files being used, but something like <code>http://yoursite.com/?debug</code> causes the browser to instead download <code>loadIndividualJsCssFiles.js</code> and call <code>myapp.util.loadIndividualJsCssFiles()</code> with the path to resources.xml.</p>
<p>Finally, let&#8217;s take a look inside loadIndividualJsCssFiles.js. At a high level, it extracts the list of .js/.css files from resources.xml and dynamically adds &lt;script&gt; and &lt;link&gt; nodes to the browser&#8217;s DOM for each JavaScript and CSS file. Note: it&#8217;s easiest to start at the bottom and read up.</p>
<pre class="c" name="code">if( myapp === undefined ) { myapp = {}; }
if( myapp.util === undefined) { myapp.util = {}; }

/**
 * Use this function to dynamically load a single CSS file.
 *
 * @param {String} path - URL path to the .css file that should be loaded
 */
myapp.util.loadStylesheetFile = function(path) {
 var linkElement = document.createElement('link');
 linkElement.setAttribute("type", "text/css");
 linkElement.setAttribute("rel", "stylesheet");
 linkElement.setAttribute("href", path);

 // Append the new &lt;link&gt; element to the end of &lt;head&gt;. The browser should
 // start downloading it immediately.
 myapp.console.info('Loading '+ path);
 document.getElementsByTagName("head")[0].appendChild(linkElement);
};

/**
 * Use this function to dynamically load a single JavaScript file.
 *
 * @param {String} path - URL path to the .js file that should be loaded
 * @param {Object} callbackFcn - (optional) A function that will be called if/when the script finishes loading
 */
myapp.util.loadJavaScriptFile = function(path, callbackFcn) {
 var elementOnLoadFcn,
     scriptElement = document.createElement('script');

 scriptElement.setAttribute("type", "text/javascript");

 if( callbackFcn != undefined &#038;&#038; callbackFcn != null ) {
   // Create a function that will be used as the value for the &lt;script&gt;
   // element's "onLoad" and "onreadystatechange" attributes.
   elementOnLoadFcn = function() {
     // This function can work for both 'onlload' and 'onreadystatechange' events
     // Note: When this code is run 'this' will refer to the &lt;script&gt; object.
     if ( this.readyState &#038;&#038; this.readyState != "complete" &#038;&#038; this.readyState != "loaded" ) {
       return;
     }
     this.onload = this.onreadystatechange = null; // ensure callback is only called once

     // Execute callback that indicates the script was loaded
     callbackFcn(this.src);
   };

   // Configure the &lt;script&gt; element's onload and onreadystatechange attributes
   scriptElement.onload = elementOnLoadFcn;
   scriptElement.onreadystatechange = elementOnLoadFcn;
 }

 scriptElement.setAttribute("src", path);

 // Append the new &lt;script&gt; element to the end of &lt;head&gt;. The browser should
 // start downloading it immediately; when finished, the elementOnLoadFcn
 // function (if it exists) will run.
 myapp.console.info('Loading '+ path);
 document.getElementsByTagName("head")[0].appendChild(scriptElement)
};

/**
 * Use this function to dynamically load multiple JavaScript files.
 *
 * @param {Array} filePathsArr - Array of URL paths to the .js files that should be loaded
 */
myapp.util.loadJavaScriptFiles = function(filePathsArr) {
 var jsFileIndex = 0,
     loadNextScriptFcn = function() {
       if (jsFileIndex &lt; filePathsArr.length) {
         myapp.util.loadJavaScriptFile(filePathsArr[ jsFileIndex++ ], loadNextScriptFcn);
       }
     };

 loadNextScriptFcn();
};

/**
 * Use this function to dynamically load a single JavaScript file.
 *
 * @param {String} path - Path to a wro4j resources XML file.
 */
myapp.util.loadIndividualJsCssFiles = function(wro4jResourcesFile) {
 // JS best practice: declare vars at start of fcn (for more info, search "javascript hoisting")
 var i,
     cssNodesArr,
     jsNodesArr,
     nodesArrLength,
     request,
     jsFilePathsArr = [],
     resourcesDoc;

 // Get the XML file which has the list of all individual .js and .css files
 // used by the front-end.
 if (window.XMLHttpRequest) { // IE7+, Firefox, Chrome, Opera, Safari
   request = new XMLHttpRequest();
 } else { // IE5, IE6
   request = new ActiveXObject("Microsoft.XMLHTTP");
 }

 request.open("GET", wro4jResourcesFile, false);
 request.send();
 resourcesDoc = request.responseXML;

 // Load all stylesheet files specified by &lt;css&gt; elements in resources file
 cssNodesArr = resourcesDoc.getElementsByTagName("css");
 nodesArrLength = cssNodesArr.length; // Best practice: iterate HTMLCollection by caching array length
 for(i = 0; i &lt; nodesArrLength; i++) {
   myapp.util.loadStylesheetFile( cssNodesArr[i].childNodes[0].nodeValue );
 }

 // Load all JavaScript files specified by &lt;js&gt; elements in resources file
 jsNodesArr = resourcesDoc.getElementsByTagName("js");
 nodesArrLength = jsNodesArr.length; // Best practice: cache HTMLCollection length instead of re-calculating for each iteration
 jsFilePathsArr = new Array();
 for(i = 0; i &lt; nodesArrLength; i++) {
   jsFilePathsArr.push( jsNodesArr[i].childNodes[0].nodeValue );
 }

 myapp.util.loadJavaScriptFiles( jsFilePathsArr );
};</pre>
<p>The end result is that you keep the list of .js/.css files in <em>one</em> place (resources.xml)&#8211;you don&#8217;t have to keep updating your .jsp or pom.xml file each time you need to add or remove .js/.css files. The <code>loadJavaScriptFiles()</code> function will ensure those files get picked up the next time you refresh the browser with the &#8216;debug&#8217; URL param, and wro4j will similarly include those files in myapp-all-compressed.js/myapp-all-compressed.css the next time a build is done.</p>
<style type="text/css">@import url("http://www.clintharris.net/syntaxhighlighter/Styles/SyntaxHighlighter.css");</style><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shCore.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushCpp.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushJava.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushPhp.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushSql.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushXml.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushJScript.js"></script><script language="javascript">window.onload = function (){ dp.SyntaxHighlighter.HighlightAll("code"); }</script> ]]></content:encoded>
			<wfw:commentRss>http://www.clintharris.net/2011/using-wro4j-to-easily-switch-between-minified-and-debuggable-javascriptcss/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How to Safely Use the JavaScript console Object (and Dynamically Enable/Disable Logging)</title>
		<link>http://www.clintharris.net/2011/how-to-safely-use-the-javascript-console-object-and-dynamically-enabledisable-logging/</link>
		<comments>http://www.clintharris.net/2011/how-to-safely-use-the-javascript-console-object-and-dynamically-enabledisable-logging/#comments</comments>
		<pubDate>Wed, 18 May 2011 10:43:05 +0000</pubDate>
		<dc:creator>Clint</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.clintharris.net/?p=561</guid>
		<description><![CDATA[Note: Your RSS reader or email client may block the JavaScript and CSS in this post. If the code samples below do not appear with syntax highlighting and line numbers, you may want to view this post in your browser.In the primordial days of the web, debugging JavaScript often meant using the alert() function to [...]]]></description>
			<content:encoded><![CDATA[<div style='background-color:#F3F3F3; border-color:#DDDDDD; border-style:solid; border-width:1px 0; font-size:0.8em; font-style:italic; margin-bottom:1.571em; padding:5px;}'><em><strong>Note:</strong> Your RSS reader or email client may block the JavaScript and CSS in this post. If the code samples below do not appear with syntax highlighting and line numbers, you may want to <a href='http://www.clintharris.net/2011/how-to-safely-use-the-javascript-console-object-and-dynamically-enabledisable-logging/'>view this post in your browser</a>.</em></div><p>In the primordial days of the web, debugging JavaScript often meant using the alert() function to print information about what your code was doing. Thankfully we now have debuggers and, for developers who prefer logging, the console object which offers functions like console.log().</p>
<p>There’s a catch with the console object, however: it doesn’t always exist. More specifically, most browsers don’t provide a console object by default (Chrome being one exception). You usually need some kind of developer tool or extension running to provide a console object—Firebug or the ‘Developer Tools’ add-on for IE, for example. And without a console object, calls like console.log() result in a “console is not defined” error.</p>
<p>I came up with a solution to this on a recent project (although I highly doubt I was the first to do so). It basically involves creating a “dummy” console object that will be used if the real thing doesn’t exist, which prevents “undefined” errors. With the flip of a switch, however, you can “turn on” logging and start using the actual console if it exists.</p>
<p>It’s pretty simple to use. First, make sure the following gets run before any code tries to call the console functions:</p>
<pre class="c" name="code">// Create object that will be used for 'myapp' namespace if it doesn't already exist.
if( myapp === undefined ) {
    var myapp = {};
}

// Create an object with functions that mimic the window.console object made
// available by tools like Firebug or the "Dev Tools" add-on in IE8+
myapp.dummyConsole = {
    assert : function(){},
    log : function(){},
    warn : function(){},
    error : function(){},
    debug : function(){},
    dir : function(){},
    info : function(){}
};

// Throughout our app we'll make console/logging calls by using the myapp.console
// object. Example: myapp.console.debug("blerg!"). By default, the myapp.console
// object should use the "dummy" console that doesn't do anything.
myapp.console = myapp.dummyConsole;

// This function can be used to switch the myapp.console variable to use the
// real window.console object. Note that it does a safety check to ensure that
// window.console actually exists (it won't in browsers not running Firebug or
// the IE dev tools).
myapp.enableConsoleOutput = function(enable) {
    // Don't enable the console unless it actually exists
    if (enable &amp;&amp; window.console !== undefined) {
        myapp.console = window.console;
    } else {
        myapp.console = myapp.dummyConsole;
    }
};</pre>
<p>I like putting this in a file called console.js and making sure it appears in one of the first &lt;script&gt; elements, for example. Next, instead of using the console object directly, modify your code to use myapp.console:</p>
<pre class="c" name="code">myapp.console.info(“my cat’s breath smells like cat food”);
myapp.console.warn(“danger will robinson!”);</pre>
<p>You can leave these logger statements in your code without worrying about them causing errors. To “enable logging” (i.e., swap the fake console object with the real one if it exists), call:</p>
<pre class="c" name="code">myapp.enableConsoleOutput(true);</pre>
<p>This gives you the ability to dynamically turn logging on/off. You could, for example, execute the statement in the Firebug console. Another approach would be to hard-code it in your HTML doc:</p>
<pre class="c" name="code">&lt;script type="text/javascript" src="console.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
    myapp.enableConsoleOutput(true);
&lt;/script&gt;</pre>
<p>Lastly, if your HTML doc is generated dynamically (e.g., JSP, PHP, etc.) you could add some server-side logic that only writes this statement if a special “enable logging” flag exists in the URL parameters. I usually take this approach because it allows you to A) see any logging statements that execute during the page’s “startup” phase (i.e., before you have had time to run the statement in the Firebug console) and B) still gives you the option of running Firebug with logging disabled.</p>
<style type="text/css">@import url("http://www.clintharris.net/syntaxhighlighter/Styles/SyntaxHighlighter.css");</style><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shCore.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushCpp.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushJava.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushPhp.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushSql.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushXml.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushJScript.js"></script><script language="javascript">window.onload = function (){ dp.SyntaxHighlighter.HighlightAll("code"); }</script> ]]></content:encoded>
			<wfw:commentRss>http://www.clintharris.net/2011/how-to-safely-use-the-javascript-console-object-and-dynamically-enabledisable-logging/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>InAppSettingsKit</title>
		<link>http://www.clintharris.net/2010/inappsettingskit/</link>
		<comments>http://www.clintharris.net/2010/inappsettingskit/#comments</comments>
		<pubDate>Thu, 15 Jul 2010 18:56:46 +0000</pubDate>
		<dc:creator>Clint</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[iphone_dev]]></category>

		<guid isPermaLink="false">http://www.clintharris.net/?p=544</guid>
		<description><![CDATA[I recently came across an extremely handy open source API for managing settings in iPhone apps. In a nutshell, InAppSettingsKit looks and works just like the normal settings/preferences mechanism (e.g., Settings.bundle), except that it allows you to easily display a settings view in your app in addition to the standard Settings.app (there are a few [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_462" class="wp-caption alignleft" style="width: 231px"><img class="size-full wp-image-462" title="Settings Screenshot" src="http://img.skitch.com/20100715-8rnjc1juuwqwpbn8r1emj18siw.jpg" alt="Image courtesy of InAppSettingsKit.com" width="221" height="329" /><p class="wp-caption-text">Image courtesy of InAppSettingsKit.com</p></div>
<p>I recently came across an extremely handy open source API for managing settings in iPhone apps. In a nutshell, InAppSettingsKit looks and works just like the normal settings/preferences mechanism (e.g., Settings.bundle), except that it allows you to easily display a settings view <em>in your app</em> in addition to the standard Settings.app (there are a few other perks, too).</p>
<p>In addition to their <a href="http://www.inappsettingskit.com">website</a>, you can listen to a great <a href="http://www.mac-developer-network.com/shows/podcasts/mdnshow/mdnshow027.html">interview</a> with one of the creators from via the &#8220;mac developer network&#8221; website.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.clintharris.net/2010/inappsettingskit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Benefits of Coding Protocols that *Extend* the NSObject Protocol</title>
		<link>http://www.clintharris.net/2010/the-benefits-of-coding-protocols-that-extend-the-nsobject-protocol/</link>
		<comments>http://www.clintharris.net/2010/the-benefits-of-coding-protocols-that-extend-the-nsobject-protocol/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 23:09:44 +0000</pubDate>
		<dc:creator>Clint</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[iphone_dev]]></category>
		<category><![CDATA[objective-c]]></category>

		<guid isPermaLink="false">http://www.clintharris.net/?p=532</guid>
		<description><![CDATA[Note: Your RSS reader or email client may block the JavaScript and CSS in this post. If the code samples below do not appear with syntax highlighting and line numbers, you may want to view this post in your browser.Update (8/19/10): It&#8217;s come to my attention that using delegates as the primary example below was [...]]]></description>
			<content:encoded><![CDATA[<div style='background-color:#F3F3F3; border-color:#DDDDDD; border-style:solid; border-width:1px 0; font-size:0.8em; font-style:italic; margin-bottom:1.571em; padding:5px;}'><em><strong>Note:</strong> Your RSS reader or email client may block the JavaScript and CSS in this post. If the code samples below do not appear with syntax highlighting and line numbers, you may want to <a href='http://www.clintharris.net/2010/the-benefits-of-coding-protocols-that-extend-the-nsobject-protocol/'>view this post in your browser</a>.</em></div><p><em><strong>Update (8/19/10)</strong>: It&#8217;s come to my attention that using delegates as the primary example below was not a good idea. When you have a @property for a delegate, the best practice is to use assign, not retain, so that you avoid a so-called &#8220;retain loop&#8221; and accompanying memory leaks (<a href="http://stackoverflow.com/questions/918698/why-are-objective-c-delegates-usually-given-the-property-assign-instead-of-retain" target="_self">more info</a>). That said, the idea of extending the NSObject protocol so that you can call release without warnings is still helpful in some situations&#8211;just not those involving delegates.</em></p>
<p>It&#8217;s pretty common to use custom Objective-C protocols in iPhone development, especially when it comes to using <a href="http://en.wikipedia.org/wiki/Delegation_pattern" target="_blank">delegates</a> to keep your code modular. Consider the following example:</p>
<pre class="c" name="code">@protocol EngineDelegate
{
    -(void) goFaster;
    -(void) goSlower;
}

@interface Automobile : NSObject
{
    id&lt;EngineDelegate&gt; engineDelegate;
}
@property (nonatomic, assign) id&lt;EngineDelegate&gt; engineDelegate;</pre>
<p>This shows an Automobile class that has a single member variable/property, an &#8220;engine delegate&#8221; (i.e., the Automobile will delegate requests to go faster/slower to the EngineDelegate). Because engineDelegate is declared using the generic pointer &#8220;id&#8221; type, you can assign ANY object to it as long as that object implements the EngineDelegate protocol (i.e., has -goFaster and -goSlower methods). But what happens if you try to release the delegate? For example:</p>
<pre class="c" name="code">@implementation Automobile
...
- (void) dealloc
{
    [engineDelegate release];
}
@end</pre>
<p>The compiler will generate a &#8220;-release not found&#8221; warning because it can&#8217;t tell if engineRelease implements the -release method. This is problematic not just because of the warning, but more importantly, <em>because it prevents you from doing normal retain/release operations</em> that are common in a managed memory environment like the iPhone. In other words, how are you supposed to ensure that the delegate is properly released?</p>
<p>I recently came across a clever solution to this dilemma on MobileOrchard. In a nutshell, <a href="http://www.mobileorchard.com/idprotocol-retainrelease-and-protocol-inheritance/" target="_blank">the post</a> suggests declaring protocols as inheriting from the NSObject <strong>protocol</strong> which, in turns, defines the retain and release methods. A lot of developers might be surprised to learn that you can do such a thing (I certainly was). Here&#8217;s what it looks like:</p>
<pre class="c" name="code">@protocol EngineDelegate &lt;NSObject&gt;
{
    -(void) goFaster;
    -(void) goSlower;
}</pre>
<p>Now the Automobile class can safely assume that the delegate will implement the -retain and -release methods (and in most cases, the delegate will inherit the methods from the NSObject*). It&#8217;s nice that we can get rid of compiler warnings in this way, but it&#8217;s more important that we can use normal retain/release methods for memory management and not worry about whether or not the memory used by the delegate is freed.</p>
<p><em>*Note that not all objects extend the NSObject class (although for most folks, this is pretty rare). For example, many classes related to Cocoa&#8217;s &#8220;distributed object&#8221; mechanism descent from NSProxy instead of NSObject.</em></p>
<style type="text/css">@import url("http://www.clintharris.net/syntaxhighlighter/Styles/SyntaxHighlighter.css");</style><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shCore.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushCpp.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushJava.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushPhp.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushSql.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushXml.js"></script><script language="javascript" src="http://www.clintharris.net/syntaxhighlighter/Scripts/shBrushJScript.js"></script><script language="javascript">window.onload = function (){ dp.SyntaxHighlighter.HighlightAll("code"); }</script> ]]></content:encoded>
			<wfw:commentRss>http://www.clintharris.net/2010/the-benefits-of-coding-protocols-that-extend-the-nsobject-protocol/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Xcode 3.2 (OSX 10.6) Shortcut Reference</title>
		<link>http://www.clintharris.net/2009/xcode-32-osx-106-shortcut-reference/</link>
		<comments>http://www.clintharris.net/2009/xcode-32-osx-106-shortcut-reference/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 14:34:54 +0000</pubDate>
		<dc:creator>Clint</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[xcode]]></category>

		<guid isPermaLink="false">http://www.clintharris.net/?p=525</guid>
		<description><![CDATA[Colin Wheeler recently updated his chart of keyboard shortcuts for Xcode 3.2. Great resource.]]></description>
			<content:encoded><![CDATA[<p>Colin Wheeler recently updated his <a href="http://cocoasamurai.blogspot.com/2009/08/xcode-shortcuts-updated-for-xcode-32-on.html" target="_self">chart of keyboard shortcuts for Xcode 3.2</a>. Great resource.</p>
<p><a href="http://cocoasamurai.blogspot.com/2009/08/xcode-shortcuts-updated-for-xcode-32-on.html"><img class="alignleft size-full wp-image-526" title="xcodeshortcuts" src="http://www.clintharris.net/_wpress/wp-content/uploads/2009/08/xcodeshortcuts.png" alt="xcodeshortcuts" width="309" height="320" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.clintharris.net/2009/xcode-32-osx-106-shortcut-reference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
