<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
        <title>Mac OS X - Blogs at Near Infinity</title>


        <link>http://www.nearinfinity.com/blogs/</link>
        <description>Employee Blogs</description>
        <language>en</language>
        <copyright>Copyright 2010</copyright>
        <lastBuildDate>Mon, 21 Sep 2009 12:45:00 -0500</lastBuildDate>
        <generator>http://www.sixapart.com/movabletype/</generator>
        <docs>http://www.rssboard.org/rss-specification</docs>
        
        <item>
            <title>Migrating Macs When You Use FileVault</title>
            <description><![CDATA[ <p>Recently I got a brand spankin new MacBook Pro (MBP) to replace my three-year-old one. One of the things I did <i>not</i> want to deal with is setting up a new computer from scratch and reconfiguring and reinstalling everything I already had on my old MBP. I have things pretty-well organized, I know where things are, and I remember when I rebuilt from scratch from Tiger to Leopard I lost a bunch of settings and such because I hadn't used any kind of migration software. Not this time. This time I wanted my new computer to essentially be my old computer, but with more memory and faster with no hassles.</p>

<p>There are a few options I considered. First, simply take a SuperDuper backup and restore directly to the new MBP. I researched this a lot, talked to people who've done this both successfully and unsuccessfully, and  talked to a Genius at the Apple store. The second option was to use the Migration Assistant to transfer from old to new. After all the research, I decided against restoring from SuperDuper for several reasons. First, it seemed to be hit or miss: some people reported success and some did not. Second, and more importantly, I was transferring from a circa August 2006 MBP, in fact one of the first revs that had the Intel chips inside, to a circa June 2009 MBP with the new trackpad and all the other updated jazz. I was mostly concerned that there could have been enough difference between the old and new computers' hardware and software drivers and that a direct restore would not contain up-to-date drivers and whatever else that could screw things up. So I chose to explore using Migration Assistant, which promised a very easy transfer of all files and settings.</p>

<p>So then I ran into the first  snag, which is that Migration Assistant does not transfer File Vault-ed user accounts, and I happen to use FileVault. Doh. So I thought, "OK no problem I'll simply turn off FileVault on the old machine first." Except that I only had about 7GB of space left on my hard drive, and turning FileVault off needs about as much free space as your home directory currently takes up. So if my home directory is currently 50GB, then I need about 50GB free. Double Doh, because I didn't have that kind of space! To solve all these problems, here is what I did, for anyone else who might be trying to do the same thing:</p>

<h3>Step 1 - Backup Original Mac</h3>

<p>Make a SuperDuper backup of the old MBP onto a portable external hard drive. (I actually made two copies on two different external hard drives, just in case something got screwed up later.) The external drive should contain plenty of space, enough so you can turn off FileVault on your home directory.</p>

<h3>Step 2 - Turn off FileVault on External Drive</h3>

<p>Restart the old Mac and boot from the SuperDuper backup. (You hold down the option key during startup to get the screen where you can choose to boot from the Mac hard drive or the SuperDuper backup on the external drive.) Note at this point you are now running Mac OS X on the external hard drive. Log into the FileVault-ed account, go to System Preferences, and turn FileVault off. (This is why you needed to make sure the external drive has enough space to turn off FileVault, since you are turing it off there, not on your Mac's hard drive!) Now go grab something to eat and/or watch a movie as this step can take a few hours depending on how much data you have.</p>

<p>Once complete, log out and shut down the external drive. You are now ready to transfer.</p>

<h3>Step 3 - Prepare for Migration Assistant on New Mac</h3>

<p>Log into your new Mac, and connect the external drive that contains the freshly un-FileVault-ed SuperDuper bootable backup of the original Mac. If you or someone else already setup a new user account on the new Mac <i>that has the same username as your old account does</i>, then create a new account with Administrator privileges (e.g. "MigrationAccount") and then delete the account that you will be transferring to. For example, if your old Mac account username was "bsmith" and the new Mac has an account with the same username, remove the "bsmith" account on the new Mac. Otherwise when you attempt the migration you might receive the following message like I did the first time I tried: "There is an existing user account with the same name as an account you are transferring." This wouldn't have been an issue, except that the option to replace the account was <i>disabled</i> and so Migration Assistant was refusing to overwrite it. Thus you should delete it first.</p>

<h3>Step 4 - Run Migration Assistant</h3>

<p>On the new Mac, run Migration Assistant and answer the questions. You'll be transferring from the external SuperDuper backup to the new Mac. The questions are easy and straightforward. Go grab something to drink or watch some TV, as it'll take a while to transfer all your old files and settings from the external drive to the new Mac. I'll just assume everything went well, because it did for me. If something went wrong, well, I don't have answers other than maybe to try, try, try again from scratch.

<h3>Step 5 - Turn FileVault Back On</h3>

<p>On the new Mac, turn FileVault on for the newly migrated account, e.g. if the "bsmith" account previously had FileVault on, then login as "bsmith" and turn on FileVault in System Preferences. Tick tock. More waiting as Mac OS X encrypts all the data in your home directory. Once this process completes, your new Mac should be pretty much the same as your old Mac, with all the same files and settings like Desktop, Screen Saver, etc. and with all your applications transferred successfully. And you are back up running with FileVault enabled.</p>

<h3>Step 6 - Secure Erase External Hard Drive</h3>

<p>At this point you have the new Mac setup with FileVault, and the old Mac still has FileVault on as well since you migrated from the external drive. But, the external drive now has unencrypted data sitting around since you turned FileVault off on it. Open up Disk Utility and do a <a href="http://support.apple.com/kb/TA24002?viewlocale=en_US">secure erase</a> of the un-FieVaulted external drive. Depending on which option you choose, e.g. "Zero Out Data", "7-Pass Erase", "35-Pass Erase", etc., the erase process can take a <i>long</i> time, as in <i>days</i>.  In other words, a 7- pass write overwrites every part of the disk 7 times to sanitize it and make recovery of the unencrypted information much harder, and takes 7 times longer than just zeroing out the data, which writes zeroes all over data on the disk.</p>

<p>I only did a zero out of the data, because I knew I was going to immediately overwrite that external drive with a new SuperDuper backup once I was done. If you need more insurance than that, a 7-pass erase confirms to the <a href="http://en.wikipedia.org/wiki/DOD_5220.22-M">DoD 5220.22-M</a> specification which is probably good enough. (Actually I started out using 7-pass erase until I saw it was going to take a day or two, and then I got a tad lazy and just did the zero out. Perhaps that is bad, but I didn't feel like waiting that long, and it's not like I have data for 100,000 employees on my hard drive in an Excel spreadsheet anyway. Just a lot of code and presentations and such, really.)</p>

<h3>Step 7 - Backup New Mac</h3>

<p>Make a fresh SuperDuper backup of the new Mac.</p>

<h3>Coda</h3>

<p>Although all the above sounds like it took a long time, the waiting and time was mostly due to having to turn FileVault off and then on and doing the secure erase.  Migration Assistant itself takes a fair amount of time but is totally worth it. Overall the entire process from start to finish on my old MBP with a 100GB hard drive containing only 7GB free space took between five and six hours, which is way less time than if I had tried to start over from scratch with the new Mac. I do wonder why Apple cannot just allow Migration Assistant to transfer accounts with FileVault enabled, because then pretty much all you'd need to do is run Migration Assistant directly, and you wouldn't need to go through all the  drama.</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/migrating_macs_when_you_use_fi.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/migrating_macs_when_you_use_fi.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Mac OS X</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">FileVault</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">Mac OS X</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">migration</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">superduper</category>
            
            <pubDate>Mon, 21 Sep 2009 12:45:00 -0500</pubDate>
        </item>
        
        <item>
            <title>Running VisualVM on a 32-bit Macbook Pro</title>
            <description><![CDATA[<p>If you want/need to run <a href="https://visualvm.dev.java.net/">VisualVM</a> on a <i>32-bit</i> Macbook Pro you'll need to do a couple of things. First, download and install Soy Latte, using <a href="http://landonf.bikemonkey.org/static/soylatte/">these instructions</a> - this gets you a Java 6 JDK/JRE on your 32-bit Macbook Pro. Second, download VisualVM and extract it wherever, e.g. /usr/local/visualvm. If you now try to run VisualVM you'll get the following error message:</p>

<pre class="prettyprint">
$ ./visualvm
./..//platform9/lib/nbexec: line 489: /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/bin/java: Bad CPU type in executable
</pre>

<p>Oops. After looking at the bin/visualvm script I noticed it is looking for an environment variable named "jdkhome." So the third step is to export an environment variable named 'jdkhome' that points to wherever you installed Soy Latte:

<pre class="prettyprint">
export jdkhome=/usr/local/soylatte16-i386-1.0.3
</pre>

<p>Now run the bin/visualvm script from the command line. Oh, almost forgot to mention that you should also have <a href="http://developer.apple.com/opensource/tools/X11.html">X11</a> installed, which it will be by default on Mac OS X Leopard. Now if all went well, you should have VisualVM up and running!</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/running_visualvm_on_a_32-bit_m.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/running_visualvm_on_a_32-bit_m.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Java</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Mac OS X</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">java</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">Mac OS X</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">macbook</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">visualvm</category>
            
            <pubDate>Wed, 01 Apr 2009 10:08:23 -0500</pubDate>
        </item>
        
        <item>
            <title>Use DNS Search Domains for Shorter URLs</title>
            <description><![CDATA[While I was reading through some Apple documentation on Bonjour I stumbled across a discussion on link-local addressing and DNS search domains. While the details of link-local addressing aren't that important here, the discussion on DNS search domains triggered a little light bulb in my brain.<div><br /></div><div>You see, DNS search domains are used as a guide to help your computer lookup an IP address when something simple like "blogs" is typed into your browser's URL. If you setup a DNS search domain of "nearinfinity.com", typing "blogs" will force your computer to first check if there's an address for "blogs.nearinfinity.com". If not it falls back to its default behavior.</div><div><br /></div><div>If you're a person that spends a lot of time on a small number of websites, you could use DNS search domains to your advantage to make navigating to those sites a snap. For instance, I just setup "nearinfinity.com" as an entry in my DNS search domains on my Mac. Simply go to the network preferences pane, click the advanced button at the bottom left, and then the DNS tab on the resulting popup.</div><div><br /></div><div><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="dns_search_domains_osx.jpg" src="http://www.nearinfinity.com/blogs/assets/jkunkle/dns_search_domains_osx.jpg" width="600" height="450" class="mt-image-none" style="" /></span></div><div><br /></div><div>So now, whenever I type "blogs" in my URL I get "blogs.nearinfinity.com". Whenever I type "support" I get "support.nearinfinity.com". I think you probably get the idea. I know I'm no genius for discovering this since it's precisely the reason for having search domains. I just never thought to use them before.</div>]]></description>
            <link>http://www.nearinfinity.com/blogs/jeff_kunkle/use_dns_search_domains_for_sho.html</link>
            <guid>http://www.nearinfinity.com/blogs/jeff_kunkle/use_dns_search_domains_for_sho.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">General</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Mac OS X</category>
            
            
            <pubDate>Sat, 24 Jan 2009 20:01:37 -0500</pubDate>
        </item>
        
        <item>
            <title>iPhone Bootcamp Summary</title>
            <description><![CDATA[ <p>So, after having actually written a blog entry covering <a href="/blogs/scott_leberknight/iphone_bootcamp_blogs.html">each day</a> of the <a href="http://www.bignerdranch.com/classes/iphone.shtml">iPhone bootcamp</a> at <a href="http://www.bignerdranch.com/">Big Nerd Ranch</a>, I thought a more broad summary would be in order. (That, and I'm sitting in the airport waiting for my flight this evening.) Anyway, the iPhone bootcamp was my second BNR class (I took the Cocoa bootcamp last April and wrote a summary blog about it <a href="/blogs/scott_leberknight/cocoa_bootcamp_at_big_nerd.html">here</a>.)</p>

<p>As with the Cocoa bootcamp, I had a great time and learned a ton about iPhone development. I met a lot of really cool and interesting people with a wide range of backgrounds and experiences. This seems to be a trend at BNR, that the people who attend are people who have a variety of knowledge and experience, and bring totally different perspectives to the class. The students who attend are also highly motivated people in general, which, when combined with excellent instruction and great lab coding exercises all week, makes for a great learning environment.</p>

<p>Another interesting thing that happens at BNR is that in this environment, you somehow don't burn out and can basically write code all day every day and many people keep at it into the night hours. I think this is due to the way the BNR classes combine short, targeted lecture with lots and lots and lots of hands-on coding. In addition, taking an afternoon hike through untouched nature really helps to refresh you and keep energy levels up. (Maybe if more companies, and the USA for that matter, encouraged this kind of thing people would actually be <i>more</i> productive rather than less.) And because of the diversity of the students, every meal combines good food with interesting conversation.</p>

<p>So, thanks to our instructors Joe and Brian for a great week of learning and to all the students for making it a great experience. Can't wait to take the OpenGL bootcamp sometime in the future.</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/iphone_bootcamp_summary.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/iphone_bootcamp_summary.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Mac OS X</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">iPhone</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">apple</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">big</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">bootcamp</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">cocoa</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">iphone</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">nerd</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">ranch</category>
            
            <pubDate>Fri, 05 Dec 2008 17:08:29 -0500</pubDate>
        </item>
        
        <item>
            <title>iPhone Bootcamp Day 5</title>
            <description><![CDATA[<p>Today is Day 5 &mdash; the final day &mdash; of the iPhone bootcamp at <a href="http://www.bignerdranch.com/">Big Nerd Ranch</a>, taught by Joe Conway. The last day of Big Nerd Ranch bootcamps are half-days so you have breakfast, have class until lunch, have lunch, and then shuttle back to the airport. Unfortunately for me my flight isn't until 7pm so I have a lot of time to write this entry!</p>

<p>See <a href="/blogs/scott_leberknight/iphone_bootcamp_blogs.html">here</a> for a list of each day's blog entries.</p>

<h3>Preferences</h3>

<p>First up on this last day of iPhone bootcamp is preferences, which allow an app to keep user settings in a centralized location. While you can store user settings yourself using a custom UI, the easiest way is to use the iPhone's built-in Settings app. The Settings app is the central location where apps can store user settings. It is also where all the other common iPhone settings are, which is convenient.</p>

<p>You work with the <code>NSUserDefaults</code> object to store app settings based on the app's bundle ID, for example <code>com.acme.MyKillerApp</code>. You'll also want to ensure you provide "factory default" settings using  the <code>registerDefaults</code> method; these settings will be used if the user has not changed anything. <code>NSUserDefaults</code> is basically a dictionary of key-value pairs, and you obtain the standard user defaults using the <code>standardUserDefaults</code> method. From that point you can write user settings using methods like <code>setObject:forKey</code>, <code>setInteger:forKey</code>, and so on, and you can remove settings using <code>removeObjectForKey</code>. Similarly, you read settings using methods like <code>objectForKey</code>, <code>integerForKey</code>, and so forth.</p>

<p>As mentioned earlier, the Settings app is a uniform way of setting preferences for all apps. Users know where to look for setting preferences for apps there. In addition, managing the settings separately from your application also saves screen real estate, which is important since the screen isn't all that big. You define the settings for your application using the Settings Bundle. This is a standard Property List. You use special property keys, such as <code>PSToggleSwitchSpecifier</code>, to define the settings for your application. The Settings app uses the Settings bundle and property list to create the settings UI for your app. For example, if you define settings for a <code>PSToggleSwitchSpecifier</code>, a <code>PSTextFieldSpecifier</code>, and a <code>PSMultiValueSpecifier</code>, the user will see a toggle switch, a text field, and a slider when she goes to edit your app's settings.</p>

<p>For the lab exercise, we modified our Random Number app (from Day 4 during the Web Services section) to have user settings for how the random numbers are generated &mdash; for example minimum number and the range of numbers. It is quite easy to add user settings to your app in the iPhone using the Settings app and bundle.</p>

<h3>Instruments</h3>

<p>Joe briefly talked about using the Instruments app to do powerful debugging, for example to detect memory leaks in your app. He then demonstrated using the Leaks tool within Instruments to track a memory leak &mdash; which he had previously introduced intentionally &mdash; in the Tile Game app. Leaks was able to pinpoint the exact line of code where a leaked object (i.e. it was not released) was allocated. This is pretty cool.</p>

<p>Joe also showed what leaks look like when they come from C code versus Objective-C code. C-code allocation leaks (i.e. allocated using <code>malloc</code>) show up in Instruments as just 'General Block' and from what I gather are probably not that fun to track down the exact cause. Leaks in Objective-C code are easier, and as I just mentioned, Leaks can show you the exact line of code where a leaked object was allocated.</p>

<h3>Networking</h3>

<p>By this time, it is getting closer to lunch, and the end of the class. Sad, I know. Anyway, probably one of the hardest and broadest topics was saved for last, given that you could spend an entire course on nothing but network programming. Anyway, on the iPhone a key concept when doing network programming is "reachability." Reachability does <i>not</i> mean that a network resource is definitely available; rather it means the resource is "not impossible" to reach. Another important thing on the iPhone is figuring out what type of connection you have, for example EDGE or 3G or Wi-Fi. You might choose to do different things based on the type of connection.</p>

<p>With the SystemConfiguration framework you can determine if the outside world is reachable, again with the caveat the "reachable" means "not impossible to reach." When coding you work with "reachability references" and "reachability flags" which describe the type of connection, for example reachable, connection required, is wide-area network, and so on.</p>

<p>We then learned a bit about <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/NetServices/Introduction.html">Bonjour</a>, which is basically a zero-configuration network service discovery mechanism that works on all platforms, has implementations in many languages, and is easy to use. For example, Bonjour makes it ridiculously easy to find printers on a network, as opposed to the way you have to do it in other operating systems. You can use Bonjour on the iPhone to discover and resolve Bonjour services. You use <code>NSNetServices</code> and <code>NSNetServiceBrowser</code> to accomplish this, and you specify a delegate to receive notifications when services appear and disappear.</p>

<p>In addition to Bonjour, you can also send and receive data over the network as you would expect. To send and receive data you can either use a C-based Core Foundation interface or use a stream-based interface with <code>CFStream</code>. You register read and write callbacks with the main iPhone run loop, which calls your functions when network events occur.</p>

<p>Network programming is really hard, since there are so many things that can go wrong and you need to deal with many if not all of them. Joe recommended that before jumping right into hardcore networking, developers should become familiar with the concepts and recommended the <a href="http://beej.us/guide/bgnet/">Beej's guide to network programming</a> as a good primer. Given that I've really only done simple socket programming in higher-level APIs like Java's, and have not really done much of it, I'll need to check that out. And so this concludes this episode of iPhone bootcamp blog, since it is now time for lunch and, sadly, the course is over!</p>

<h3>Random Thoughts</h3>

<p>This week has been a really intensive introduction to iPhone programming. We've gone from a very simple app on Day 1 and covered all kinds of things like form-based UIs and text manipulation; Core Location; Core Graphics; view transitions and Core Animation; using the iPhone camera and accelerometer; retrieving web-based data; manipulating Address Book data; setting user preferences, and finally networking and debugging using Instruments. We've basically covered an entire book's worth of content and written about 10 iPhone applications ranging from simple to not-so-simple. If you are interested in programming the iPhone, I definitely recommend checking out the <a href="http://www.bignerdranch.com/classes/iphone.shtml">iPhone bootcamp</a> at <a href="http://www.bignerdranch.com/">Big Nerd Ranch</a>. Because the OpenGL stuff we did on the iPhone was so cool, I'm thinking my next course to take might be the <a href="http://www.bignerdranch.com/classes/opengl.shtml">OpenGL bootcamp</a> but that probably won't happen until next year sometime! With my new knowledge I plan to go home and try my hand at creating a snowflake or snowstorm application that my daughters can play with. If I actually get it working maybe I'll write something about it.</p>

 ]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/iphone_bootcamp_day_5.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/iphone_bootcamp_day_5.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Mac OS X</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">iPhone</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">apple</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">big</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">bootcamp</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">cocoa</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">iphone</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">nerd</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">ranch</category>
            
            <pubDate>Fri, 05 Dec 2008 16:19:59 -0500</pubDate>
        </item>
        
        <item>
            <title>iPhone Bootcamp Day 4</title>
            <description><![CDATA[ <p>Today is Day 4 of the iPhone bootcamp at <a href="http://www.bignerdranch.com/">Big Nerd Ranch</a>, taught by Joe Conway. Unfortunately that means we are closer to the end than to the beginning.</p>

<p>See <a href="/blogs/scott_leberknight/iphone_bootcamp_blogs.html">here</a> for a list of each day's blog entries.</p>

<h3>View Transitions</h3>

<p>Since we had not completely finished up the Core Graphics lab from <a href="http://www.nearinfinity.com/blogs/page/sleberkn?entry=iphone_bootcamp_day_3">Day 3</a>, we spent the first hour completing the lab exercise, which was to build a "Tile Game" application where you take an image, split it into tiles, and the user can move the tiles around and try to arrange them in the correct way to produce the full image. Actually you don't really split the image; you use a grid of custom objects &mdash; which are a subclass of<code>UIControl</code> &mdash; and <i>translate</i> the portion of the image being split to the location in the grid where the tile is located. When a user moves the tiles around, each tile still displays its original portion of the image. So, you are using the same image but only displaying a portion of the image in each tile.</p>

<p>After completing the lab, Joe went over view transitions. View transitions allow you to easily add common animations (like the peel and flip animations you see on many iPhone apps) to your applications to create nice visual effects and a good user experience. For example, in our Tile Game app, when you move a tile it abruptly jumps from the old location to the new location with no transition of any kind. Also, when you touch the "info" button to select a new tiled-image there is no animation. It would be better to make the tiles <i>slide</i> from square to square, and to <i>flip</i> the tile over to the image selection screen. View transitions let you do this pretty easily. (Joe mentioned that later we'll be covering Core Animation which is more powerful and lets you perform all kinds of advanced animations.)</p>

<p>So, to reiterate, view transitions are meant for simple transitions like flipping, peeling, and so on. There are several "inherently animatable" properties of a <code>UIView</code>: the view frame, the view bounds, the center of the view, the transform (orientation) of the view, and the alpha (opacity) of the view. For example, to create a pulsing effect you could peform two alpha animations one after the other: the first one would transition the view from completely opaque to completely transparent, and the second animation would transition back from completely transparent to completely opaque. For the View Transition lab we used a "flip" animation to flip between views.</p>

<p>You use class methods of <code>UIView</code> to begin animations, setup view transitions, and commit the transitions. You use <code>beginAnimations</code> to begin animations. Then you define the animations using methods like <code>setAnimationDuration</code> and <code>setAnimationTransition</code>, which set the length of time over which the animation occurs and the type of animation such as peel or flip, respectively. Then you perform actions like add and remove subviews or perform transitions on any of the "inherently animatable" properties in an "animation block." To start the animations on screen you call <code>commitAnimations</code> after the animation block. This seems similar to how transactions work in a relational database, in that you begin a transaction, define what you want done, and then when satisfied you commit those "changes." Joe mentioned that Core Graphics essentially uses a hidden or offscreen view to store the actions and only shows the animations and actions when the animations are committed.</p>

<h3>Core Animation</h3>

<p>Next up: Core Animation. While view transitions are for simple animations, with Core Animation you can animate almost anything you want. The basic idea here is that when using Core Animation, the animation takes place on a <code>CALayer</code> rather than the <code>UIView</code>. There is one <code>CALayer</code> per <code>UIView</code>, and the <code>CALayer</code> is a cached copy of the content in the <code>UIView</code>. As soon as an animation begins, the <code>UIView</code> and <code>CALayer</code> are interchanged, and all drawing operations during the animation take place on the <code>CALayer</code>; in other words when an animation begins the <code>CALayer</code> becomes visible and handles drawing operations. After the animation ends the <code>UIView</code> is made visible again and the <code>CALayer</code> is no longer visible, at which point the <code>UIView</code> resumes responsibility for drawing.</p>

<p>You create animations using subclasses of <code>CAAnimation</code> and adding them to the <code>CALayer</code>. <code>CABasicAnimation</code> is the most basic form of animation: you can animate a specific property, known as a key path, to perform a linear transition from an original value to a final value. For example, using a key path of "opacity" you can transition an object from opaque to translucent, or vice versa.</p>

<p>You can also combine multiple animations using a <code> CAAnimationGroup</code>, which is itself a subclass of <code>CAAnimation</code> (hey, that's the Composite design pattern for anyone who cares anymore). You can use <code>CAKeyframeAnimation</code> to perform nonlinear animations, in which you have one or more "waypoints" during the animation. In other words, with <code>CAKeyframeAnimation</code> you define transitions for a specific attribute &mdash; such as opacity, position, and size &mdash; that have different values at the various waypoints. For example, in the Core Animation lab exercise we defined a rotation animation to "jiggle" an element in the Tile Game we created earlier to indicate that a tile cannot be moved. The "jiggle" animation uses the <code>CAKeyframeAnimation</code> to rotate a tile left, then right, then left, then right, and finally back to its original position to give the effect of it jiggling back and forth several times.</p>

<p>To finish up Core Animation, Joe covered how to use Media Timing Functions to create various effects during animations. For example, we used <code>CAMediaTimingFunctionEaseIn</code> while sliding tiles in the Tile Game. Ease-in causes the tile animation to start slowly and speed up as it approaches the final location. Finally, I should mention that, as with most iPhone APIs, you can set up a delegate to respond when an animation ends using <code>animationDidStop</code>. For example, when one animation stops you could start another one and chain several animations together.</p>

<h3>Camera</h3>

<p>After a cheeseburger and fries lunch, we learned how to use the iPhone's camera. The bad news about the camera is that you can't do much with it: you can take pictures (obviously) and you can choose photos from the photo library. The good news is that using the camera in code is really simple. You use a <code>UIImagePickerController</code>, which is a subclass of <code>UINavigationController</code>, and push it modally onto the top view controller using the <code>presentModalViewController:animated</code> method. Since it is modal, it takes over the application until the user cancels or finishes the operation. Once a user takes a picture or selects one from the photo library, <code>UIImagePickerController</code> returns the resulting image to its delegate.</p>

<p>There are two delegate methods you can implement. One is called when the user finishes picking an image and the other is called if the user cancelled the operation. The delegate method called when a user selects a picture returns the chosen image and some "editingInfo" which allows you to move and scale the image among other things. The lab exercise for the camera involved modifying the Tile Game to allow the user to take a photo which then becomes the game's tiled-image.</p>

<h3>Accelerometer</h3>

<p>The accelerometer on the iPhone is cool. It measures the G-forces on the iPhone. You use a simple, delegate-based API to handle accelerations. While the API itself is pretty simple, the math involved and thinking about the orientation of the iPhone and figuring out how to get the information you want is the hard part. But you'd kind of expect that transforming acceleration information in 3D space into information your application can use isn't exactly the easiest thing. (Or, maybe it's just that I've been doing web applications too long and don't know how to do math anymore.)</p>

<p>There is one shared instance of the accelerometer, the <code>UIAccelerometer</code> object. As you might have guessed, you use a delegate to respond to acceleration events, specifically the <code>accelerometer:didAccelerate</code> method which provides you the <code>UIAccelerometer</code> and a <code>UIAcceleration</code> object. You need to specify an update interval for the accelerometer, which determines how often the <code>accelerometer:didAccelerate</code> delegate method gets called.</p>

<p>The <code>UIAcceleration</code> object contains the measured G-force along the x, y, and z axes and a time stamp when the measurements were taken. One thing Joe mentioned is that you should not assume a base orientation of the iPhone whenever you receive acceleration events. For example, when your application starts you have no idea what the iPhone's orientation is. To do something like determine if the iPhone is being shaken along the z-axis (which is perpendicular to the screen) you can take an average of the acceleration values over a sample period and look at the standard deviation; if the value exceeds some threshold your application can decide the iPhone is being shaken and you can respond accordingly. For the lab exercise, we modified the Tile Game to use the accelerometer to slide the tiles around as the user tilts the iPhone and to randomize the tiles if the user shakes the iPhone. Pretty cool stuff!</p>

<h3>Web Services</h3>

<p>Well, I guess the fun had to end at some point. That point was when we covered Web Services, mainly because it reminded me that, no, I'm not going to be programming the iPhone next week for the project I'm on, and instead I'm going to be doing "enterprisey" and "business" stuff. Oh well, if we must, then we must.</p>

<p>Fortunately, Joe is defining web services as "XML over HTTP" and not as <a href="http://www.flickr.com/photos/psd/1428661128/">WS-Death-*</a>, though of course if you really want to reduce the fun-factor go ahead Darth. To retrieve web resources you can use <code>NSURL</code> to create a URL, <code>NSMutableURLRequest</code> to create a new request, and finally <code>NSURLConnection</code> to make the connection, send the request, and get the response. You could also use <code>NSURLConnection</code> with a delegate to do asynchronous requests, which might be better to prevent your application's UI from locking up until the request completes or times out.</p>

<p>If you have to deal with an XML response, you can use <code>NSXMLParser</code>, which is an event-based (SAX) parser. (By default there is no tree-based (DOM) parser on the iPhone, but apparently you can use <a href="http://iphonedevelopment.blogspot.com/2008/04/simplifying-libxml.html">libxml</a> to parse XML documents and get back a doubly-linked list which you can use to traverse the nodes of the document.) You give <code>NSXMLParser</code> a delegate which recieves callbacks during the parse, for example <code>parserDidStartDocument</code> and <code>parser:didStartElement:namespaceURI:qualifiedName:attributes</code>. Then it's time to kick it old school, handling the SAX events as they come in, maintaining the stack of elements you've seen, and writing logic to respond to each type of element you care about. For our Web Services lab we wrote a simple application that connected to <a href="http://www.random.org">random.org</a>, which generates random numbers based on atmospheric noise, and made a request for 10 random numbers, received the response as XHTML, extracted the numbers, and finally displayed them to the user.</p>

<h3>Address Book</h3>

<p>Last up for today was using the iPhone Address Book. There are two ways to use the address book. The first way leverages the standard iPhone Address Book UI. The second uses a lower-level C API in the AddressBook framework.</p>

<p>When you use the Address Book UI, you use the standard iPhone address book interface in your application. It allows the user to select a person or individual items like an email address or phone number. You must have a <code>UIViewController</code> and define a delegate conforming to <code>ABPeoplePickerNavigationControllerDelegate</code> protocol. You then present a modal view controller passing it a <code>ABPeoplePickerNavigationController</code> which then takes over and displays the standard iPhone address book application. You receive callbacks via delegate methods such as <code>peoplePickerNavigationController:shouldContinueAfterSelectingPerson</code> to determine what action(s) to take once a person has been chosen. You, as the caller, are responsible for removing the people picker by calling the <code>dismissModalViewControllerAnimated</code> method. We created a simple app that uses the Address Book UI during the first part of the lab exercise.</p>

<p>Next we covered the AddressBook framework, which is bare-bones, pedal-to-the-metal, C code and a low-level C API. However, you get "toll-free bridging" of certain objects meaning you can treat them as Objective-C objects, for example certain objects can be cast directly to an Objective-C <code>NSString</code>. Another thing to remember is that with the AddresBook framework there is no autorelease pool and you must call <code>CFRelease</code> on objects returned by methods that create or copy values. Why would you ever want to use the AddressBook framework over the Address Book UI? Mainly because it provides more functionality and allows you to directly access and potentially manipulate, via the API, iPhone address book data. For the second part of the Address Book lab, we used the AddressBook API to retrieve specific information, such as the mobile phone number, on selected contacts.</p>

<h3>Random Thoughts</h3>

<p>Using View Transitions and Core Animation can really spice up your apps and create really a cool user experience. (Of course you could probably also create really bad UIs as well if overused.) The camera is pretty cool, but the most fun today was using the accelerometer to respond to shaking and moving the iPhone. Web services. (Ok, that's enough on the enterprise front.) Last, using the various address book frameworks can certainly be useful in some types of applications where you need to select contacts.</p>

<p>Something in one of the labs we did today was pretty handy, namely that messages to <code>nil</code> objects are <i>ignored</i> in Objective-C. There are a lot of times this feature would be hugely useful, though I can also see how it might cause debugging certain problems to be really difficult! There's even a design pattern named the <a href="http://en.wikipedia.org/wiki/Null_Object_pattern">Null Object Pattern</a> since in languages like Java you get nasty things like null-pointer exceptions if you try to invoke methods on a <code>null</code> object.</p>

<p>Man, we really covered a lot today, and now I am sad that tomorrow is the last day of iPhone bootcamp. I should become a professional Big Nerd Ranch attendee; I think that would be a great job!</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/iphone_bootcamp_day_4.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/iphone_bootcamp_day_4.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Mac OS X</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">iPhone</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">apple</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">big</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">bootcamp</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">cocoa</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">iphone</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">nerd</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">ranch</category>
            
            <pubDate>Thu, 04 Dec 2008 23:50:00 -0500</pubDate>
        </item>
        
        <item>
            <title>iPhone Bootcamp Day 3</title>
            <description><![CDATA[ <p>Today is Day 3 of the iPhone bootcamp at <a href="http://www.bignerdranch.com/">Big Nerd Ranch</a>, taught by Joe Conway.</p>

<p>See <a href="/blogs/scott_leberknight/iphone_bootcamp_blogs.html">here</a> for a list of each day's blog entries.</p>

<h3>Media</h3>

<p>Today we started off learning how to play audio and video files by creating a simple application that allows you to play a system sound, an audio file, and a movie. If all you want to do is play .caf, .wav. or .aiff audio files tat are less than 30 seconds in length, you're in luck because you can simply use <code>AudioServicesCreateSystemSoundID</code> to register a sound with the system and then use <code>AudioServicesPlaySystemSound</code> to play the sound. On the other hand, if you want to play almost any type of audio file, you can use the <code>AVAudioPlayer</code>, which really isn't all that much more complicated. You create a <code>AVAudioPlayer</code> and then implement <code>AVAudioPlayerDelegate</code> methods like <code>audioPlayerDidFinishPlaying</code> to respond to audio player events. You simply call <code>start</code> and <code>stop</code> to control playback and you can use <code>isPlaying</code> to check playback status. Recording audio is apparently more difficult, and we didn't really cover it in lecture or lab, though the exercise book has a whole appendix devoted to creating your own voice recorder application.</p>

<p>For movie playback you can use <code>MPMoviePlayerController</code>. It is also pretty easy to use. But, one caveat is that it completely takes over your iPhone application when you call <code>play</code>, and the user has no control until the movie ends or until the user exits your application.</p>

<h3>Low Memory Warnings</h3>

<p>We next took a (very) short detour talking about low memory warnings. When your application is taking too much memory, the iPhone sends your application the <code>applicationDidReceiveMemoryWarning</code> message. In that method you are supposed to release as much memory as you possibly can. However, according to Joe, the iPhone does not really provide much information about how much memory you need to release, or how much memory will cause a low memory warning in the first place! Joe says to just release as much memory as you possibly can immediately or else the iPhone can simply terminate your application. All your <code>UIViewController</code>s are sent <code> didReceiveMemoryWarning</code>. The default implementation checks if you have implemented <code>loadView</code>, and if so releases its view instance. The next time the view needs to be shown on screen, it gets reconstructed. One last thing is that the iPhone simulator allows you to simulate a low memory warning via the "Simulate Memory Warning" option on the Hardware menu.</p>

<h3>OpenGL</h3>

<p><a href="http://www.khronos.org/opengles/">OpenGL ES</a> is the implementation of OpenGL on the iPhone. Basically it is a low-level C API that allows you to draw 2D and 3D graphics on the iPhone in various colors and textures. Triangles, lines, and points comprise the basic geometrical shapes you can use to compose graphics. When coding OpenGL ES you basically need to define all the vertices in two or three dimensional space, then define the color of each vertex, and then, via the <code>EAGLContext</code>, render the graphic. The color of a vertex is defined in RGBA8 format, which allows you to specify red, blue, green color channels and an alpha transparency channel, using 8-bits per channel. The <code>EAGLContext</code> is the bridge between Cocoa Touch and OpenGL ES, and is what allows you to use OpenGL on the iPhone.</p>

<p>When coding OpenGL ES, you use various buffers. The frame buffer describes one frame of drawing. The render buffer contains the pixels created by drawing commands sent to the frame buffer. When you draw to the screen, you really draw to a <code>CAEAGLLayer</code> object, and you use a timer to request drawing updates, e.g. schedule a timer to update the drawing 60 times per second creates a 60 frame per second rendering. Another important thing is that you must call <code>setCurrentContext</code> on the <code>EAGLContext</code> before performing any drawing commands. Last, according to Joe, OpenGL is not at all forgiving if you screw something up, for example if you have an empty buffer or mismatched vertex data in the buffer. When that occurs, your application simply crashes.</p>

<p>The lab exercise for OpenGL was to create a "Fireworks" application that randomly generates "fireworks" using OpenGL and that simulates those fireworks exploding and then burning out. Pretty cool stuff, but man is it a lot of code to just to create relatively simple things because you must fully define all the geometry and colors and then use OpenGL functions to enable various drawing states and draw the geometry. You also of course need to implement logic to change the drawing over time, for example once a firework explodes you need to define the logic to animate the particles using lots of math and even some good old physics equations to compute position, velocity, and acceleration. I bet if they taught physics by having students implement particle engines on the iPhone more people would be into science!</p>
	
<h3>Textures</h3>

<p>After various types of pizza, including a really good barbeque pizza, for lunch, we learned about using textures in OpenGL ES. You use per-pixel coloring to spread an image file across geometric primitives (triangles, points, and lines). Textures add depth to a scene and can also be used to create shadow effects and is how you draw text using OpenGL. We extended our Fireworks application by adding texture to each exploding particle. Essentially you pin an image file to your geometry. Since adding textures is still OpenGL coding, it is low level and requires a fair amount of code to define the mapping coordinates for the texture in order to pin it to the scene geometry. But the end result is pretty cool!</p>

<h3>Multi-touch Events</h3>

<p>Before getting into touch events, we took an afternoon hike. It was really nice and I wished we had done the zip lines at Banning Mills today, since it is supposed to rain tomorrow. When we got back from the hike, we plowed into how to handle touch events on the iPhone. First up, Joe told us all about <code>UIResponder</code>, which is the base class for <code>UIView</code>, <code>UIController</code>, <code>UIWindow</code>, and <code>UIApplication</code>. Because of this inheritance relationship, subclasses gain similar functionality automatically for handling the different phases for <code>UIResponser</code>. The phases of <code>UIResponser</code> are: <code>touchesBegan</code>, <code>touchesMoved</code>, and <code>touchesEnded</code>. These phases allow you to handle all kinds of touch events, including up to five simultaneous touches.</p>

<p>The <code>UITouch</code> object is what you work with when handling touches. By default, multi-touch is not enabled, so you have to enable multi-touch either in code using <code>setMultipleTouchEnabled:YES</code> or you can set the property in Interface Builder. Each of the touch callback methods, for example <code>touchesBegan</code>, sends you the touches as a set of <code>UITouch</code> objects and a <code>UIEvent</code> object. You can use the event object to determine the number of touches and respond appropriately. In the lab exercise we extended the Fireworks application to respond to single touches, touch-and-drag, and multiple-touches. When handling multiple touches you need to use math and geometry to figure out things like how far apart the touches are; in the Fireworks application we made it so the further away the touches the faster we disperse the firework particles.</p>

<h3>Core Graphics</h3>

<p>Last for today was Core Graphics, which allows drawing in Cocoa Touch. Core Graphics is much simpler to use than OpenGL but is not as powerful. It is not designed to draw super fast animations and games like OpenGL is, and according to Joe should mostly be used for UIs where you need to do drawing.</p>

<p>You use the <code>drawRect</code> method to define your drawing commands. You draw to a <code>CGContext</code> graphics context. The main iPhone run loop, not you, is responsible for creating the graphics context and calling <code>drawRect</code>; you simply need to define what to draw, not when to do it. The basic process you follow to draw is as follows. First, get a reference to a <code>CGContext</code> graphics context. Second, create a <code>CGMutablePathRef</code> path object and then draw points, lines, curves, and shapes to the path. Next, you set the color of the graphics context, and finally you stroke or fill the path object.</p>

<p>During drawing you can save and restore the state of a <code>CGContext</code>. For example, you might perform some drawing commands, then save the context state, change a few drawing attributes and perform several more drawing operations, restore the context state, and continue drawing using the original state. According to Joe, you should not save/restore state a lot or it can really slow down your application.</p>

<p>Core Graphics uses the "Painter's Method" when drawing objects on screen, meaning objects are drawn from back to front. Objects drawn later are drawn over top objects that were drawn earlier, effectively replacing the existing pixels. One other thing to mention is that, using Core Graphics, you can do 2D transforms applied to <code>CGContext</code> to perform rotation, translation, scaling, and skewing of the shapes on screen.</p>

<h3>Random Thoughts</h3>

<p>My brain is starting to hurt after three days of hardcore learning and coding. Several of us started watching the Bourne Ultimatum after dinner on the nice big flat-screen TV in the Banning Mills lodge to relax a bit.</p>

<p>OpenGL, while powerful, is not what I'd call the most fun API I've ever worked with, and it would probably take a while to learn the ins and outs and become an expert in it. Adding textures using OpenGL can really spice up your application and make it look better. Our Fireworks application went from exploding popcorn before adding texture to looking like real, exploding firework particles after the texture was added to the particles.</p>

<p>Being able to handle multi-touch events is just plain cool.</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/iphone_bootcamp_day_3.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/iphone_bootcamp_day_3.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Mac OS X</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">iPhone</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">apple</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">big</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">bootcamp</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">cocoa</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">iphone</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">nerd</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">ranch</category>
            
            <pubDate>Wed, 03 Dec 2008 23:53:00 -0500</pubDate>
        </item>
        
        <item>
            <title>iPhone Bootcamp Day 2</title>
            <description><![CDATA[ <p>Today is Day 2 of the iPhone bootcamp at <a href="http://www.bignerdranch.com/">Big Nerd Ranch</a>.</p>

<p>See <a href="/blogs/scott_leberknight/iphone_bootcamp_blogs.html">here</a> for a list of each day's blog entries.</p>

<h3>Localization</h3>

<p>After a nice french toast breakfast, we headed down to the classroom and started off learning about localizing iPhone apps. As with Cocoa, you basically have string tables, localized resources (e.g. images), and a <i>separate</i> XIB file for <i>each</i> different locale you are supporting. (Interface Builder stores the UI layout in an XML format in a XIB file, e.g. MainWindow.xib.) This means that, unlike Java Swing for example, you literally define a separate UI for each locale. We localized our DistanceTracker application that we built on day one for English and German locales. To start you use the <code>genstrings</code> command line utility to generate a localizable string resource and then in Xcode make it localizable; this creates separate string tables for each language which a translator can then edit and do the actual translation. You also need to make the XIB files localized and then redo the UI layout for each locale. Sometimes this might not be too bad, but if the locale uses, for example, a right-to-left language then you'd need to reverse the position of all the UI controls. While having to create essentially a separate UI for each locale seems a bit onerous, it makes a certain amount of sense in that for certain locales the UI might be laid out completely differently, e.g. think about the right-to-left language example. Finally, you use <code>NsLocalizedString</code> in code, which takes a string key and a comment intended for the translator which is put into the string tables for each locale - at runtime the value corresponding to the specified key is looked up based on the user's locale and is displayed. If a value isn't found, the key is displayed as-is which might be useful if you have a situation where all locales use the same string or something like that.</p>

<h3>View Controllers</h3>

<p>After localization we tackled view controllers. View controllers control a single view, and are used with <code>UITabBarController</code> and <code>UINavigationController</code>. We created a "navigation-based application" which sets up an application containing a <code>UINavigationController</code>. The difference between <code>UITabBarController</code> and <code>UINavigationController</code> is that the tab bar controller stores its views in a list and allows the user to toggle back and forth between views. For example, the "Phone" application on the iPhone has a tab bar at the bottom (which is where it is displayed in apps) containing Favorites, Recents, Contacts, Keypad, and Voicemail tab bar items. Tab bar items are always visible no matter what view is currently visible. As you click the tab bar items, the view switches. So, a <code>UITabBarController</code> is a controller for switching between views in a "horizontal" manner somewhat similar to the cover flow view in Finder. On the other hand you use <code>UINavigationController</code> for stack-based "vertical" navigation through a series of views. For example, the "Contacts" iPhone application lists your contacts; when you touch a contact, a detail view is pushed onto the <code>UINavigationController</code> stack and becomes the visible and "top" view. You can of course create applications that combine these two types of view controllers. In class we created a "To Do List" application having a tab bar with "To Do List" and "Date & Time" tabs. If you touch "To Do List" you are taken to a list of To Do items. Touching one of the To Do items pushes the To Do detail view onto the stack, which allows you to edit the item. Touching "Date & Time" on the tab bar displays the current date and time in a new view.</p>

<p>It took me a while to get my head wrapped around combining the different types of view controllers in the same application and how to connect everything together. Since I am used to web app development, this style of development requires a different way of thinking. I actually like it better since it has a better separation of concerns and is more true to the MVC pattern than web applications are, but I'm sure I'll have to try to build more apps using the various view controllers to get more comfortable.</p>

<h3>Table Views</h3>

<p>We had a good lunch and after that headed back down to cover table views. Table views are views that contain cells. Each cell contains some data that is loaded from some data source. For example, the "Contacts" application uses a <code>UITableView</code> to display all your contacts. The "To Do List" application we created earlier also uses a <code>UITableView</code> to list the To Do items. Basically, <code>UITableView</code> presents data in a list style.</p>

<p>Table views must have some data source, such as an array, a SQLite database, or a web service. You are responsible for implementing data retrieval methods so that when the table view asks for the contents of a specific cell, you need to offer up a cell containing the data appropriate for the row index. Since the iPhone has limited real estate, <code>UITableView</code> re-uses cells that have been moved off screen, for example if they are scrolled out of view. This way, rather than create new cells every single time <code>UITableView</code> asks for a cell, you instead ask if there are any cells that can be re-used. If so, you populate the cell with new data and return it.</p>

<p><code>UITableView</code> also provides some basic functionality, like the ability to drag cells, delete them, etc. You only need to implement the logic needed when events, like move or delete, occur. Another thing you typically do with table views is respond when a user touches a cell. For example, in the "To Do List" application a new "detail" view is displayed when you touch a cell in the table view. This is probably the most common usage; table views display aggregate or summary data, and you can implement "drill down" logic when a user touches a cell. For example, when a user touches a To Do item cell, a new view controller is pushed onto the stack of a <code>UINavigationController</code> showing the "detail" view and allowing you to edit the To Do item. Another cool thing you can do with table views is to subclass <code>UITableView</code> in order to lay out <i>subviews</i> in each cell. In the "To Do List" app, we added subviews to each cell to show the To Do item title, part of the longer item description in smaller font, and an image to the left of the title if the item was designated as a "permanent" item. The "Photo Albums" iPhone application also uses subviews; it shows an image representing the album and the album title in each cell.</p>

<h3>Saving and Loading Data Using SQLite</h3>

<p>By this time, it was already late afternoon, and we hiked out to the old paper mill and back. It stared getting colder on the way back as the sun started to set. When we got back, we learned all about saving and loading data using SQLite. First, we learned about the "Application Sandbox" which can only be read/written by your application, for security reasons. There are several locations that each iPhone application can store data. Within you application's bundle (e.g. &lt;AppName.app&gt;) there is Documents, Library/Preferences, Library/Caches, and tmp folders. Documents contains persistent data, such as a SQLite database, that gets backed up when you sync your iPhone. Library/Preferences contains application preference data that gets backed up when you sync. Library/Caches, which Joe and Brian (the other instructor who is helping Joe this week) just found out about before our hike, is new in version 2.2 of the iPhone software, and stores data cached between launches of your application. The tmp directory is, as you expect, used for temporary files. You as the developer are responsible for cleaning up your mess in the tmp folder, however!</p>

<p>After discussing the sandbox restrictions, we learned how you can locate the Documents directory using the <code>NSSearchPathForDirectoriesInDomains</code> function. Finally, we learned how to use SQLite to add persistence to iPhone applications using SQLite, which I continually misspell with two "L"s even though there is really only one! SQLite supports basic SQL commands like select, insert, update, and delete. The reason you need to know how to find the Documents directory is because you'll need to create a copy of a default SQLite database you ship with your application into Documents. Basically, you supply an empty database with your application's Resources &mdash; this is read-only to your app. In order to actually write new data, the database must reside in a location (such as Documents) where you have access to write. So, the first thing to do is copy the default database from Resources to the Documents directory where you can then read and write, and where the database will then automatically be backed up when the user syncs her iPhone.</p>

<p>We then added SQLite persistence to the "To Do List" application. While I think SQLite is cool in theory, actually using it to query, insert, update, and delete data is painful, as you have to handle all the details of connecting, writing and issuing basic CRUD queries, stepping through the results, closing the statements, cleaning up resources, etc. It feels like writing raw JDBC code in Java but possibly worse, if that's possible. Someone told me tonight there is supposedly some object-relational mapping library which makes working with SQLite more palatable, though I don't remember what it was called or if it is even an object-relational mapper in the same sense as say, Hibernate. Regardless, I persisted (ha, ha) and got my "To Do List" application persisting data via SQLite.</p>

<h3>WebKit</h3>

<p>Joe apparently gave a short lecture on using WebKit in iPhone applications at this point. Unfortunately I decided to go for a run and missed the lecture. In any case, WebKit is the open source rendering engine used in Safari (both desktop and mobile versions) to display web content. You use <code>UIWebView</code> in your application and get all kinds of functionality out-of-the-box for hardly any work at all. <code>UIWebView</code> takes care of all the rendering stuff including HTML, CSS, and JavaScript. You can also hook into events, such as when the web view started and finished loading, via the <code>UIWebViewDelegate</code> protocol. In our lab exercises after dinner, we implemented a simple web browser using <code>UIWebView</code> and used an activity progress indicator to indicate when a page is loading.</p>

<p>In addition to loading HMTL content in <code>UIWebView</code>, you can also load things like images and audio content. It is ridiculously easy to add a <code>UIWebView</code> to your application in order to display web content.</p>

<h3>Random Thoughts</h3>

<p>Another long day has come and gone. It is amazing how much energy everyone has to basically learn all day and keep going well into the night hours.</p>

<p>Today we learned about localization on the iPhone. The most important thing is that you need to create a separate UI for each locale you are supporting. This means you should not work on localizing until right before you are ready to ship; otherwise you'll spend all your time continually tweaking all the localized UI after every little change you make.</p>

<p>Tab and navigation view controllers are powerful ways to implement application navigation using a tab paradigm or a stack-based, guided navigation scheme, respectively. Combined with table views, you can accomplish a lot with just these three things.</p>

<p>While I think having a relational database available for persistence in your iPhone apps is nice, I really do not want to write the low-level code required to interact with SQLite; once you get used to using an ORM tool like Hibernate or ActiveRecord you really don't want to go back to hand-writing basic CRUD statements, marshaling result sets into objects and vice-versa, and managing database resource manually. Guess I'll need to check into that SQLite library someone mentioned.</p>

<p>It is surprisingly easy to integrate web content directly into an iPhone application using <code>UIWebView</code>!</p>

<p>Tomorrow looks to be really cool, covering things like media and OpenGL. Until then, ciao!</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/iphone_bootcamp_day_2.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/iphone_bootcamp_day_2.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Mac OS X</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">iPhone</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">apple</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">big</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">bootcamp</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">cocoa</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">iphone</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">nerd</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">ranch</category>
            
            <pubDate>Tue, 02 Dec 2008 23:37:00 -0500</pubDate>
        </item>
        
        <item>
            <title>iPhone Bootcamp Day 1</title>
            <description><![CDATA[<p>Today is the first day of the iPhone bootcamp at <a href="http://www.bignerdranch.com/">Big Nerd Ranch</a> at <a href="http://www.historicbanningmills.com/">Historic Banning Mills</a> B&amp;B in Whitesburg, GA. It is being taught by Joe Conway. My goal is to write a blog entry for each day of the class, so we'll see how that goes.</p>

<p>See <a href="/blogs/scott_leberknight/iphone_bootcamp_blogs.html">here</a> for a list of each day's blog entries.</p>

<h3>Simple iPhone Application</h3>

<p>We started off the course by creating a simple iPhone application using a bunch of UI controls that come out of the box. We dragged and dropped controls onto an iPhone Window application, hooked up some events in Interface Builder, and wrote a bit of event handling code. We ran the application on the simulator (i.e. not on our phones) and played around a bit with it. Cool to get something up and running in the first hour of a five day course!</p>

<h3>App Icon and Default Image</h3>

<p>After getting the initial iPhone app up and running we added an icon for the application which is what displays on the iPhone "desktop" and added a default image, the purpose of which is to "fool" the user into thinking the application launched immediately without delay. So, in other words, when an iPhone app launches, the first thing that happens is the Default.png image is displayed. Joe mentioned some people use this for so-called "splash" screens, perhaps to display a company logo or some advertising. While this is nice in theory, Joe mentioned this is about the worst thing you can do - when Apple makes the iPhone faster over time, instead of a two or three second splash screen, now you might see something flicker into and out of existence in a split second and users won't know what's going on. In any case the best thing to do is take a screenshot of your application. By the time the user gets around to actually clicking something the Default.png image will have been replaced by the actual application, and your app has the appearance of an immediate startup, which users always like.</p>

<h3>Objective-C</h3>

<p>Then it was onto a short introduction to the Objective-C language. Having attended the Cocoa bootcamp last April and read through Programming in Objective-C I was already comfortable with Objective-C. You basically learn that Objective-C is a dynamically-typed language built on top of C, adding objects and messaging, i.e. you send messages to objects. We blew through the basics of creating objects, initializing them, and creating accessors. Thankfully Objective-C 2.0 added properties which gets rid of the getter/setter method tedium. We briefly covered some of the basic classes like NSString and NSArray and NSMutableArray. After all that, it was on to memory management. Although Apple introduced a garbage collector in Mac OS Leopard, it is not available to iPhone applications and you must manage retain counts of objects manually using retain, release, and the autorelease pool. This is tedious at best, but Joe provided several concrete and relatively simple rules to follow when writing iPhone apps, which I'm not really going to delve into right now, but suffice it to say that you have to pay a lot more attention to memory issues writing iPhone apps than, say, writing web apps in a garbage-collected language like Ruby, Java, or C#. We wrote several sample applications that demonstrated Objective-C basics, counting object references, and using the autorelease pool.</p>

<h3>Using Text Controls</h3>

<p>Next up was the chapter on "text" on the iPhone, which focused on using the UITextField and UITextView controls. For this section we created an application that allowed you to search a large block of text in a UITextView for specific text typed into a text field. During this section we learned how to deal with the (virtual) keyboard and how it automatically becomes the "first responder" when a user touches a text UI control. Joe showed how the Responder Chain delegates events until some object handles it, or if no objects are interested, the event simply and silently drops off into nothingness. (For Gang of Four aficionados, this would be the Chain of Responsibility pattern. Does anyone actually care anymore?) This allows you to delegate events up a chain of objects. When an text-capable object becomes the first responder, the virtual keyboard automatically appears for the user to type something. To remove it you can write code to resign the first responder status. Last in the text section was using notifications and the notification center to observe when the keyboard is about to show (be displayed on screen) and write a log message.</p>

<h3>Delegates</h3>

<p>Even though it was cold outside (about 40 degrees Fahrenheit) we took a 30 minute hike around 3 o'clock and got refreshed. Then we continued to learn about using delegates and protocols. Basically a delegate handles certain functionality passed off to it by another object. The delegate essentially extends the functionality of an object without needing to resort to all kinds of subclassing everywhere; in other words it is a way to perform callbacks and extend functionality. For example, an XML parser knows how to parse the XML and it might send messages to a delegate object. The delegate object in this case knows what to do when it sees specific elements or attributes, while the parser remains completely generic. This enables re-use of the parser without it needing to know anything about how your application actually responds to various elements and attributes. We extended our text search application using delegates to perform the actual searching logic as well as resigning and becoming the first responder.</p>

<h3>Core Location</h3>

<p>The last, and coolest, topic today was Core Location, which is the framework that allows your iPhone to figure out where you are in the world. We wrote an application that uses your current location and tracks the distance you've traveled after you enable tracking. Since I have not actually enabled my iPhone device yet, I had to run this only on the simulator which was not quite as cool since it only reports one location (which IIRC was the lat/long of Apple's headquarters but I might have caught that wrong.) Basically you use a CLLocationManager which sends location updates to a delegate (good thing I paid attention to the section on delegates earlier); the delegate does pretty much whatever it wants to. Again, the delegate implements application-specific logic and the CLLocationManager just sends you the updated lcoation information, resulting in a clean separation of concerns. You can configure the manager for the level of accuracy you'd like, for example ten meters, a hundred meters, or "best" possible accuracy. The higher the accuracy, the faster your battery will drain, so setting this to best accuracy and leaving it on continuously might not be the best thing to do. Joe also mentioned that if you turn off the iPhone using the top button, the active application can still be doing things and so you want to make sure you check for the "application will passivate" event and stop updating the location to prevent excessive battery drainage! (Maybe that's what happened to me a few weeks ago when my full battery completely drained overnight.) You can also configure a distance filter if, for example, you only want to receive updates after the phone has moved a certain distance. Cool stuff!</p>

<h3>Provisioning Profiles</h3>

<p>After dinner we returned to the classroom to set up our provisioning profiles, which is going to allow those of us who have not yet registered with Apple to actually run apps on our iPhones (known as "devices"). I am planning to buy my developer certificate but for now Big Nerd Ranch has provisioning profiles for students since apparently it is now taking a day or two to get your developer certs and other required stuff.</p>

<h3>Random Thoughts</h3>

<p>After a long day, I have a few random thoughts in no particular order. Interface Builder is really, really nice for building UIs. Of course I already knew this having taken the <a href="http://www.bignerdranch.com/classes/cocoa.shtml">Cocoa bootcamp</a> last April. Regardless, building UIs using a sophisticated and refined tool like Interface Builder is sooooooo much nicer than the current kludge of web technologies that splatter HTML, CSS, and JavaScript all over the place and various data exchange formats like XML, JSON, or whatever combined with eight different JavaScript frameworks and a potentially very different server-side programming model and finally trying to jam it all together. Can you tell I've been doing web development for a while?</p>

<p>Delegates and Core Location were probably the coolest things from today, and it is really nice that after only one day I can build iPhone apps, even if they are pretty simple. Then again, it is really cool how easy it is to integrate location into an iPhone application. Objective-C as a language is actually not all that bad, and is really easy to read since the methods (at least the ones from the Apple SDK) tend to be very well-named. Of course I like the fact that Objective-C is dynamically typed and I don't have to be told by the compiler what I can and cannot do at every step of the way, e.g. I can send any message to any object and so long as it responds, no problem. Of course the code does still have to compile in the XCode IDE so it isn't a total dynamic language free-for-all. The thing I don't like is having to manually manage memory. After doing malloc and free in C on a VAX for the first several years out of college, I was quite happy to not have had to do that for over 10 years. Oh well, I suppose the autorelease pool and simply sending retain and release messages is better than malloc and free.</p>

<p>Big Nerd Ranch is all about coding. While there is lecture, you code hands-on most of the time, and this is why you learn so much. The hikes really relieve the tendency to want to go to sleep after lunch! It's 10:25 and I've finally got ten my iPhone provisioned and the apps we developed today all working directly on the phone. I also finally got the SDK updated to the latest version as well as update my phone's software to version 2.2. All in all a great first day!</p> ]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/iphone_bootcamp_day_1.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/iphone_bootcamp_day_1.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Mac OS X</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">iPhone</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">apple</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">big</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">bootcamp</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">cocoa</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">iphone</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">nerd</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">ranch</category>
            
            <pubDate>Mon, 01 Dec 2008 22:39:09 -0500</pubDate>
        </item>
        
        <item>
            <title>iPhone Bootcamp Blogs</title>
            <description><![CDATA[<p>Check out my blog entries this week while I'm attending the <a href="http://www.bignerdranch.com/classes/iphone.shtml">iPhone bootcamp</a> at <a href="http://www.bignerdranch.com/">Big Nerd Ranch</a>.

<ul>
<li><a href="/blogs/scott_leberknight/iphone_bootcamp_day_1.html">Day 1</a></li>
<li><a href="/blogs/scott_leberknight/iphone_bootcamp_day_2.html">Day 2</a></li>
<li><a href="/blogs/scott_leberknight/iphone_bootcamp_day_3.html">Day 3</a></li>
<li><a href="/blogs/scott_leberknight/iphone_bootcamp_day_4.html">Day 4</a></li>
<li><a href="/blogs/scott_leberknight/iphone_bootcamp_day_5.html">Day 5</a></li>
<li><a href="/blogs/scott_leberknight/iphone_bootcamp_summary.html">Summary</a></li>
</ul>]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/iphone_bootcamp_blogs.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/iphone_bootcamp_blogs.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Mac OS X</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">iPhone</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">apple</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">big</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">bootcamp</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">cocoa</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">iphone</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">nerd</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">ranch</category>
            
            <pubDate>Sun, 30 Nov 2008 00:00:00 -0500</pubDate>
        </item>
        
        <item>
            <title>Cocoa Bootcamp at Big Nerd Ranch</title>
            <description><![CDATA[<p>Last week I went to the <a href="http://www.bignerdranch.com/classes/cocoa.shtml">Cocoa Bootcamp</a> at the <a href="http://www.bignerdranch.com/">Big Nerd Ranch</a>. It was held outside Atlanta at the <a href="http://historicbanningmills.com/">Historic Banning Mills</a> country inn in Whitesburg, GA - pretty much in the woods in the middle of nowhere, which was nice because there were no distractions like when you go to training in a big city where you want to go out do things every night.</p>

<img src="http://www.sleberknight.com/blog/sleberkn/resource/IMG_0105.JPG" alt="Historic Banning Mills" title="Historic Banning Mills"/>

<p><a href="http://en.wikipedia.org/wiki/Aaron_Hillegass">Aaron Hillegass</a> taught the class and is the author of the excellent <a href="http://www.amazon.com/Cocoa-Programming-Mac-OS-3rd/dp/0321503619/">Cocoa Programming for Mac OS X</a> which was actually what we used during the class all week. The bottom line for me was that this was the best training class I've ever attended. It was basically one week of intense learning and writing (lots and lots and lots of) code, as the class was way more hands-on than any other training I've attended. Aaron would show some slides on a topic, talk about the real-world implications, and then we were off working through the examples in the book with Aaron providing help and guidance along the way. Everyone in the class was extremely motivated to learn and Aaron (as well as Mark Fenoglio who was assisting Aaron and the students) was willing to stay late at night helping you out with the code labs and exercises.</p>

<p>At Big Nerd Ranch it goes like this: Wake up and go to a nice sit-down breakfast where you try not to eat too much of the good food they provide. Then you go downstairs to a nice classroom from 9am until 12:30pm and write lots of Cocoa code. After that you have more good food at lunch, have about an hour of training after lunch followed by an afternoon hike. Below is JavaScript (and Cocoa) Jedi Master <a href="http://www.nearinfinity.com/blogs/page/jharwig">Jason Harwig</a> making his way on one of the hikes along with several other photos I took along the hikes.</p>

<img src="http://www.sleberknight.com/blog/sleberkn/resource/IMG_0115.JPG" alt="Jason hiking" title="Jason hiking"/>

<p>Hiking along the river:</p>

<img src="http://www.sleberknight.com/blog/sleberkn/resource/IMG_0117.JPG" alt="River along hiking trail" title=""River along hiking trail"/>

<p>An old mill along the river:</p>

<img src="http://www.sleberknight.com/blog/sleberkn/resource/IMG_0124.JPG" alt="Old mill along hiking trail" title="Old mill along hiking trail"/>

<p>The hike (and apparently swimming as well in the summer months) is a great way to break up the training day, refresh, and re-energize. Usually about that time in other training classes I would prefer to take a nap and require need a mass infusion of caffeine. But after the hikes I was ready for some more Cocoa! After the hike you go back and do some more learning/coding until about 6:30 when a nice country dinner is served. Good food and they provide free wine and beer, which is always a plus anywhere! After dinner many students actually go back to the training room and write code for <i>several more hours</i> and somehow you actually want to do it! In other training classes by about 5pm my brain is on the way out and I want to stop doing anything related to training. For some reason here, though, you seem to have more energy and drive to keep on coding.</p>

<p>I had a great time and am planning to go back and take more training there, probably the <a href="http://www.bignerdranch.com/classes/python.shtml">Python Bootcamp</a> since I have been interested in Python for a few years now and have written some admin-type scripts for various projects I've been on as well as worked my way through a Python introductory book. Now that <a href="http://code.google.com/appengine/">Google App Engine</a> is available and that you currently must code in <i>Python-only</i> I am even more motivated to go and take this course. I'm hoping that as influential innovative companies like Google show that Java and .NET aren't the only game in town to "real" businesses, perhaps they'll be more willing to implement projects in more flexible and lightweight technologies.</p>]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/cocoa_bootcamp_at_big_nerd.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/cocoa_bootcamp_at_big_nerd.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Mac OS X</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">big</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">bootcamp</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">cocoa</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">nerd</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">ranch</category>
            
            <pubDate>Thu, 10 Apr 2008 11:17:12 -0500</pubDate>
        </item>
        
        <item>
            <title>Update Mac OSX split for Pieces Larger than 2GB and Greater</title>
            <description><![CDATA[<p>Split is a very useful command-line utility for breaking large files into smaller pieces. Unfortunately, the version Apple ships with OSX 10.4 cannot split files into pieces 2GB or larger. Luckily, there is a newer version of split that you can compile and use instead of the Apple-supplied one.</p>

<p>There is a nice <a href="http://www.macosxhints.com/article.php?story=20061118222901111">article/post</a> over at macosxhints.com describing how to upgrade split. It's really not very hard but I thought I'd write a script so people could upgrade with a minimum of effort.</p>

<p>The short script is shown below. Please note that it is currently hard-coded for version 1.21 of split. You may want to check and see if there is a newer version before running the script.</p>

<pre class="prettyprint lang-bsh">#!/bin/bash
curl -o split.c "http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/usr.bin/split/split.c?rev=1.21&amp;content-type=text/plain"
perl -p -i -e 's/#include <sys\/cdefs.h>/#include <sys\/stat.h>\n#include <sys\/cdefs.h>/' split.c
cc -Os -o split split.c
sudo mv /usr/bin/split /usr/bin/split.apple
sudo cp split /usr/bin/split
sudo chmod ugo-w /usr/bin/split
sudo chmod ugo+rx /usr/bin/split
sudo chown root:wheel /usr/bin/split
echo "Upgrade Complete."
</sys\/cdefs.h></sys\/stat.h></sys\/cdefs.h></pre>]]></description>
            <link>http://www.nearinfinity.com/blogs/jeff_kunkle/update_mac_osx_split_for.html</link>
            <guid>http://www.nearinfinity.com/blogs/jeff_kunkle/update_mac_osx_split_for.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Mac OS X</category>
            
            
            <pubDate>Fri, 30 Mar 2007 10:26:23 -0500</pubDate>
        </item>
        
        <item>
            <title>Logging into Mac OS X Hidden Administrator Accounts</title>
            <description><![CDATA[<p>Every once in a while I need to login to a hidden administrator account on my Mac. It's a simple process after you invest lots of time trying to remember the key combination needed to expose the User Name and Password prompt instead of the usual graphical user account login prompt (which doesn't show the hidden admin accounts of course). Many times I've searched all over the Internet to uncover the secret and never seem to find anything quickly, so I thought I'd document it here for future reference.</p>

<p>Let's assume that you're staring at the usual graphical login prompt. There's a nice little picture to the left of each of your user accounts, but no way to enter a username. If you only have one user account on your Mac, you're already being prompted for the password to that account. If this is the case, hit Esc.</p>

<p>Now you should only see a list of all the user accounts on your Mac, and should not see a password field. Press the down arrow key until you see a gray background behind one of your user accounts. It doesn't matter which one.</p>

<p>Next, press Option-Enter. Your normal graphical login screen should now be replaced with two text entry fields, one for your User Name and one for your Password. Now you can enter the username and password of your hidden administrator account (or any account for that matter). That's it.</p>

<p>Please note that I don't know if the Option-Enter key combination does anything if you don't have any hidden accounts. You'll have to try it for yourself and see.</p>
]]></description>
            <link>http://www.nearinfinity.com/blogs/jeff_kunkle/logging_into_mac_os_x.html</link>
            <guid>http://www.nearinfinity.com/blogs/jeff_kunkle/logging_into_mac_os_x.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Mac OS X</category>
            
            
            <pubDate>Sat, 24 Mar 2007 12:20:12 -0500</pubDate>
        </item>
        
        <item>
            <title>Checkpointed Backups in OS X with rsnapshot</title>
            <description><![CDATA[<p>Starting a backup routine is hard. I wanted a backup solution that did the following:
</p><ul>
<li>Runs automatically every night</li>
<li>Backup OS X resource forks correctly</li>
<li>Maintain creation/modification times for backup files</li>
<li>Make checkpointed-incremental backups</li>
</ul>
.. and I didn't want to wait until <a href="http://www.apple.com/macosx/leopard/timemachine.html">Apple's next operating system</a>.  This solution is similar to Time Machine, without the pretty GUI.]]></description>
            <link>http://www.nearinfinity.com/blogs/jason_harwig/checkpointed_backups_in_os_x.html</link>
            <guid>http://www.nearinfinity.com/blogs/jason_harwig/checkpointed_backups_in_os_x.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Mac OS X</category>
            
            
            <pubDate>Tue, 06 Mar 2007 17:30:54 -0500</pubDate>
        </item>
        
        <item>
            <title>Building Subversion (SVN) 1.4.2 on Mac OS X</title>
            <description><![CDATA[<p>Today I needed to install Subversion on my Macbook running OS X and was following <a href="http://hivelogic.com/about">Dan Benjamin's</a> excellent <a href="http://hivelogic.com/articles/2006/04/19/svn_on_os_x">instructions</a> for accomplishing this task. The main difference was that I wanted to install the latest and greatest (as of today) version of Subversion, which is 1.4.2. Dan's instructions covered 1.3.1 and a co-worker was able to install SVN just fine using those instructions and the older version. I started following the instructions, substituting 1.4.2 for 1.3.1. Everything was going nicely until the <code>configure</code>, at which point I received an error stating "no suitable apr found". The following is the full output.</p>

<pre class="prettyprint">configure: Configuring Subversion 1.4.2
configure: creating config.nice
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... 
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ANSI C... none needed
checking how to run the C preprocessor... gcc -E
checking build system type... i386-apple-darwin8.8.1
checking host system type... i386-apple-darwin8.8.1
checking target system type... i386-apple-darwin8.8.1
checking for egrep... grep -E
checking whether ln -s works... yes
checking for a BSD-compatible install... /usr/bin/install -c
checking for static Apache module support... no
checking for Apache module support via DSO through APXS... no - Unable to locate /usr/include/httpd/mod_dav.h
==================================================================
WARNING: skipping the build of mod_dav_svn
         --with-apxs or --with-apache must be used
==================================================================
configure: Apache Portable Runtime (APR) library configuration
checking for APR... no
configure: WARNING: APR not found
The Apache Portable Runtime (APR) library cannot be found.
Please install APR on this system and supply the appropriate
--with-apr option to 'configure'

or

get it with SVN and put it in a subdirectory of this source:

   svn co \
    http://svn.apache.org/repos/asf/apr/apr/branches/0.9.x \
    apr

Run that right here in the top level of the Subversion tree,
then run autogen.sh again.

Whichever of the above you do, you probably need to do
something similar for apr-util, either providing both
--with-apr and --with-apr-util to 'configure', or
getting both from SVN with:

   svn co \
    http://svn.apache.org/repos/asf/apr/apr-util/branches/0.9.x \
    apr-util

configure: error: no suitable apr found
</pre>

<p>Oops.</p>

<p>I searched around Google a bit to see if anyone else had encountered (and solved) this problem. Didn't find much so I decided to go ahead and follow the suggestion to install Apache Portable Runtime and then try the configuration again. In case you run into the same problem, here are the modified instructions I used to build SVN 1.4.2 for OS X. Thanks to Dan for the original instructions, and I hope the modified ones will help you out too. Admittedly I did not think too much about exactly why I needed <code>apr</code> and was interested in just getting it to work. So if I've done something stupid by installing <code>apr</code> please feel free to post a comment and let me know!</p>

<p>One last note is that the following commands contain my username, <code>sleberkn</code>, so of course you'll need to substitute your username, or follow <a href="http://www.nearinfinity.com/blogs/page/jharwig">Jason's</a> suggestion to use <code>$HOME</code> instead. Before just trying these commands, first read Dan's entire <a href="http://hivelogic.com/articles/2006/04/19/svn_on_os_x">post</a> so you have all the prerequisites, such as setting your <code>PATH</code> correctly!</p>

<pre class="prettyprint">cd ~/Desktop
mkdir src
cd src
curl -O http://subversion.tigris.org/downloads/subversion-1.4.2.tar.gz
tar xzvf subversion-1.4.2.tar.gz
curl -O http://mirrors.24-7-solutions.net/pub/apache/apr/apr-1.2.7.tar.gz
tar xvzf apr-1.2.7.tar.gz
curl -O http://mirrors.24-7-solutions.net/pub/apache/apr/apr-util-1.2.7.tar.gz
tar xvzf apr-util-1.2.7.tar.gz
cd apr-1.2.7
./configure --prefix=/Users/sleberkn/Desktop/src/subversion-1.4.2
make
make install
cd ..
cd apr-util-1.2.7
./configure --prefix=/Users/sleberkn/Desktop/src/subversion-1.4.2 --with-apr=/Users/sleberkn/Desktop/src/subversion-1.4.2
make
make install
cd ..
cd subversion-1.4.2
./configure --prefix=/usr/local --with-openssl --with-ssl --with-zlib --with-apr=/Users/sleberkn/Desktop/src/subversion-1.4.2 --with-apr-util=/Users/sleberkn/Desktop/src/subversion-1.4.2
make
sudo make install
</pre>

<p>Assuming all that worked, verify your installation.</p>

<pre class="prettyprint">which svn
svn --version
</pre>

<p>The output from the above commands should show the Subversion is installed in  <code>/usr/local/bin</code>. My output looked like this.</p>

<pre class="prettyprint">nic-sleberkn:~/Desktop/src/subversion-1.4.2 sleberkn$ which svn
/usr/local/bin/svn
nic-sleberkn:~/Desktop/src/subversion-1.4.2 sleberkn$ svn --version
svn, version 1.4.2 (r22196)
   compiled Nov 30 2006, 17:47:45

Copyright (C) 2000-2006 CollabNet.
Subversion is open source software, see http://subversion.tigris.org/
This product includes software developed by CollabNet (http://www.Collab.Net/).

The following repository access (RA) modules are available:

* ra_svn : Module for accessing a repository using the svn network protocol.
  - handles 'svn' scheme
* ra_local : Module for accessing a repository on local disk.
  - handles 'file' scheme
</pre>]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/building_subversion_svn_1_4.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/building_subversion_svn_1_4.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Mac OS X</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Mac OS X</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">subversion</category>
            
            <pubDate>Thu, 30 Nov 2006 19:03:37 -0500</pubDate>
        </item>
        
    </channel>
</rss>
