<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by Squarespace Site Server v5.9.2 (http://www.squarespace.com/) on Thu, 11 Mar 2010 05:29:17 GMT--><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rss="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:cc="http://web.resource.org/cc/"><rss:channel rdf:about="http://www.levelofindirection.com/journal/"><rss:title>level of indirection</rss:title><rss:link>http://www.levelofindirection.com/journal/</rss:link><rss:description></rss:description><dc:language>en-GB</dc:language><dc:date>2010-03-11T05:29:17Z</dc:date><admin:generatorAgent rdf:resource="http://www.squarespace.com/">Squarespace Site Server v5.9.2 (http://www.squarespace.com/)</admin:generatorAgent><rss:items><rdf:Seq><rdf:li rdf:resource="http://www.levelofindirection.com/journal/2010/3/5/the-80s-called-they-want-their-memory-manager-back.html"/><rdf:li rdf:resource="http://www.levelofindirection.com/journal/2010/3/2/interlude.html"/><rdf:li rdf:resource="http://www.levelofindirection.com/journal/2010/1/31/why-the-ipad-may-never-need-multi-tasking.html"/><rdf:li rdf:resource="http://www.levelofindirection.com/journal/2010/1/30/what-ill-be-using-the-ipad-for.html"/><rdf:li rdf:resource="http://www.levelofindirection.com/journal/2010/1/27/what-is-the-ipad-for.html"/><rdf:li rdf:resource="http://www.levelofindirection.com/journal/2009/11/11/code-formatting-in-c-part-three.html"/><rdf:li rdf:resource="http://www.levelofindirection.com/journal/2009/11/4/apples-magic-mouse-just-sleight-of-hand.html"/><rdf:li rdf:resource="http://www.levelofindirection.com/journal/2009/10/31/devdays-slides.html"/><rdf:li rdf:resource="http://www.levelofindirection.com/journal/2009/10/29/stackoverflow-devdays-london.html"/><rdf:li rdf:resource="http://www.levelofindirection.com/journal/2009/10/10/using-a-networked-drive-for-time-machine-backups-on-a-mac.html"/></rdf:Seq></rss:items></rss:channel><rss:item rdf:about="http://www.levelofindirection.com/journal/2010/3/5/the-80s-called-they-want-their-memory-manager-back.html"><rss:title>The 80s called; they want their memory manager back!</rss:title><rss:link>http://www.levelofindirection.com/journal/2010/3/5/the-80s-called-they-want-their-memory-manager-back.html</rss:link><dc:creator>Phil Nash</dc:creator><dc:date>2010-03-05T00:25:55Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[<p>
Not too long ago I was presenting on the subject of iPhone development and Objective-C at the <a href="http://blog.stackoverflow.com/2009/05/stack-overflow-developer-days-conference/">Stackoverflow conference</a>. As <a href="http://www.levelofindirection.com/journal/2009/10/29/stackoverflow-devdays-london.html">I wrote at the time</a>, the audience was of predominantly .Net developers and the twitter backchat was filled with a whole range of reactions. Actually there were two themes to that reaction. One was to the syntax of Objective-C which is certainly very different to most C-family languages. The other was to the fact that Objective-C for the iPhone is not garbage collected (although it is on the Mac these days). My favourite comment on twitter was the title of this post.[*]
</p>
<p>
Much has been said from both sides about whether the iPhone <em>should</em> support garbage collection or not and I won't go into the debate here, other than to say that I think there are valid reasons for it being that way - but that's not to say that it couldn't be made to work (it would be nice if it was at least optional).</p>
<h2>A few pointers</h2>
<div style="text-align:center;"><a href="http://xkcd.com/138/"><img src="http://imgs.xkcd.com/comics/pointers.png" border="0" /></a></div>
<br/>
<p>
As a grizzled C++ developer in past (and, as it happens, present) lives I'm not fazed by the sight of a raw pointer or the need to count references. That said I struggle to remember the last time I had a memory leak, a dangling pointer or a double-deletion. Is that because I'm an awesome C++ demigod who eats managed programmers for breakfast? No! Not <em>just</em> that! It's also because I use <em>smart pointers</em>.
</p>
<p>
Smart pointers make use of a feature of C++ that is disappointingly rare in modern programming languages (and often seen as incompatible with garbage collection): <em>deterministic destruction</em>. Put simply when a value goes out of scope it is destroyed there and then. There is no waiting for a garbage collector to kick in at some undetermined, and indeterminate, time to clean up after you. Then why does C++ have the <span class="code">delete</span> keyword? Well I said when a <em>value</em> goes out of scope. If you allocate an object on the heap, the <em>value</em> you have in scope is the <em>pointer</em> to the object. C++ also allows you to create objects on the stack, and these are destroyed at the end of the scope in which they were created (there is a third case where an object is declared by value as a member of another object that lives on the heap - but I'll ignore that for simplicity). When that object is an instance of a class the developer has defined they can supply a <a href="http://en.wikipedia.org/wiki/Destructor_%28computer_science%29">destructor</a> that is run when the object is destroyed. Often this is used to delete memory owned by the object - but it could be used to clean up any resources the object is managing, such as file handles, database collections etc. Smart pointers manage objects on the heap. Depending on the type of smart pointer they may simply delete an object in their destructor - or they may offer shared ownership semantics by managing a reference count - so destructors decrement the ref count and only delete when the count reaches zero.
</p>

<p>I've crammed an overview of a rich and incredible powerful language feature into a single paragraph above. I haven't even touched on how smart pointers use operator overloading to look like pointers. You can read more details <a href="http://en.wikipedia.org/wiki/Smart_pointer">elsewhere</a>. My point is that, because of smart pointers - made possible by deterministic destruction (or more generally an idiom unfortunately known as RAII) - garbage collection is not really missed in C++.
<p>

<h2>Using {</h2>
<p>All of which is the long winded setup to my story for this post. The last couple of days I have been involved with tracking down an issue in a .Net app. I say "involved with" because there were three of us looking at this one problem. Three developers, with more than half a century of professional development experience between us, all on the critical path, tracking down this one problem. In .Net. The problem turned out to be with garbage collection. Actually there was more than one problem.<p>

<h3>Is that a jagged array in your pocket?</h3>
<p>Now this is not about knocking garbage collection. Or .Net. This is about how things are not always as they appear. In fact that's exactly what the first issue was. We have C++/CLI classes that are really just thin proxy wrappers for native C++ objects. The C++ objects are often multi-dimensional arrays and can get quite big. The problem was that the "payload" of these objects was effectively invisible to .Net. As far as it was concerned it was dealing with thousands of <em>tiny</em> objects. The result was that, when called from C#, it was happily creating more and more of these without garbage collecting the large number of, now unreferenced, older objects!<p>

<p>Actually we had anticipated this state of affairs and had made sure that all these proxy objects were disposable. This meant that in C# we could wrap the usage in a <span class="code">using</span> block and the objects would be disposed of at the end of the <span class="code">using</span> scope. The problem with this is that there is no way to enforce the use of <span class="code">using</span>. By contrast: in C++ if you implement clean-up code in a destructor it will always be called at the end of scope (ok, if you create it on the heap there is no "end of scope" and you're back to square one. I'd argue that you have to make more of an effort to do this, however - and there are also tricks you can use to detect if).</p>

<p>As it happens <span class="code">using</span> is not really the right tool here anyway. The vast majority of these objects, whether boxed primitives (we have a <span class="code"><a href="http://en.wikipedia.org/wiki/Variant_type">Variant</a></span> type) or arrays, are semantically just values. Using <span class="code">using</span> with "value" types is clumsy and often impractical. What we would really like is a way to tell the GC that these proxies have a native payload - and have it take that into consideration when deciding when and what to collect. Of course we have just such a facility: <span class="code"><a href="http://msdn.microsoft.com/en-us/library/system.gc.addmemorypressure.aspx">GC.AddMemoryPressure()</a></span> and <span class="code"><a href="http://msdn.microsoft.com/en-us/library/system.gc.removememorypressure.aspx">GC.RemoveMemoryPressure()</a></span>. These methods allow you to tell .Net that a particular managed object also refers to unmanaged memory of a particular size (in fact you can incrementally add and remove "pressure"). Sounds like just what we need.<p>
<p>Unfortunately there is more to it. First we need to know what "pressure" to apply. If the data is immutable and fully populated by the time the proxy sees it then that is one thing. But if data can be added and removed from <em>both managed and native sides</em> it becomes more tricky. To do it properly we'd have to add hooks deeper into the native array objects so that we know when to apply more or less pressure. Furthermore many of our arrays are really jagged arrays, implemented in terms of Variants containing Variant arrays of more Variants of Variant arrays (if that sounds appalling you probably haven't worked in a bank. Or maybe you have). How can we keep track of the memory being consumed by such structures? Well it helps to keep in mind that we don't really need to know the exact number of bytes. As long as we can give the GC enough hints that it could bucket sizes into, say, orders of magnitude (I don't know exactly how the GC builds its collection strategies and I don't want to second guess it. I'd imagine even this is more granularity than it needs most of the time, but it seems a reasonable level of accuracy to strive for). Fortunately I already have code that can walk these structures and come back with effective fixed array dimensions, so multiplying that by the size of a Variant should get us well into the ballpark we need.
</p>

<div style="text-align:center;" width="500"><img src="http://www.levelofindirection.com/resource/-?fileId=6011051" alt="Garbage Only.jpg" border="0" width="500"/><div>Photo by Peter Kaminski - http://flic.kr/p/2A5db</div></div> 



<h3>A weak solution</h3>
<p>So that was one problem (with several sub-problems). The other was that a certain set of these objects were being tracked in a static <span class="code">Dictionary</span> in the proxy infrastructure. Setting aside, for a moment, the horrors of globals, statics and (shudder) singletons, let's assume that there were valid reasons for needing to do this. The problem here was that the references in the dictionary were naturally keeping the objects alive beyond their useful lifetime! In a way this was a memory leak! Yes you can get memory leaks in garbage collected languages. Of course what we should have been doing (and now are doing) is to hold <em><a href="http://en.wikipedia.org/wiki/Weak_reference">weak references</a></em> in the static dictionary. I'd guess, however, that many .Net developers are not even aware of <span class="code">WeakReference</span>. Why should they be? Managed Code is supposed to, well, "manage" your "code" isn't it? Anyway, not surprisingly switching to weak references here solved that problem (and somewhat more easily than the other one).</p>

<p>I'll say again - I'm not having a dig at .Net developers - or anyone else who primarily targets "managed" languages these days. I've used them for years myself. My point is that there is a lot more to it and you don't have to go <em>too</em> far to hit the pathological cases. And when you do hit them things get tricky pretty fast. In addition to the fundamental problems discussed above I spent a lot of time profiling and experimenting with different frequencies and placements of calls to <span class="code">GC.Collect()</span> and <span class="code">GC.WaitForPendingFinalizers()</span>. None of these things were necessary in the pure C++ code (admittedly they are not often necessary in pure C# code either) but when they are it can be very confusing if you're not prepared</p>

<h2>}</h2>
<p>phew!</p>

<p>Now I started out talking about Objective-C but have ended up talking mostly about C++ and C# (although the lessons have been more general). To bring us back to Objective-C, though, where does it fit in to all this?</p>

<h2>Clearly destructive</h2>
<p>Well on the iPhone Objective-C lacks garbage collection, as we already noted. It also lacks deterministic destruction (or destructors as a language concept at all). So does that leave us in the Wild West of totally manual C-style memory management? Not quite. Probably the biggest issue with memory management in C is <em>not</em> that you have to do it manually. Personally I think a bigger issue is a lack of universally agreed conventions for <em>ownership</em>. If a function allocates some memory who owns that memory? The caller? Maybe - except when they don't! Some libraries, and most frameworks, establish their own conventions for these things - which is fine. But they're not all the same conventions. So not only is it not always immediately obvious if you are supposed to clean-up some memory - but the confusion makes it less likely that you will remember to at all (because, sub-consciously you're putting off the need to work it out for as long as possible).<p>

<p>Objective-C, at least in Apple's world, doesn't have this problem. There is a very simple, clear and concise <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html">set of rules for ownership</a> that are universally adopted:</p>

<blockquote>
If a function or method begins with <span class="code">alloc</span> or <span class="code">new</span>, or has the word <span class="code">copy</span> in it, or you explicitly call <span class="code">retain</span> - the caller owns it. Otherwise they don't.
</blockquote>

<p> That's it! There are some extra wrinkles, mostly to do with <span class="code">autorelease</span>, but they still follow those rules.</p>

<p>Other than some circular references I had once, and quickly resolved, I don't recall having any problems with memory management in Objective-C for a long time either<p>
<h2>Epilogue</h2>
<p>
There. I've discussed memory management in four languages in a single post - and not mentioned the iPad once! As it happens you can use all four languages to write for the iPhone or iPad. So take your pick of memory management trade-offs.
</p>
<br />
<p>
[*] I tried to track down who tweeted "The 80s called; they want their memory manager back" during Stackoverflow Devdays. As it's difficult to search Twitter very far into the past I couldn't find the original tweet - but thanks to a <a href="http://twitter.com/nickgps/status/5232966633">retweet</a> by <a href="http://twitter.com/nickgps">Nick Sertis</a> it appears that it was <a href="http://twitter.com/jMarkP">J. Mark Pim</a>. Thanks J.
</p>]]></content:encoded></rss:item><rss:item rdf:about="http://www.levelofindirection.com/journal/2010/3/2/interlude.html"><rss:title>Interlude</rss:title><rss:link>http://www.levelofindirection.com/journal/2010/3/2/interlude.html</rss:link><dc:creator>Phil Nash</dc:creator><dc:date>2010-03-02T19:22:11Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[<p>
I don't usually use this blog to get meta about, well, this blog. But I just wanted to take a moment to reset some expectations. This is probably not of great interest to most readers so please feel free to skip it. I promise I won't do it very often.
</p>
<p>
I've had a series of posts recently about the iPad, and historically one or two others that have touched on products rather than code. Primarily this blog has been about software development. The target audience is software developers. I will continue to write about software development. However I also occasionally intersperse this with commentary on technology that I feel is relevant to software development as a scene, if not as a discipline. I feel that the iPad is going to have a big impact on he future of software - maybe not in total, but in significant part. Not everyone will agree with that, but what are blogs for if not for putting opinions out there to be dissected (don't answer that)?
</p>
<p>It's also interesting that, while my iPad posts gave it a run for its money for a while, my highest ranking post to date remains the one about setting up <a href="http://www.levelofindirection.com/journal/2009/10/10/using-a-networked-drive-for-time-machine-backups-on-a-mac.html">Time Machine backups to network drives</a>. I'm not sure if this is a good sign or not. But one thing is sure. I'm not going to switch my focus to writing about products just to get the page hits. That's not why I write this blog.
</p>
<p>
Well that's enough indulgence of the forbidden fruit of meta for now. We will now resume our usual programming (pun very much intended).
</p>]]></content:encoded></rss:item><rss:item rdf:about="http://www.levelofindirection.com/journal/2010/1/31/why-the-ipad-may-never-need-multi-tasking.html"><rss:title>Why the iPad may never need multi-tasking</rss:title><rss:link>http://www.levelofindirection.com/journal/2010/1/31/why-the-ipad-may-never-need-multi-tasking.html</rss:link><dc:creator>Phil Nash</dc:creator><dc:date>2010-01-31T12:36:08Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[<div style="text-align:center;"><img src="http://www.levelofindirection.com/resource/-?fileId=5573803" alt="activityMonitor.png" border="0" width="577" height="448" /></div>
<p>
Like the iPhone and iPod touch the iPad does not allow multi-tasking of third-party apps. That is, if you are using one app and want to start another you must close the first app. I wouldn't rule out that changing in a future update, but I'm more inclined to think we won't see it even on the iPad - at least not in a general form. Why?</p>
<p>The way I see it multi-tasking is used for three purposes:</p>
<ol>
<li>
Background apps, such as music players. The iPod app <em>does</em> run in the background, of course, but there is certainly a case for third-party apps such as <a href="http://www.spotify.com/en/">Spotify</a> or <a href="http://www.last.fm/">Last.fm</a> to have the same ability.
</li>
<li>
Notifications. This is at least partly addressed by the <a href="http://developer.apple.com/iphone/program/sdk/apns.html">Push Notification</a> service that Apple now provides. More on that in a moment.
</li>
<li>
Fast switching between apps
</li>
</ol>

<p>
I'd say that (3) is probably the number one reason we usually have so many apps open at once. After all we can usually only <em>interact</em> with one at a time. As the time it takes to (save and) quit one app and start (and restore) a new one gets closer to zero our need to have the apps open just so we can switch to them diminishes or disappears. From what I have read and heard the iPad gets us pretty close to the threshold where this happens. By some reports it crosses that threshold. I'll reserve final judgement until I see it with my own hands (mixed metaphor intended).
</p>
<p>
Going back to reason (2) let me explain what I mean by being only partly addressed so far. Imagine a calendar-type app - such as <a href="http://www.perculasoft.com/eventhorizon/">Event Horizon</a>. You set up events and appointments - which may be days, weeks or months later. Ideally the app would be able to alert you of upcoming events in much the same way that Apple's own calendar app can already do. One way to achieve that now would be to use the push notification service. This would work but has two problems. First it's a bit heavyweight. Your event data would need to be synced up to a cloud service which could then decide when to push a notification back to the device. Cloud services certainly have their place, but bringing them in <em>solely</em> to provide alerts seems out of proportion. Secondly it means you will not receive the notification if you don't happen to be connected at that time. You will get it when you do get online, but that may be too late! Furthermore you need to be connected for the alert to sync up to the cloud in the first place. These all seems unjustifiable limitations when it concerns data that you already <em>hold locally on your device</em>.  Therefore I think it reasonable that some sort of Scheduled Notification API should be made available. This could work just like the Push Notification service, allowing badges, messages and alert tones to be "pushed" to the user, with the ability for the user to open the associated app straight away, or defer that until later. The difference would be that the notification would be posted by the app itself for delivery at a specific time in the future and would <em>never leave the device</em>. I don't see any technical challenges to providing such an API.
</p>
<p>
If a scheduled notification API is made available I think the only significant remaining need for background tasks would be for things like music players. If Apple do allow background tasks in the future I think it will be limited to these types of tasks, and very strictly policed in the app store approval process. I'll say again,<em> I don't believe Apple will ever allow <strong>general purpose</strong> multi-tasking in App Store apps.</em> - and I don't believe they <em>need</em> to with the concessions just described. Note that I am ruling out other scenarios such as video encoders or bit-torrent clients, which I don't think are appropriate apps for running on these devices in the first place. If you can think of anything genuinely useful for a significant number of people that wouldn't be covered by such provisions I'd be interested to know.
</p>

<technoratiTags>
<!-- Technorati Tags Start -->
<p>Technorati Tags:
<a href="http://technorati.com/tag/Apple" rel="tag">Apple</a>, <a href="http://technorati.com/tag/iPad" rel="tag">iPad</a>, <a href="http://technorati.com/tag/iPhone" rel="tag">iPhone</a>, <a href="http://technorati.com/tag/Multi-tasking" rel="tag">Multi-tasking</a>
</p>
<!-- Technorati Tags End -->
</technoratiTags>]]></content:encoded></rss:item><rss:item rdf:about="http://www.levelofindirection.com/journal/2010/1/30/what-ill-be-using-the-ipad-for.html"><rss:title>What *I'll* be using the iPad for</rss:title><rss:link>http://www.levelofindirection.com/journal/2010/1/30/what-ill-be-using-the-ipad-for.html</rss:link><dc:creator>Phil Nash</dc:creator><dc:date>2010-01-30T13:18:16Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[<p><a href="http://www.levelofindirection.com/journal/2010/1/27/what-is-the-ipad-for.html">My last post</a> was a bit of a teaser for the app that I am writing for the iPad. I don't apologise for that. While I did want to pique your curiosity my key point was that there are developers, like me, already out there with plans for iPad applications that simply wouldn't be feasible for any other platform. Just to clarify that: they would be <em>possible</em> for sure - I was planning first a desktop version, then later an iPhone version, of my app - but the experience would always feel like a compromise. I <em>still</em> plan on desktop, iPhone, and even web clients - but they will effectively be auxiliary clients in much the same way that many iPhone apps today are auxiliary to their desktop counterparts.
</p>

<p>Does this mean that, before such apps arrive, the iPad is just an empty slab? Perhaps useable only for the very old, the very young, or the technically illiterate? Not at all. The key reason that there has been such a backlash against the iPad is that there was so much hype about it before the announcement. It wasn't just that everyone had idyllic expectations of what it would be for <em>them</em> - although that certainly didn't help. Just the fact that there <em>was</em> hype meant that everyone was watching this event as being a turning point in the history of computing. The trouble with historical turning points is that they are often only recognisable as such when you have the historical perspective. Put it this way: if the launch of the iPad really does turn out to be the moment of a revolution in computing, when looking back on this in years to come, would it seem reasonable to think that its lack of a front-facing camera or support for Flash would be a factor in that status?
</p>

<p>
I think it's quite likely that some sort of camera facility will arrive at some point - either by way of a future hardware upgrade, or as a peripheral. There are some practical challenges there, but if they can be overcome I suspect they will. As for Flash, that's another story.<a href="http://forums.macrumors.com/showpost.php?p=9160578&postcount=287"> I'm with the camp that hopes it doesn't get it</a>. There is plenty of <a href="http://daringfireball.net/2010/01/apple_adobe_flash">good discussion of why that should be the case around already</a>. Whether you agree with that or not, and whether Apple does eventually allow Flash or not, I think is irrelevant to whether this device will change the way we think about computing in the future.
</p>

<p>
Some great articles and <a href="http://speirs.org/blog/2010/1/29/future-shock.html">blog posts</a> have been written already about why the iPad really is a revolutionary new device. I think I can summarise them in one sentence: 
</p>

<blockquote>The iPad takes the tasks we use personal computers and the internet for the most and packages them into a focused, polished, device with an interaction method that <strong>gets out of the way</strong>.</blockquote>

<p>To add a couple more sentences to that: It does this by removing the need to know about mice and windows and multi-tasking and file systems and cables and hard drives and memory and even, to some extent, physical keyboards! Not that those things are gone forever - just that, for most tasks - tasks that even us technically-savvy power users perform much of the time - they are just a distraction! They are, or were, the <em>means</em> not the <em>end</em>. The iPad gets you to what you were trying to achieve more directly than any device before. If this is not what you wanted that's fine. That doesn't mean this device won't change the way many - perhaps most - people interact with and think about computers forever.
</p>

<p>
But that hasn't answered the question of what can we use the iPad for <em>right away</em>? Well, even assuming there are no additional game-changing apps available on launch (remember that's still 2-3 months away) there are still some very worthwhile apps bundled with the device, or available on the app store (including Apple's own iWork suite). While none of these are conceptually revolutionary, the ways you interact with them, and when you can use them, may well be. Here are some of the things I can see myself doing that currently would be either impossible or a different quality of experience:</p>

<ul>
<li>
Reading on the train. The laptop is not always possible - iPhone too small for sustained reading
</li>
<li>
Reading/ watching video at the gym
</li>
<li>
Browsing maps. Especially when planning future or reflecting on earlier travel. Looks like such a better experience than a laptop.
</li>
<li>
Picture frame in my office. I was planning on getting one anyway - this will save me the cost and looks better than most, if not all, dedicated devices anyway.
</li>
<li>
Task management. It's been great having GTD apps like <a href="http://culturedcode.com/things/iphone/">Things</a> with me all the time on my iPhone, but they still suck for data entry or big re-orgs - so I usually have to wait until I have access to my laptop - by which time I often have forgotten (which was why I was using them in the first place!). I'm confident that at least once such app will be available on, or shortly after launch. If not the existing iPhone versions, in pixel doubled mode, will still be more usable just be dint of a larger keyboard.
</li>
<li>
I'm hoping that the <a href="http://www.apple.com/itunes/remote/">Remote app</a> for controlling iTunes will soon be updated with an iPad UI as that will be an awesome way to control my household media
</li>
<li>
Showing photos. When family visit it's been great that we can browse photos on the TV or a laptop - but this will be a far more natural and intimate experience.
</li>
<li>
Playing <a href="http://www.vconqr.com">vConqr</a>. No seriously - it's going to be great! :-)
</li>
<li>
Of course casual browsing, email contacts and calendar when I'm away from my laptop - or even instead of using the laptop for such things. That way I keep my workspace a little tidier. Obviously I'll still do serious web-browsing on the laptop (if only because of multiple-tabs and copy-and-paste into my other desk-top apps).
</li>
</ul>

<p>
I should point out that I consider myself very much a power-user of my laptop/ desktop computers. I have my laptop (a Macbook Pro) connected to a 30" display and still use Spaces to give me more workspace area! As a developer and technologist this will alway be my primary computing experience, but I still see myself using the iPad for more and more tasks too - and not just when I'm on the move. For many people I can see it being their <em>primary</em>, and at some point <em>only</em>, computing device (for now, at least, it seems the iPad still needs to sync against a general purpose computer but the need for that seems to be decreasing).
</p>

<p>
I started to write about multi-tasking here too, but realised I had a lot of material that diverges from this post, so I've moved it into its own article, which I'll post a bit later.
</p>

<technoratiTags>
<!-- Technorati Tags Start -->
<p>Technorati Tags:
<a href="http://technorati.com/tag/iPhone" rel="tag">iPhone</a>, <a href="http://technorati.com/tag/iPad" rel="tag">iPad</a>, <a href="http://technorati.com/tag/Apple" rel="tag">Apple</a>, <a href="http://technorati.com/tag/Tablet" rel="tag">Tablet</a>
</p>
<!-- Technorati Tags End -->
</technoratiTags>]]></content:encoded></rss:item><rss:item rdf:about="http://www.levelofindirection.com/journal/2010/1/27/what-is-the-ipad-for.html"><rss:title>What is the iPad for?</rss:title><rss:link>http://www.levelofindirection.com/journal/2010/1/27/what-is-the-ipad-for.html</rss:link><dc:creator>Phil Nash</dc:creator><dc:date>2010-01-27T22:08:02Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[<div style="text-align:center;"><img src="http://www.levelofindirection.com/resource/-?fileId=5532724" alt="iPad.png" border="0" width="570" height="690" /></div>
<p>
So Apple's fabled Tablet, the iPad, has finally been unveiled. While many of the rumours turned out to be spot on, at least as many more missed the mark. Inevitably there will be a section of the community who feel disappointed with the reality. After all no single device could live up to every expectation. I mean it doesn't even have sharks with frickin' lasers!
</p>
<p>
However, while Apple have made clear what they think this device is initially going to be used for I think ultimately it's going to be the developer community that proves whether this really is a new device category. Can you imagine the iPhone now still being just a phone that does email, music and internet? Certainly they are still very much core to the iPhone experience, but what really sets the iPhone apart are the apps that have taken it in directions that Apple would never even have thought of. Of course Apple know that too and have already released a new SDK for developers.
</p>
<p>
This is what makes this time especially exciting to me, as I am part of that developer community. I have one iPhone app out there at the moment, <a href="http://www.vconqr.com">vConqr</a>, a turns-based strategy game somewhat based on the board game, <a href="http://en.wikipedia.org/wiki/Risk_%28game%29">Risk</a>. vConqr should work quite nicely on the new device as is, and of course I have plans to tweak it to take advantage of the new form factor and features. But I have other apps in the pipeline, including one idea that I have been brewing for about five years now. In fact, back in 2005 I was shopping around for tablet computers, looking for a platform to do my app idea justice, but I never found anything compelling. I had initially planned to write a desktop version, which I did start work on, and when the iPhone came out I put it on my queue for an iPhone version. But when I started hearing that rumours of an Apple tablet device where gaining momentum I realised this could be the ideal home platform. Today's unveiling has turned that hope into reality and I can confirm that I am now fully committed to bringing this product to market.
</p>
<p>
I hope you'll forgive me for not describing exactly what my idea entails just yet, although I have mentioned it to some people in the past. I'll go as far as saying that it is a productivity app that is largely a synergy of two existing app concepts - both of which I fully expect to see numerous implementations of becoming available, individually, for the tablet (as, indeed, they already are for the iPhone). My offering would not simply be a tool that provided both functions - or even a way of seamlessly switching between the two. I believe the integration of the two concepts leads to a sum that is greater than its parts, and throwing in some extra factors (think "cloud") leads to something that, for the last five years, I've wished I already had almost daily and I'm very excited about finally following through on.
</p>
<p>
Of course, I'm not suggesting that my app will be the saviour of the iPad! In context my point is that, as a developer, I have ideas for this device that would not work so well on any other platform yet. I'm sure I'm not the only one. What the iPad ultimately becomes associated with is something that will not fully emerge until time has allowed the developer community to provide that answer.
</p>
<p>
As I start to work on <a href="http://www.twobluecubes.com">Two Blue [Dacted]</a> I'll post a little more information - just to keep you in suspense. You can also follow me on Twitter as <a href="http://www.twitter.com/phil_nash">phil_nash</a> where I may say more from time to time.
</p>

<technoratiTags>
<!-- Technorati Tags Start -->
<p>Technorati Tags:
<a href="http://technorati.com/tag/iPhone" rel="tag">iPhone</a>, <a href="http://technorati.com/tag/iPad" rel="tag">iPad</a>, <a href="http://technorati.com/tag/Apple" rel="tag">Apple</a>, <a href="http://technorati.com/tag/Tablet" rel="tag">Tablet</a>
</p>
<!-- Technorati Tags End -->
</technoratiTags>
]]></content:encoded></rss:item><rss:item rdf:about="http://www.levelofindirection.com/journal/2009/11/11/code-formatting-in-c-part-three.html"><rss:title>Code formatting in C++ Part Three</rss:title><rss:link>http://www.levelofindirection.com/journal/2009/11/11/code-formatting-in-c-part-three.html</rss:link><dc:creator>Phil Nash</dc:creator><dc:date>2009-11-11T21:30:29Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[<p>
In this article I am going to present my recommendation for a C++ code formatting style (although it applies to most free-formatted languages, especially those that are C/C++ like).
</p>

<p>
I have covered the background to most of my choices in some detail (some would say too much - but I invoke <a href="http://www.quotationspage.com/quote/26931.html">Blaise Pascal</a> here) in the first two articles of this series, the rather consistently named:
</p>

<blockquote><a href="http://www.levelofindirection.com/journal/2009/9/24/code-formatting-in-c-part-one.html">Code formatting in C++ Part One</a></blockquote>
<blockquote><a href="http://www.levelofindirection.com/journal/2009/10/5/code-formatting-in-c-part-two.html">Code formatting in C++ Part Two</a></blockquote>

Since the style I am about to present is a little unusual in places, and arbitrary in others, I encourage you to take a look a the previous articles if you have not already done so. Also, where arbitrary looking numbers are used, follow the spirit of the rule rather than the letter (or, in this case, number).

<h3>Page width</h3>
<p>
The proposals below refer often to page width, and by this I mean the number of characters that you would normally expect to be visible while reading and writing code in an editor. For example, it used to be common to keep within 80 characters (or less) due to text mode screen sizes. These days windows can easily be sized to much greater character widths, but I would still recommend adopting a page width of between 80-100 characters. It is not a hard limit, although it is more important in some areas than others. Personally I still try to stick to 80.
</p>

<h2>Proposal 1: Formatting variable declaration blocks</h2>

<pre class="prettyprint">
char*          txt = "hello";
int            i = 7;
std::string    txt2 = "world";
std::vector&lt;std::string>            v;
std::map&lt;std::string, std::string>  m;
</pre>

<p>
Variable declarations should be grouped together where possible (without violating the principle of locality - ie, keeping them close to first use) in "islands" of no more than 16 lines at a time. If there are more than 16 variable declarations in a group then use single lines of whitespace to break them up. Try to keep variables of similar length in the same block.
</p>

<p>
Within each block, align the variable names as much as possible. Where there is a large variation in type name length, sub-group longer names and shorter names together and align variable names in sub-group blocks instead (note how the vector and map, above, are separated out this way)
</p>

This proposal applies both in function body code and within class declarations (and at global scope, if you must).

<h2>Proposal 2: Formatting function signatures</h2>

Function signatures come in two forms, and we make a distinction here. The first form is the prototype, usually found in a header file, if at all. The second form is part of the definition and is followed by the function body (if applying this to a language without the separate prototype stage, the first form does not exist, of course). We shall start with that:

<h3>Function definition signatures</h3>

<pre class="prettyprint">
////////////////////////////////////////////////////////////////////////////////
void ClassName::MethodName
(
	char*          txt = "hello",
	int            i = 7,
	std::string    txt2 = "world",
	std::vector&lt;std::string>            v,
	std::map&lt;std::string, std::string>  m
)
const
{
	// ... method body
}
</pre>

<p>The example here is for a method of a class, but the formatting would be the same for a free function</p>

<p>The return value and function or method name (along with any modifier prefixes - e.g. static, or namespace prefixes)  appear on their own line.<br />
Next are the parentheses - both of which appear on their own line - indented to the same level as the preceding line.<br />
Within the parentheses, each on their own lines, are the arguments - formatted according to Proposal 1. Any post-fix modifiers (just const, in this case) appear on their own line, followed by the function or method body.
</p>
<p>This is almost certainly the most controversial proposal and I will take up my additional rationale in the next article</p>
<p>
If a comment block does not already precede the signature, use a line of forward slashes for about a page width (e.g. I run them up to the 80th column).
</p>
<p>An additional point worth mentioning here is that this style lends itself well to being used with the Doxygen "inline comment" method of documenting function and method arguments.
</p>

<h3>Function prototype signatures</h3>

<pre class="prettyprint">
void MethodName
	(	char*          txt,
		int            i,
		std::string    txt2,
		std::vector&lt;std::string>            v,
		std::map&lt;std::string, std::string>  m ) const;
</pre>

<p>
If a separate prototype is required there are some differences to the formatting. This might seem a little odd but I'll provide the rationale in the following article.
</p>
<p>
First, the parentheses appear in-line with the arguments block, rather than on their own lines. Furthermore the whole block itself is indented with respect to the function name. Finally, any post-fix modifiers (which may include the pure virtual marker here) appear on the same line as the closing parenthesis.</p>
<p>
Note that no line of comment characters precedes the signature. Ideally functions and methods would be fully documented at the implementation site and the documentation extracted from comments using a tool such as Doxygen. There are reasons to consider keeping the prototypes clear of too many comments, but obviously you can put them here if you are sure that is best for you
</p>

<h2>Proposal 3: Function calls</h2>
If a function call fits within a normal page width then write it on one line. Long lines should be split across lines according to one of the following two examples:

<pre class="prettyprint">
LongMethodCall1( "some text",
                  aString,
                  anInt,
                  anotherArgument );
</pre>

<pre class="prettyprint">
string returnVal = ReallyLongMethodNameCall
		( "some text",
		  aString,
		  anInt,
		  anotherArgument );
</pre>

<p>
In both cases the arguments are aligned, one line each, with parentheses on the first and last lines. The first line should share the line with the function or method name itself, unless that would push the argument list across such that any of the arguments end up beyond the page width
</p>

<h2>General Principles</h2>

<p>
The proposals above are deliberately narrow in focus, concentrating on those areas that are often left out of standards, or not sufficiently described, and where using an ad-hoc approach is often less than satisfactory. However there are some simple emergent themes that can be carried through to other areas of code:
</p>
<ul>
<li>
Types and identifier names are separated into columns through alignment
</li>
<li>
Code is kept within a page width where possible. This is especially significant for code that you need to refer to at a glance, such as function prototypes - and is often where it is most overlooked!
</li>
<li>
For "structural" code, such as function signatures, consistency is especially important, even in places where it <em>seems</em> unnecessary (e.g. splitting short function signatures across multiple lines - even empty constructors). For implementation code the choice of when to split can be guided by the page width.
</li>
</ul>

<p>
I have made some recommendations in these proposals that are not specifically backed by the discussion in the previous articles. I will attempt to cover these in the next, and final, article in this series.
</p>]]></content:encoded></rss:item><rss:item rdf:about="http://www.levelofindirection.com/journal/2009/11/4/apples-magic-mouse-just-sleight-of-hand.html"><rss:title>Apple's "Magic Mouse" - just sleight of hand?</rss:title><rss:link>http://www.levelofindirection.com/journal/2009/11/4/apples-magic-mouse-just-sleight-of-hand.html</rss:link><dc:creator>Phil Nash</dc:creator><dc:date>2009-11-04T08:09:56Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[<div style="text-align:center;"><img src="http://images.apple.com/magicmouse/images/hero_1_20091020.jpg" alt="Magic Mouse" border="0" width="504" />
</div>

<p>
Apple recently released their latest mouse. It's a smooth, minimal design, connected via bluetooth, but of particular significance it claims to be "the world's first Multi-Touch mouse". But how good is it in practice. Do the multi-touch features enhance usability? Does it break Apple's curse when it comes to mouse designs (historically they tend to suck)?</p>

<p>There are many reviews of the Magic Mouse springing up over the internet already - on both professional and personal sites, as you would expect. However using a mouse is such a subjective experience that I feel there is still some value in presenting my own experience so far with it. Not least becausea fair amount of controversy surrounds it</p>

<h2>One button to rule them all</h2>

<p>
Apple are often criticised, if not ridiculed, for only supporting a single mouse button. In fact that is not true and Macs have supported multi-button mice <a href="http://www.gearlive.com/index.php/news/article/why-apple-makes-a-one-buttoned-mouse-01280820/">by default since at least the mid-90s</a>, and <a href="http://en.wikipedia.org/wiki/Mouse_%28computing%29#One.2C_two.2C_three_or_more_buttons.3F">through third-party drivers since long before then</a>. What they have continued to do until only relatively recently is to ship with only a single button mouse, and advocate that all features should be accessible with only the single button.
</p>
<p>In 2005 Apple released the <a href="http://en.wikipedia.org/wiki/Apple_Mighty_Mouse">Mighty Mouse</a>, first in wired form, then a year later with a Bluetooth variant. This added not just one extra button - but three (for a total of four)! Unfortunately this mouse had problems - most notably in the very area that it appeared to have finally caught up in! To perform a right click you had to lift your left finger, or else the click was interpreted as a left click! There were also <a href="http://en.wikipedia.org/wiki/Apple_Mighty_Mouse#Criticism">other criticisms</a>, such as the ball clogging with dirt frequently.</p>
<p>
Since it was Apple who first popularised the use of a mouse for personal computing, it seems odd that for many years now most discerning Mac users eschew Apple's own mice for third-party devices - usually Logitech. Originally the main reason was the lack of extra buttons, but more recently the implementation of multiple buttons has been badly executed. So the release of the Magic Mouse has been met with much hope that Apple have finally got it right - but have they?
</p>

<h2>Almost but not quite</h2>

<p>
Sadly the right-click problem is still there. If your left finger is touching the mouse during a right click then a left click event is fired. If, having read this you are ready to give up in disgust, please read on. Personally I have found this to be not as much of an issue as I thought it would be, and by getting past this sticking point I have been able to enjoy the nicer features this new device has to offer.
</p>
<p>
First, the <a href="http://en.wikipedia.org/wiki/Unique_selling_proposition">USP</a> for the new mouse is its multi-touch ability. Now this is not as fully featured as an iPhone screen, or the newest Macbook Pro/Air trackpads, but since this is in addition to traditional mouse features it's a good first step. At it's most basic it replaces the scroll-ball of the Mighty Mouse, offering full 360 degree scrolling by dragging or flicking (just like on an iPhone screen). Scroll-ball diehards fail to see what the fuss is about, but if you've never liked scroll-balls much, and if you're already used to the iPhone way of doing things, this new surface is very nice indeed. In addition to basic scrolling a two finger swipe left or right invokes the back and forward buttons of a browser, respectively. These gestures are a little more awkward at first, but are still useable. It would have been nice if pinch-to-zoom had been available too, but I suspect that would require a more advanced touch surface to work reliably. 
</p>

<h2>Size matters</h2>
<p>
What about the form factor. This is another highly individual area. If you're used to the ergonomic styles of many of the Logitech mice, which fill the cup of your hand, you may find the Magic Mouse to be small and cramped. Moving from such a Logitech device myself I did notice the difference, but don't find it a problem. I think the differentiating factor is how long you tend to be tied to the mouse. I can imagine that if you are a graphics designer, or someone who spends the majority of their time with their hand on the mouse, the advantage of an ergonomic design become significant. As a developer I'm generally more keyboard oriented. Switching from mouse to keyboard frequently, if anything, is easier with the smaller design as I only tend to touch the mouse with my finger-tips.
</p>
<p>
Despite being much smaller than my Logitech, the Magic Mouse is roughly the same weight. This is not unusual since the Logitech I have is a wired mouse. As a wireless device, the Magic is probably at the lighter end of the spectrum - but not so light that it feels flimsy. The weight seems just about right - any lighter and the multi-touch gestures would likely knock the mouse around.
</p>

<h2>Batteries included</h2>

<p>
Another criticism of the Magic Mouse is that it takes AA batteries, with no integral charging facility. Obviously rechargeable batteries can be used but then it is up to you to take them out and charge them separately. For a mouse with this form factor I think it would be tricky to get the charging circuitry in too - but I could be wrong.
It remains to be seen whether this is a real issue or not. I've had battery powered mice before they've been a minor inconvenience, but then so have those with their own chargers - remembering to dock them all the time. Again this is a very subjective experience
</p>

<h2>Magic or curse?</h2>

<p>
So is this the Apple mouse that's finally worth getting? Well it seems this question is tougher to answer than before. It still has the right-click problem, and it has a number of other possible downsides too. However the extent and merits of each are highly subjective, and you may be surprised yourself at the experience. Therefore the only conclusion is to try it for yourself. Fortunately they are readily available for testing out in Apple stores around the world. 
</p>
</p>Personally I'm really enjoying the experience. The scrolling works well and it feels good for my usage patterns. The right-click problem is less of an issue than I thought it would be. Your Magic May Vary.</p>]]></content:encoded></rss:item><rss:item rdf:about="http://www.levelofindirection.com/journal/2009/10/31/devdays-slides.html"><rss:title>DevDays slides</rss:title><rss:link>http://www.levelofindirection.com/journal/2009/10/31/devdays-slides.html</rss:link><dc:creator>Phil Nash</dc:creator><dc:date>2009-10-31T17:13:15Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[
<a href="http://www.levelofindirection.com/storage/docs/Stackoverflow%20DevDays%20London%20-%20iPhone%20Dev.pdf">
<div style="text-align:center;"><img src="http://www.levelofindirection.com/resource/-?fileId=4615948" alt="titlepage.png" border="0" width="504" height="377" />
</div>
</a>

<p>
I have <a href="http://www.levelofindirection.com/storage/docs/Stackoverflow%20DevDays%20London%20-%20iPhone%20Dev.pdf">sanitised (as pdf) and uploaded the slides</a> from <a href="http://www.levelofindirection.com/journal/2009/10/29/stackoverflow-devdays-london.html">my devdays presentation on iPhone development</a>. Enjoy.
</p>

<div class="technoratiTags">
<!-- Technorati Tags Start -->
<p>Technorati Tags:
<a href="http://technorati.com/tag/Conference" rel="tag">Conference</a>, <a href="http://technorati.com/tag/DevDays" rel="tag">DevDays</a>, <a href="http://technorati.com/tag/iPhone" rel="tag">iPhone</a>, <a href="http://technorati.com/tag/Objective-C" rel="tag">Objective-C</a>, <a href="http://technorati.com/tag/Stackoverflow" rel="tag">Stackoverflow</a>
</p>
<!-- Technorati Tags End -->
</div>]]></content:encoded></rss:item><rss:item rdf:about="http://www.levelofindirection.com/journal/2009/10/29/stackoverflow-devdays-london.html"><rss:title>Stackoverflow DevDays London</rss:title><rss:link>http://www.levelofindirection.com/journal/2009/10/29/stackoverflow-devdays-london.html</rss:link><dc:creator>Phil Nash</dc:creator><dc:date>2009-10-30T08:43:22Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[<p>
Yesterday I attended, and presented at, the <a href="http://stackoverflow.carsonified.com/events/london/">Stackoverflow London DevDays event</a>.
</p>

<p>
For various reasons I missed a chunk of the conference, and as my mind was on my own presentation I wasn't quite as attentive to the rest as I would normally like to be. 
</p>

<p>
Nonetheless the highlight for me, and I think most attendees, was <a href="http://stackoverflow.com/users/22656/jon-skeet">Jon Skeet's</a> entertaining, yet thought-provoking, foray into how we can't even get the most fundamental aspects of software right: numbers, text and dates - all accompanied by a <a href="http://www.flickr.com/photos/dafydd_ll_rees/4054084898/">sock puppet called Tony</a>. I also enjoyed <a href="http://icant.co.uk/">Christian Heilmann's</a> coverage of the Yahoo YUI web toolkit, and especially the little known <a href="http://developer.yahoo.com/yql/">YQL</a>. From the <a href="http://twitter.com/#search?q=%23devdays">twitter back-chat</a> it seems I am not alone in both being blown away by YQL and not having heard of it before!
</p>

<h2>Divided Opinions</h2>

<p>
As for my own presentation, one of the points I brought out was that people tend to either love or hate Objective-C.
</p>

<div style="text-align:center;"><img src="http://www.levelofindirection.com/resource/-?fileId=4593824" alt="Objective-C as Marmite" border="0" width="398" height="346" /></div>
<br />
<p>
It seems this dichotomy extended to my presentation as well, so I feel it's worthwhile to fill in here some of the things I had to leave out of the talk. Trying to fit an introduction to an "alien" language, a sampling of the SDK, and a coding demo into a 50 minute presentation was always going to be a challenge. Some things had to go. A lot had to go! In the end it was a case of following the adage, adopted by the iPhone community, of <em>do just one thing but do it well</em>. At least the first part worked out.
</p>

<h2>Why the focus on Objective-C?</h2>

<p>
There is more to iPhone development than Objective-C. Even if you leave <a href="http://monotouch.net/">Monotouch</a> out, the bulk of what you need to learn is actually the libraries and platform. Then there's the IDE, Interface Builder (more on that in a moment), the headache of submitting your application to Apple, the review process etc etc.
</p>

<p>
However, these are all things you can readily read about on the internet or in books. In the case of the libraries learning them is actually pretty easy - it just takes the time to read the docs. Knowing what to look for takes a bit more effort, but even that is usually just a case of googling around. So the value of trying to cover just a fraction of that in the time allotted is questionable. I did try to show a little of XCode and the APIs in my code demo - just enough, I hope, to show that you can get a lot done with a few lines of descriptive code.
</p>

<p>
But here's the bigger problem: just to be able to demo those few lines of code I needed to explain enough the syntax of Objective-C for the demo to make sense. Learning Objective-C for the first time is not easy <em>right at the start</em>, but that's exactly where I needed to be!
</p>

<p>
So for my 10 minute code demo to make sense, all the slides preceding that were the minimum that seemed necessary just to get to that point. Just writing the code and hoping people will follow it wouldn't cut it!
</p>

<p>
But why use Objective-C at all? With Monotouch gaining traction - and just the day before the presentation getting full debugger support - isn't it easier to just use that? Well, I'm not entirely qualified to answer that as I have yet to try it for myself - but it certainly <em>looks</em> very good. In the U.S. my counterpart for the iPhone sessions was <a href="http://blog.orenblog.org/2009/10/21/devdays-rory-blyth-on-developing-iphone-apps/">Rory Blyth</a> and he seems to be all over Monotouch.
</p>

<p>
In my presentation I brought out a few points that I believe show that at least a basic understanding of Objective-C is necessary to be an effective iPhone developer - for now, anyway. From what I have heard Rory made similar points in his presentations. They are:
</p>

<ul>
<li>Documentation - all Apple docs for the iPhone APIs (except those that are pure C APIs) describe the Objective-C usage.</li>
<li>Books and web articles - similarly the majority of these also assume Objective-C</li>
<li>Debugging - this was an obstacle, but, as mentioned, has now been addressed in the latest release. Again I do not have first hand experience</li>
<li>Not all the APIs have been exposed to Monotouch yet, although it's getting pretty darn close. Notably <a href="http://en.wikipedia.org/wiki/Core_Data">Core-Data</a> is currently missing and there are <a href="http://monotouch.net/Documentation/Limitations">other limitations</a> that may or may not be of relevance</li>
</ul>

<p>
Of course all of these will change, although - as with Mono itself - there will always be a certain amount of catch-up as the raw APIs evolve.
</p>

<p>
Another potential obstacle is that Monotouch has a <a href="http://monotouch.net/Store">price associated with it</a>. It's not an unreasonable price, but it may put off those just looking to casually tinker with it. One point that I forgot to mention in the talk (there were a few - due to technical difficulties I did not have access to my notes) was that, even with Monotouch you still need to be running on a Mac! One or two Twitter comments seemed to imply otherwise so it's worth clearing that up. Also, to run on the device or submit to the app store you still need to join Apple's developer programmer at the same cost (<a href="http://developer.apple.com/iphone/program/">$99/ year for a non enterprise membership</a>). Therefore the cost of Monotouch really is an additional cost.
</p>

<p>
So the premise of my presentation was that, if you still want to pursue iPhone development, whether or not you plan to use Monotouch at some point, you'll need some Objective-C fundamentals and that has a steep initial learning curve. I attempted to temper that by observing that the curve flattens out quite quickly the other side, and that the iPhone APIs are quite sensible, easy to use, and fairly self-documenting (even if this leads to quite a verbose naming style at times).
</p>

<h2>What I wasn't saying</h2>

<p>
As often happens when you put yourself out there, some of my motivations appear to have been misconstrued. I did not give this presentation to try and convince anyone to take up iPhone development, nor to dissuade them from doing so. If some have decided that, having seen Objective-C, they want nothing to with it, then hopefully that just means that I saved them some time, rather than doing them any injustice.
</p>

<p>
My objective (pun partly intended) was really to say that, if you have already decided that you want to have a go at developing for the iPhone, don't be too put off by the initial difficulty - it gets much easier. Beyond that I hope that I clarified some things. If you never intended to do it in the first place I believe it's always beneficial to look at other ways of doing things - regardless of whether you consider them to be better or worse. <a href="http://www.joelonsoftware.com/items/2009/05/12.html">That was the theme of the conference, after all</a>.
</p>

<h2>Why didn't I show Interface Builder</h2>

<p>
This was probably the number one question posed to me directly, or on Twitter. For this I have two answers. Whether they are good answers I make no claim to:
</p>

<ol>
<li>My focus, as I've said, was on Objective-C. Having gone to some lengths to try to give an accessible crash course in the language basics in a small amount of time it didn't seem logical to then almost completely ignore it and use a GUI builder tool. Several people posted on twitter that my demo would have been simpler if I'd used Interface Builder to do it That may or may not be true but that wouldn't have supported what I was trying to do. I do concede that I should have pointed out, at least, that it <em>could</em> have been done using IB.</li>
<li><a href="http://blog.shinetech.com/?p=195">Not everyone thinks that Interface Builder is worth using for building iPhone apps</a>. Personally I think it's fine for some things, if you're already familiar with it. For many tasks, especially if you'll have to customise the controls a lot anyway, it can add as much complexity as it removes. That is all IMHO, of course, and others are welcome to disagree with it - as they will. My purpose here is just to explain my own motivation in largely excluding it from the presentation</li>
</ol>

<h2>Was it really that bad?</h2>

<div style="text-align:center;"><img src="http://www.levelofindirection.com/resource/-?fileId=4600701" alt="Krusty.jpg" border="0" width="400" height="291" /></div>

<p>
If you didn't see my presentation you may conclude from the above that the whole thing was a disaster! Actually I was pleasantly surprised at the volume of positive chatter on the Twitter back-channel, as well as from people who approached me personally. Obviously I was pleased that they enjoyed the session and that I didn't completely suck, but more than that I was pleased that what I set out to do did reach a good number of people. Thanks to everyone that gave me feedback, good and bad, directly and indirectly. This has certainly been a challenge and I've enjoyed the opportunity of helping people to think along new lines.
</p>

<h2>Onwards</h2>

<p>
I know that I'll have picked up a few extra readers of this blog as a result of the conference, and that they will largely be reading it for iPhone related material. I'm not <a href="http://www.codinghorror.com/blog/archives.html">a prolific blogger</a>, but I have been posting a little more frequently of late, and intend to keep the momentum going. I don't just blog about iPhone development, however. I also cover <a href="http://www.levelofindirection.com/journal/2009/9/24/raii-and-readability-in-c.html">C#</a> and <a href="http://www.levelofindirection.com/journal/2009/9/23/code-formatting-in-c-part-one.html">C++</a> as well as <a href="http://www.levelofindirection.com/journal/2009/10/10/using-a-networked-drive-for-time-machine-backups-on-a-mac.html">more general themes</a>. See the archive links on the side for more.
</p>

<div class="technoratiTags">
<!-- Technorati Tags Start -->
<p>Technorati Tags:
<a href="http://technorati.com/tag/Conference" rel="tag">Conference</a>, <a href="http://technorati.com/tag/iPhone" rel="tag">iPhone</a>, <a href="http://technorati.com/tag/Objective-C" rel="tag">Objective-C</a>, <a href="http://technorati.com/tag/Stackoverflow" rel="tag">Stackoverflow</a>, <a href="http://technorati.com/tag/DevDays" rel="tag">DevDays</a>
</p>
<!-- Technorati Tags End -->
</div>]]></content:encoded></rss:item><rss:item rdf:about="http://www.levelofindirection.com/journal/2009/10/10/using-a-networked-drive-for-time-machine-backups-on-a-mac.html"><rss:title>Using a networked drive for Time Machine backups (on a Mac)</rss:title><rss:link>http://www.levelofindirection.com/journal/2009/10/10/using-a-networked-drive-for-time-machine-backups-on-a-mac.html</rss:link><dc:creator>Phil Nash</dc:creator><dc:date>2009-10-10T20:13:37Z</dc:date><dc:subject></dc:subject><content:encoded><![CDATA[You'll find similar information to this around the web, but I find it fiddly enough to piece together reliably, and I need it often enough, that I thought I'd blog about it. That way it at least gives <em>me</em> a single place to look. Maybe it will help others too. Much of the specifcs, especially the hdiutil command line and the ifconfig trick, I sourced from <a href="http://www.readynas.com/forum/viewtopic.php?p=87127#87127">this thread in the ReadyNAS forums</a>. Note that the advice is by no means specific to ReadyNAS drives (I have a <a href="http://www.thecus.com/products_over.php?cid=10&pid=8&set_language=english">Thecus NAS</a> myself). Many thanks to btaroli in that thread for the insight.

<h2>Time Machine</h2>
<a href="http://www.apple.com/macosx/what-is-macosx/time-machine.html">Time Machine</a> is Apple's easy-to-use backup system, baked into OS X (as of Leopard). Unfortunately it doesn't allow you to back-up to a networked drive out of the box. Enabling this ability is pretty easy. Early on there were some reliability issues - which were largely due to the fact that Time Machine created a disk image (more specifically, a <a href="http://en.wikipedia.org/wiki/Sparse_image">sparse bundle</a>) on the network drive, and this was prone to corruption if the network connection was disrupted during a backup. I don't know if all the issues here have been entirely resolved now, but it does seem more reliable. Apple's own <a href="http://www.apple.com/uk/timecapsule/">Time Capsule</a>, which has been specifically designed to work with Time Machine, uses this same method, so it is no longer an entirely unsupported technique.

<h3>Enabling Time Machine for network drives</h3>

So how do you enable backing up to network drives? Open a terminal window and paste the following in (then hit return, of course):

<pre>
defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1
</pre>

Mounted network drives will then show up in the list of destinations available for storing backups.

<h2>Getting a working disk image</h2>
Unfortunately this is not always enough. Often, after doing this, Time Machine will appear to start preparing a backup then fail with a cryptic error code. The error I have seen is:

<blockquote>
<strong>Time Machine could not complete the backup.</strong><br />
The backup disk image "/Volumes/backups-1/Wall-E.sparsebundle" could not be created (error 45).
</blockquote>
"Error 45"? What's that. If I try to create a sparse image myself in the same location I'm told, "the operation could not be completed". This is not much more helpful. If you google there are many references around to these errors - mostly in forums. Many of them are not terrible helpful, or require a lot of knowledge and/ or patience.

I still don't really know what the problem is, although I suspect it's something to do with permissions and/ or attributes. Either way the solution generally seems to be to create the sparse image manually using a command called hdiutil. If you get this right then Time Machine will think it created it and just start using it. Simple eh? Well, it's not rocket science - but it does involve piecing a few things together. The name of the sparse bundle has to be something very specific which is made up from a few pieces of information unique to your set-up. I'll now take you through how to find those pieces of information.

<h3>Finding the Computer Name</h3>

We'll start with the easy one. The computer name. Specifically this is whatever the computer is named in the Sharing preferences. So open System Preferences, select "Sharing", and copy the name from the "Computer Name" section at the top.

<h3>Finding the MAC Address</h3>

This is the physical address of your network card (not your IP address, which is a logical address. Also the term "MAC" here is nothing to do with your Mac as a computer - it stands for <a href="http://en.wikipedia.org/wiki/MAC_address">Media Access Control address</a>).

Now you have to be careful here. Most macs these days have at least two network cards! You will probably have an ethernet port (for a network cable connection) as well as wifi. You may also have a USB based device, such as a mobile broadband device.<em> Regardless of which one you use to connect to the network drive you'll be backing up to</em>, the address we need is of <em>the first network card</em> (usually the ethernet port). If this seems a bit odd at first, consider the case where you usually connect over wifi, but to do an initial backup you connect by cable. If the backup name was dependant on the network connection used this wouldn't work. The address is only used to identify your <em>computer</em>.

Anyway, it turns out there is an easy way to obtain this.

Back in the terminal window, type the following:

<pre style="white-space: normal">
ifconfig en0 | grep ether | awk '{print $2}' | sed 's/://g'
</pre>

What's that doing? The short answer is "don't worry, it works". The slightly longer answer is that ifconfig dumps all the information it has about all it's ethernet ports. The first port is called en0, so the command ifconfig en0 dumps information about just that one. The pipe character, |, is the unix instruction for sending the output of one command to the input of the next. So we send the information from en0 to "grep ether", which filters out just the lines that have the word "ether" in them - which in this case happen to be where the MAC addresses are shown. To get that line into the form we need for our filename we pipe it to another command, awk, which just picks out the second part of the string, then finally to sed, which removes the colons.

Phew.

Like I said, it just works. Trust me.

<h3>Creating the sparsebundle</h3>

Now we have the information we need to create the name of the sparsebundle. Following is the instruction you need to issue to create it. Replace the &lt;mac address> and &lt;computer name> placeholders with the information we obtained above. You may need to change the size parameter (320g here) if you have a large drive to back up. The disk image doesn't take up that space to start with, but will grow up to the size you specify here, so use it to set an upper limit. Also you will be prompted to enter your admin password (sudo runs the command as SuperUser):

<pre style="white-space: normal">
sudo hdiutil create -size 320g -type SPARSEBUNDLE -nospotlight -volname "Backup of &lt;computer_name>" -fs "Case-sensitive Journaled HFS+" -verbose ~/Desktop/&lt;computer_name>_&lt;mac address>.sparsebundle
</pre>

Note that this will create the sparsebundle on your desktop. Once there you can copy it to the desired location on your network drive (then delete from your desktop). This seems to be more reliable than creating it in place.

Once you've done that you can start Time Machine and point it at the drive where the sparsebundle resides and it will find it and start using it. If this still fails, check that the name is exactly right and that you followed all the steps above carefully.

Now sit back and relax, knowing that all your hard work is being backed up.]]></content:encoded></rss:item></rdf:RDF>