<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Jonathan Saggau&apos;s Blog</title>
    <link rel="alternate" type="text/html" href="http://www.jonathansaggau.com/blog/" />
    <link rel="self" type="application/atom+xml" href="http://www.jonathansaggau.com/blog/atom.xml" />
   <id>tag:www.jonathansaggau.com,2010:/blog//1</id>
    <link rel="service.post" type="application/atom+xml" href="http://www.jonathansaggau.com/blog/mt-atom.cgi/weblog/blog_id=1" title="Jonathan Saggau's Blog" />
    <updated>2010-01-12T21:35:48Z</updated>
    <subtitle>This Vehicle Powered by 100% Pure Clean-Burning Caffeine</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 3.2</generator>
 
<entry>
    <title>360idev v3.0</title>
    <link rel="alternate" type="text/html" href="http://www.jonathansaggau.com/blog/2010/01/360idev_v30.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.jonathansaggau.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=145" title="360idev v3.0" />
    <id>tag:www.jonathansaggau.com,2010:/blog//1.145</id>
    
    <published>2010-01-12T21:35:18Z</published>
    <updated>2010-01-12T21:35:48Z</updated>
    
    <summary>I&apos;m giving two talks this time! One on using open source UI that closely resembles those of Apple&apos;s private API and another on Augmented Reality with Jonathan Blocksom. This will make it three in a row for me speaking at...</summary>
    <author>
        <name>jonmarimba</name>
        
    </author>
    
    <content type="html" xml:lang="en" xml:base="http://www.jonathansaggau.com/blog/">
        <![CDATA[I'm giving two talks this time!  One on using open source UI that closely resembles those of Apple's private API and another on Augmented Reality with Jonathan Blocksom.  This will make it three in a row for me speaking at this conference and it's gonna be awesome again.  Clear your calendar for April 11-14 and head on over to <a href="http://www.360idev.com/">360idev.com</a> and register.
<br /><br />

o There are fewer than 20 early (Cheap) tickets left for 360|iDev. Register now, save $100 and get the same awesome content for a little less coin. Act fast, these last tickets won't last. When they're gone, the regular price of $599 kicks in.
<br /><br />
o We've got some awesome keynoters lined up (Mike Lee and David Whatley to name two), they'll be worth the price of admission alone!
<br /><br />
o Don't miss sessions from community leaders like Marcus Zarra, Brent Simmons, Joe Pezzillo, and Henry Balanon to name a few. You're not going to find this many awesome speakers under one roof anywhere!
<br /><br />
o Don't miss the parties! Get your room at the Marriott San Jose (bit.ly/360idevhotel) before they're gone! The parties WILL be there after we leave Ebay! 
<br /><br />
o Check out the Schedule, subscribe in iCal to stay up to date!!  http://360idev.com/schedule]]>
        
    </content>
</entry>
<entry>
    <title>They tell me the book is out</title>
    <link rel="alternate" type="text/html" href="http://www.jonathansaggau.com/blog/2009/11/they_tell_me_the_book_is_out.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.jonathansaggau.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=144" title="They tell me the book is out" />
    <id>tag:www.jonathansaggau.com,2009:/blog//1.144</id>
    
    <published>2009-11-12T23:55:49Z</published>
    <updated>2009-11-12T23:55:56Z</updated>
    
    <summary>I have never walked into a book store and been able to pick up a book with my name on it. Pretty soon, though... There is lots of awesomeness in this book and 1/12 of it is from me....</summary>
    <author>
        <name>jonmarimba</name>
        
    </author>
    
    <content type="html" xml:lang="en" xml:base="http://www.jonathansaggau.com/blog/">
        <![CDATA[I have never walked into a book store and been able to pick up a book with my name on it.  Pretty soon, though...  There is lots of awesomeness in this book and 1/12 of it is from me.  

<br />
<br />

<iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=jonathansagga-20&o=1&p=8&l=as1&m=amazon&f=ifr&md=10FE9736YVPPT7A0FBG2&asins=1430224037" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>


]]>
        
    </content>
</entry>
<entry>
    <title>My Deck for 360idev</title>
    <link rel="alternate" type="text/html" href="http://www.jonathansaggau.com/blog/2009/09/my_deck_for_360idev.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.jonathansaggau.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=143" title="My Deck for 360idev" />
    <id>tag:www.jonathansaggau.com,2009:/blog//1.143</id>
    
    <published>2009-09-30T05:20:54Z</published>
    <updated>2009-10-01T18:18:19Z</updated>
    
    <summary>Thanks to all who attended my talk at 360idev. I think it went rather well and I am grateful to all who attended; the audience makes the talk. Here are the slides and the sample code as promised. Please read...</summary>
    <author>
        <name>jonmarimba</name>
        
    </author>
            <category term="Technology Love" />
            <category term="Troublesome Noise" />
    
    <content type="html" xml:lang="en" xml:base="http://www.jonathansaggau.com/blog/">
        <![CDATA[Thanks to all who attended my talk at <a href="http://www.360idev.com/">360idev</a>.  I think it went rather well and I am grateful to all who attended; the audience makes the talk.  <a href="http://jonathansaggau.com/Saggau360Presentation.zip">Here</a> are the slides and the sample code as promised.  Please read the readme file.
<br />
<br />
I'll also take some time on the plane home tomorrow night to make versions of this sample code without blocks for those who like to kick it old school.  I'll post those here as soon as I can.
<br />
<br />
UPDATE: I've changed the last example to remove the blocks requirement for those who wish to avoid them.  Same download location <a href="http://jonathansaggau.com/Saggau360Presentation.zip">here</a> as before.
<br />
<br />
Note: Be aware that the slides are on a pretty slow internet connection.
<br />
]]>
        
    </content>
</entry>
<entry>
    <title>360iDev v. 2.0</title>
    <link rel="alternate" type="text/html" href="http://www.jonathansaggau.com/blog/2009/08/360idev_v_20.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.jonathansaggau.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=142" title="360iDev v. 2.0" />
    <id>tag:www.jonathansaggau.com,2009:/blog//1.142</id>
    
    <published>2009-08-29T19:33:07Z</published>
    <updated>2009-08-29T19:39:28Z</updated>
    
    <summary> I am speaking at 360iDev again! Last time in San Diego was a blast. These guys are really good at putting on a conference where everybody talks to everybody else. It&apos;s all about the after parties, man. Rock Band,...</summary>
    <author>
        <name>jonmarimba</name>
        
    </author>
    
    <content type="html" xml:lang="en" xml:base="http://www.jonathansaggau.com/blog/">
        <![CDATA[
I am speaking at <a href="http://www.360idev.com/">360iDev</a> again!  Last time in San Diego was a blast.  These guys are really good at putting on a conference where everybody talks to everybody else.  It's all about the after parties, man.  Rock Band, which I'm terrible at despite (because of?) music degrees, is great for bringing peeps together.  
<br />
<br />
I'll be talking about making your iPhone application seem fast even when it's maybe kind of not so fast under the covers.  But wait, there's more (Ron Popeil is my hero).  Besides the expected boatload of awesome speakers and lots of iPhone nerds being in attendance at the actual conference, Mobile Orchard and Noel Llopis are doing a 2 day OpenGL ES class just before the conference.  If you're not going to C4 (two conferences back - to back!) like I am, you should totally get the combo discount and go to the class and then the conference.  <a href="http://360idev-blogpost.eventbrite.com/">Register here</a>.  The price goes up by a hundred clams tomorrow night!
<br />
<br />
<a href='#eventvue' onclick='EV.show()'><img src='http://widgets.eventvue.com/discover/badges/attending_360idevdenver_large.png' border='0' /></a><script type='text/javascript' src='http://widgets.eventvue.com/discover/discover.js?event_id=121&role=attending&size=large' id='eventvue_src'></script><noscript>
<br />
<br />
Powered by <a href='http://www.eventvue.com'>EventVue</a></noscript>
]]>
        
    </content>
</entry>
<entry>
    <title>iPhone code signing and multiple clients</title>
    <link rel="alternate" type="text/html" href="http://www.jonathansaggau.com/blog/2009/08/iphone_code_signing_and_multip.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.jonathansaggau.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=141" title="iPhone code signing and multiple clients" />
    <id>tag:www.jonathansaggau.com,2009:/blog//1.141</id>
    
    <published>2009-08-29T00:29:17Z</published>
    <updated>2009-08-29T00:29:41Z</updated>
    
    <summary>If you have to make a certificate request for a new client or &quot;Team,&quot; avoid making your name the same as your current certificate. If you have more than one &quot;iPhone Developer: Jonathan Saggau&quot; on your keychain, Xcode doesn&apos;t know...</summary>
    <author>
        <name>jonmarimba</name>
        
    </author>
    
    <content type="html" xml:lang="en" xml:base="http://www.jonathansaggau.com/blog/">
        If you have to make a certificate request for a new client or &quot;Team,&quot; avoid making your name the same as your current certificate.  If you have more than one &quot;iPhone Developer: Jonathan Saggau&quot; on your keychain, Xcode doesn&apos;t know which to use for code signing.  I used to swap certs in the keychain when switching between clients, but that proved confusing.  Better to use &quot;Jonathan Saggau (BigCO inc)&quot; or some such when making your cert request.  What you&apos;ll see when you do that is a pseudo-random string appendage to your name that allows certificates from different companies or &quot;Teams&quot; to coexist.  While I&apos;m not sure if this is just a change on Apple&apos;s part (maybe they always add the pseudo-random string now; I dunno) or if the (BigCO inc) string brings the magic.  What I do know is that I no longer have to rejigger my keychain every time I want to build an app for client X after working on the app for client Y.  
        
    </content>
</entry>
<entry>
    <title>Stars, man.  Stars.</title>
    <link rel="alternate" type="text/html" href="http://www.jonathansaggau.com/blog/2009/06/stars_man_stars.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.jonathansaggau.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=140" title="Stars, man.  Stars." />
    <id>tag:www.jonathansaggau.com,2009:/blog//1.140</id>
    
    <published>2009-06-24T21:17:24Z</published>
    <updated>2009-06-24T21:17:48Z</updated>
    
    <summary>This reminds me of my favorite final exam question from University. Paraphrased: Trace the calcium in your teeth from the big bang to the end of the universe. I took some cool classes....</summary>
    <author>
        <name>jonmarimba</name>
        
    </author>
    
    <content type="html" xml:lang="en" xml:base="http://www.jonathansaggau.com/blog/">
        <![CDATA[<a href="http://videolicious.tv/2009/06/creation-from-destruction/">This</a> reminds me of my favorite final exam question from University. Paraphrased: Trace the calcium in your teeth from the big bang to the end of the universe.  I took some cool classes.  ]]>
        
    </content>
</entry>
<entry>
    <title>He&apos;s baaaaaack</title>
    <link rel="alternate" type="text/html" href="http://www.jonathansaggau.com/blog/2009/06/hes_baaaaaack.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.jonathansaggau.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=139" title="He's baaaaaack" />
    <id>tag:www.jonathansaggau.com,2009:/blog//1.139</id>
    
    <published>2009-06-23T17:07:09Z</published>
    <updated>2009-06-23T17:07:18Z</updated>
    
    <summary>Daniel Lyons appears to have resurrected fake Steve. Perhaps it&apos;s the new liver, maybe it&apos;s the new book. Either way... He&apos;s back, bitches....</summary>
    <author>
        <name>jonmarimba</name>
        
    </author>
    
    <content type="html" xml:lang="en" xml:base="http://www.jonathansaggau.com/blog/">
        <![CDATA[Daniel Lyons appears to have resurrected fake Steve.  Perhaps it's the new liver, maybe it's the new book.  Either way...

<a href="http://fakesteve.blogspot.com/">He's back, bitches</a>.]]>
        
    </content>
</entry>
<entry>
    <title>Useful bash foo with subversion</title>
    <link rel="alternate" type="text/html" href="http://www.jonathansaggau.com/blog/2009/02/useful_bash_foo_with_subversio.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.jonathansaggau.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=138" title="Useful bash foo with subversion" />
    <id>tag:www.jonathansaggau.com,2009:/blog//1.138</id>
    
    <published>2009-02-24T21:31:56Z</published>
    <updated>2009-02-24T21:32:07Z</updated>
    
    <summary>I&apos;ve been a command-line user of subversion (svn) for some time and have long enjoyed these little bits of bash foo. Stripping .svn directories I often start one-off little test projects in my private slush svn repository and then move...</summary>
    <author>
        <name>jonmarimba</name>
        
    </author>
            <category term="Notes to self" />
            <category term="Stupid Nerd Tricks" />
            <category term="Technology Love" />
    
    <content type="html" xml:lang="en" xml:base="http://www.jonathansaggau.com/blog/">
        <![CDATA[<p>I've been a command-line user of <a href="http://subversion.tigris.org/">subversion</a> (svn) for some time and have long enjoyed these little bits of bash foo.  </p>

<h1>Stripping .svn directories</h1>
I often start one-off little test projects in my private slush svn repository and then move them into their own repository for further development as (or if) they grow up.  Sometimes you'll want to get rid of svn's footprints in a working directory.  
<pre>
rm -rfv `find . -name *\.svn`
</pre>
The <em>find . -name *\.svn</em> finds all of the <em>.svn</em> folders that svn uses to track the repository and with the help of those handy back-tics, <em>rm -rv</em> does the recursive removal of svn tracking directories.

<h1>Adding new files</h1>
During that early "making lots of new stuff" phase,  I often generate quite a number of files that need to be added to svn at once.  This is one of those times where having (say) class files in their own subdirectory is nice.  Running this command will <em>svn add</em> every file that isn't currently being tracked by svn in the current directory.
<pre>
svn add `svn stat |grep \? |awk '{print $2}'`
</pre>
Grep finds every <em>svn stat</em> output line that includes a question mark (meaning the item is not currently under version control) and pipes it through <em>awk '{print $2}'</em>, which shows only the text (the filename) from the second column of the svn stat output.  The back-tics and svn add finish the magic.

<h1>Using a Mulligan</h1>
I'll use something similar to the above along with svn revert to rollback a working copy "all the way."  Say you're experimenting in your working directory; you've added a few files, hit a dead end, and want to revert the whole tree as well as delete anything you've added.  In other words, you're looking for a full-on "do over."  Using <em>svn revert --recursive</em> will revert any files that svn is tracking, but will leave anything svn is not tracking alone, so we have to also remove those files.
<pre>
svn revert --recursive && rm -rf `svn stat |grep \? |awk '{print $2}'`
</pre>

<p>As with any other nerd foo, make sure that you really want to do what you're asking for when you use these commands.  These make my life with svn just a little easier.<br />
</p>]]>
        
    </content>
</entry>
<entry>
    <title>Brain clarity through body hacking and distractions</title>
    <link rel="alternate" type="text/html" href="http://www.jonathansaggau.com/blog/2009/02/brain_clarity_through_body_hac.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.jonathansaggau.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=137" title="Brain clarity through body hacking and distractions" />
    <id>tag:www.jonathansaggau.com,2009:/blog//1.137</id>
    
    <published>2009-02-19T23:49:52Z</published>
    <updated>2009-02-19T23:58:21Z</updated>
    
    <summary>or... how I make my brain work more gooder*. I&apos;ve been known to fight foggy brain from time to time. You know what I mean? That decidedly uncool feeling of &quot;can&apos;t do crap, too tired and dumb&quot; that only seems...</summary>
    <author>
        <name>jonmarimba</name>
        
    </author>
            <category term="Introspection" />
            <category term="Strange habits" />
    
    <content type="html" xml:lang="en" xml:base="http://www.jonathansaggau.com/blog/">
        <![CDATA[<p>or... how I make my brain work more gooder*.  </p>

<p>I've been known to fight foggy brain from time to time.  You know what I mean?  That decidedly uncool feeling of "can't do crap, too tired and dumb" that only seems to creep in when the to do list is longer than my ... um ... arm.  Lately, though that feeling has struck me less and less often and I think I know why.  I've lately zeroed - in on the right set of habits for me.  Every now and again, I'll pick one of the topics below and write a short post expanding the topic.  For now, though, just a list of things that work for me.<br />
</p>]]>
        <![CDATA[<h1>1.  Maintenance (or, as I like to call it, "Entropy Reversal")</h1>

<p>- Sleep, I need more than I think. Staying up to work has too many negative consequences.  I don't do it as often as I did before.<br />
- Breakfast.  Seriously.  I usually Eat lots of carbs one morning and lots of protein the next.<br />
- Maybe meat isn't murder, but it can mess me up.<br />
- Water is boring, but damn, I'm so pretty when I drink a lot.<br />
- Vitamins and other stuff best left in the bathroom<br />
   - Multivitamin.  Pick one, it doesn't matter.<br />
   - 5-HTP (supposedly keeps seratonin levels up)<br />
   - B vitamins (Because I don't eat much meat)<br />
   - Vitamin E (skin)<br />
   - Cod Liver Oil (Vitamins A + D because I don't get much sun)<br />
   - Amino Acids + L vitamins (Not sure if this is the placebo effect talking, but I think I get fewer cold sores and my muscles recover faster).  I get this stuff in a spray because (probably placebo effect talking again) apparently these break down too fast to ingest in a pill.<br />
- Acai and <a href="http://en.wikipedia.org/wiki/Yerba_mate">Yerba-mat&eacute;</a> tea.  Less jittery than coffee, it otherwise snaps one out of it in a hurry.</p>

<h1>2.  Distractions help me concentrate (or, how I get more ADD the older I get, but still get stuff done somehow).  </h1>

<p>When I work on something that consumes me, I can ignore most anything that isn't itself too interesting.  Somehow, having something distraction in the background helps me to concentrate.  When my concentration wanes, I can return to the task at hand more quickly if I context - switch to some defined low - level distraction.  In short, I set distracting traps for myself that I know I can pull out of so I don't get distracted by something else that might consume hours.</p>

<h3>Distractions:</h3>
- TV or music I can ignore runs in the background almost all day.  The ROKU box that streams Netflix is loaded with BBC TV and crappy '80s TV shows.<br />
- Twitter.  Freaking great.  I can ignore it, or not, as I wish and it keeps me up on what the nerds are up to.<br />
- IM.  Dangerous, but occasionally just what the doctor ordered.  Opened in moderation.<br />
- Puppy!  Throwing a ball at a 4-legged fuzzy thing is not just a great way to get out of the house, it's a great way to kill 10 minutes (and break things in your house, too).  Oh, and sometimes she has to pee so I reset my brain when I take her outside.<br />

<h1>3.  Best.  Workouts.  Evar.</h1>  
<h2>(Wherein I plug an awesome virtual workout partner).  <a href="http://beachbody.com/">Tony Horton RULES.</a> </h2>

<p>You see, I hate (HATE) working out where people can see me.  I'm in good shape, but I get embarrassed easily.  I MUST workout or my brain really stops working over time.  This leaves me with working out in my home.  I have the Bowflex SelectTech (Meh. They're okay, but too much crap hangs off of them, which makes them too wide sometimes) dumbbells and a whole drawer full of resistance bands.  I loves me some resistance bands.  Add the following workout DVDs and I never get bored working out.</p>

<h3>Tony Horton Workouts I have:</h3>
- I have done the three-month P90X routine once (and will do it again soon).  I know you've seen the cheesy infomercial about "muscle confusion."  It's real, boys and girls.  No kidding.  I use the workouts from this program as my core (pun intended) group.<br />
-  One on One with Tony Horton.  He's a personal trainer for dudes like Sting for a reason, somehow motivational without being annoying (or making you feel like a weak pansy).  His 45 minute yoga vid rocks.  Oh, and he's FUNNY.  I get a new one of these automatically sent to me every month.<br />
- P90X+ (ouch).  If you're not in seriously good shape, stay away from this, especially the abdominal video.  Otherwise, these are like shorter, but even more intense, versions of P90X.  I love to throw these in to mix things up.  The interval training video is a favorite of mine.<br />

<h1>4.  Micro - Priorities and how they don't so much work for me (or, Macro - Priorities and how they do so much work for me).  </h1>

<p>I do a whole lot of different kinds of things in a given day, otherwise I get bored and lose motivation.  I have also learned that fighting frustration makes me more frustrated.  It's better to change focus away from and then back to something frustrating rather than bang my head against it.  How do I get anything at all long-term done? I follow the following system.  It consists of two large clipboards of roughly unfolded newspaper size (bought from an art supply store) on which I place 8.5x11" pieces of paper adhered with restickable adhesive; think post-it note adhesive in a glue stick, you'll find it at office supply stores (made by 3M).  Each big piece of paper is host to one project or category and each project or category is broken into tiny (tiny!) steps that I put on little individual post-it notes.  Sometimes these post-it notes are layers and layers deep.  I transfer these post-it notes to the "chin" of my 24" iMac or to the wrist rest on my laptop in batches of 5 or so at a time.  Every time I finish a step, I put a big X on the post-it note and make a nice satisfying pile of "stuff I did today."</p>

<p><img src="http://www.jonathansaggau.com/blog/images/TODO.png" alt="TODO.png" border="0" width="400" height="300" /></p>

<p>When I'm following this system the way I like to follow it, I keep around 5 to 10 different items of varying degrees of difficulty and varying required lengths of time (rarely does a note take more than a couple of hours) in front of me at all times.  The cool thing about this is that I can put the most important stuff where I'll see it.  I can chip away at a random mountain of work this way really well.  Easy to handle, little items can be thrown in the pile occasionally.  They act as mini distractions that I can do quickly when something that takes longer causes frustration.  </p>

<p>You might notice that this is a particularly analog way for a technology guy to do things and you would be right.  I haven't yet found anything that comes close to restickable paper scraps among the various techie tools I've tried to use for organization.  I do often use <a href="http://trac.edgewall.org">trac</a> to prioritize bugs in various software projects and I sometimes use it as a place to put long-term items for myself.  I'm able to start a new trac instance fairly quickly, and it's a great collaborative to do list.</p>

<p><br />
That's how I do the stuff I do in a nutshell.  In a vacuum, it's probably pretty inefficient, but it fits my personality better than anything else I've tried.  It's all the result of 15 years of varying levels of introspection about how to get stuff done (43 folders people will see some of their favorite things up there, I think) while compensating for my own weaknesses and accentuating my strengths. Many portions of the above warrant a blog post all their own, but this little distraction has been perfect to reset my brain to go back to something I was working on earlier from a fresh perspective.  ...and so it goes.</p>

<p>* One of my favorite people, Ronald L. Huber, English Teacher (with capitals appropriately deployed) former gunship pilot, and good buddy taught me how to use such phrases such as "I've always said that sometimes," "much more gooder," "perceptions are the way they are, even when they're not that way" in everyday conversation.  When my English done broke, he fixed it up good.  Hi Ron.</p>]]>
    </content>
</entry>
<entry>
    <title>iPhone responsiveness and memory usage</title>
    <link rel="alternate" type="text/html" href="http://www.jonathansaggau.com/blog/2009/01/iphone_responsiveness_and_memo.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.jonathansaggau.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=136" title="iPhone responsiveness and memory usage" />
    <id>tag:www.jonathansaggau.com,2009:/blog//1.136</id>
    
    <published>2009-01-03T20:30:42Z</published>
    <updated>2009-01-03T20:43:26Z</updated>
    
    <summary>I recently answered a question on a private mailing list about how to make a network - based (XML parsing and such) iPhone application more responsive. I&apos;ve been encouraged to post it here by a few folks (Thanks, guys! You...</summary>
    <author>
        <name>jonmarimba</name>
        
    </author>
            <category term="Cocoa" />
            <category term="Cocoa" />
            <category term="Technology Love" />
    
    <content type="html" xml:lang="en" xml:base="http://www.jonathansaggau.com/blog/">
        <![CDATA[I recently answered a question on a private mailing list about how to make a network - based (XML parsing and such) iPhone application more responsive.  I've been encouraged to post it here by a few folks (Thanks, guys!  You know who you are.).  So, I figure "why not?"  Here you go.  (Slightly modified)
<br /><br />
The original question (paraphrased):  I have an iPhone application that downloads XML data from the web, parses it, and loads it all into memory.  I notice that my app is a little sluggish and that it crashes as odd times, probably due to having too much information in memory.  There are other apps that do this kind of thing on the app store and I notice that many of them are more responsive than mine.  How does one make one's "network cloud-based" app more responsive?
<br /><br />
My Answer
<br /><br />
You're running into a few of the more common problems with embedded
programming.  Here are a few little tricks that have helped me in
general (done a little embedded Linux programming, too) and on the
iPhone.
<br /><br />
<h1>Regarding bandwith / data size / responsiveness as a result of downloading data</h1>
You'll be surprised that the actual downloading of anything but pretty
large amounts of data is pretty fast by itself.  The part that is slow
is the stuff that happens before the download even starts.  Edge / 3G
latency sucks and even DNS lookup is really really really (really?)
slow on the iPhone in almost all circumstances AFAICT.  I've found
that strategies that download more data at a time while discarding
unneeded data that you're getting on the fly, rather than making
multiple requests for specific small chunks of data has been a
performance win.  That's a little counter intuitive.
<br /><br />
<h1>Regarding memory</h1>
There is a reason the NSXMLDocument doesn't exist on the iPhone.  You
can get away with throwing a smallish XML tree into memory and go
ahead and do it if it simplifies your life for small data sets, but
the combination of larger XML trees in memory and whatever else
(including UI) you have cached in memory can cause you to hit the
memory ceiling at weird times; that's probably what's happening when
your app crashes.  The app will get terminated if you don't release
memory when you get these memory warnings.  Take a look at apples
"Books" SQLite example.  They're not doing exactly what you're looking
for there (no network code), but the handling of memory works as
they're doing it.  They load data from a SQLite database lazily, but
keep that data in memory until the application closes, until the
owning object is deallocated, or when memory gets scarce.  When the
app gets those fun memory warnings, they save any changed data and
release everything that they can get back out of the database later.
This is similar in theory to the lazy loading of views we've all grown
accustomed to (and that is partly handled for you).  When a view
controller gets a memory warning, its views are released by default if
they don't have a superview, which is why you have to figure out if
the view is still there every time you (re)load it.  Doing something
similar with your XML data by saving it somewhere when you get a
memory warning and releasing the associated data structure, reloading
it piecemeal from disk as needed (be it an SQLite database or
what-have-you) works pretty well and appears to be the recommended
approach.  Ultimately, figuring out how much and which data to put on
"disk" and/or in memory (and when) is the biggest PITA in embedded
programming, but it's also the place where you're going to get the
responsiveness you're looking for.
<a href="http://furbo.org/2008/08/27/dealing-with-memory-loss-the-cleanup/">http://furbo.org/2008/08/27/dealing-with-memory-loss-the-cleanup/</a>
<br /><br />
<h1>Regarding UI responsiveness</h1>
Don't use a lot of subviews and avoid opacity.  Instead draw the views
yourself...  Draw once, if possible.  (
<a href="http://blog.atebits.com/2008/12/fast-scrolling-in-tweetie-with-uitableview/">http://blog.atebits.com/2008/12/fast-scrolling-in-tweetie-with-uitableview/</a>
)
<br /><br />
<h1>Other tricks</h1>
Use Instruments and Shark with the code running ON THE DEVICE to see
how much memory you're using, how much disk access you're doing, and
what is actually going on timing-wise.  Optimize those specific areas
profiling the simulator (faster edit, compile, test cycle).  Rinse (on
the device) and repeat.
<br /><br />
Put breakpoints in memory warning methods and figure out when (and
why) it's happening (again, on the device).  Is it when you download
data, load view A, then view B?  Can you release view A's data when it
goes off the screen to keep the memory footprint from growing?  Do you
need the whole tree for view B?  Can you download it all, dump to
disk, and load lazily?  Blah blah blah.  This stuff can get tricky,
but try the obvious things first.  Find out what is causing the memory
ceiling problem and you're well on your way.  :)
<br /><br />
Using the <a href="http://clang.llvm.org/StaticAnalysis.html">LLVM/Clang static analyzer</a> has saved me a lot of headaches as
well.  It's easy to forget that you have a web view somewhere with a
bunch of cached data floating off screen causing the device to go bork
bork...
<br /><br />
Cache yesterday's data, load, and display it before going out to the
network for today's data.  Use a progress indicator and some other UI
indicator to let the user know that you're updating from the network
and that they're looking at what may be old data.  Do this
asynchronously.  When it comes to displaying data from the network,
sometimes you have to fake it 'til you make it.  You don't have to
rewrite Google gears or anything, just throw everything you need from
the server onto disk and reload it when the app launches.
<br /><br />
<a href="http://gusmueller.com/blog/archives/2008/03/fmdb_for_iPhone.html">Gus Mueller's FMDB rocks</a> for SQLite work.  I have a version with
embedded Dtrace probes if anybody wants it.  (This will have to be the subject of a later article after I find some time to update my version to Gus' latest version and to send it to him to look at / integrate if he wishes first...)]]>
        
    </content>
</entry>
<entry>
    <title>Enumerating and visualizing all fonts on iPhone</title>
    <link rel="alternate" type="text/html" href="http://www.jonathansaggau.com/blog/2008/12/enumerating_and_visualizing_al.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.jonathansaggau.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=135" title="Enumerating and visualizing all fonts on iPhone" />
    <id>tag:www.jonathansaggau.com,2008:/blog//1.135</id>
    
    <published>2008-12-04T06:37:00Z</published>
    <updated>2008-12-04T06:37:12Z</updated>
    
    <summary>When you&apos;re designing custom views or otherwise theming your iPhone application, it&apos;s nice to be able to see all of the available fonts. I couldn&apos;t find anything online that showed them, so I made my own little application. You can...</summary>
    <author>
        <name>jonmarimba</name>
        
    </author>
            <category term="Cocoa" />
            <category term="Cocoa" />
    
    <content type="html" xml:lang="en" xml:base="http://www.jonathansaggau.com/blog/">
        <![CDATA[When you're designing custom views or otherwise theming your iPhone application, it's nice to be able to see all of the available fonts.  I couldn't find anything online that showed them, so I made my own little application.  You can get it at <a href="http://jonathansaggau.com/FontListViz.tgz">FontListViz.tgz</a>.
<br /><br /><br /><br />
<img src="http://www.jonathansaggau.com/blog/images/Screenshot 2008.12.04 01.27.59.jpg" alt="Screenshot 2008.12.04 01.27.59.jpg" border="0" width="320" height="480" />
<br /><br /><br /><br />
It's pretty well dirt simple.  Get all font family names, then get all of the font names in each family and store them in an array, then put each font name's text in a table view cell and set the table view cell's font using <em>-[UIFont fontWithName:size:]</em> and, well, Bob's your uncle -- instant very simple font viewer.  
<pre>

- (void)viewDidLoad 
{
    [super viewDidLoad];
    self.fontNames = [NSMutableArray array];
    NSArray *fontFamilyNames = [UIFont familyNames];
    for (NSString *familyName in fontFamilyNames) {
        NSLog(@"familyName = %@", familyName);
        NSArray *names = [UIFont fontNamesForFamilyName:familyName];
        NSLog(@"FontNames = %@", fontNames);
        [self.fontNames addObjectsFromArray:names];
    }
}
.
.
.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }
    
    NSString *name = [self.fontNames objectAtIndex:indexPath.row];
    cell.text = name;
    cell.font = [UIFont fontWithName:name size:14];
    return cell;
}

</pre>

]]>
        
    </content>
</entry>
<entry>
    <title>Microsoft Office Formats won&apos;t load on the iPhone simulator</title>
    <link rel="alternate" type="text/html" href="http://www.jonathansaggau.com/blog/2008/12/microsoft_office_formats_wont.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.jonathansaggau.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=134" title="Microsoft Office Formats won't load on the iPhone simulator" />
    <id>tag:www.jonathansaggau.com,2008:/blog//1.134</id>
    
    <published>2008-12-04T06:14:18Z</published>
    <updated>2008-12-04T06:14:58Z</updated>
    
    <summary>Just an FYI: The UIWebView in the simulator remains blank when loading MS office formats like word (.doc), excel (.xls), powerpoint (.ppt) (and possibly iWork formats as well -- Go Go Gadget Google indexer), but it does work on the...</summary>
    <author>
        <name>jonmarimba</name>
        
    </author>
    
    <content type="html" xml:lang="en" xml:base="http://www.jonathansaggau.com/blog/">
        <![CDATA[Just an FYI: 
<br /><br />
The UIWebView in the simulator remains blank when loading MS office formats like word (.doc), excel (.xls), powerpoint (.ppt) (and possibly iWork formats as well -- Go Go Gadget Google indexer), but it does work on the device itself.  Caveat coder.  Don't pull your hair out for too long wondering why your files don't show up on the simulator.  They will once you compile and install on the phone.

<pre>
    NSString *filePath = @"pathToAnExcelDocument.xls";
    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath] == YES) 
    {
        NSLog(@"Loading %@", filePath);
        NSURL *pathURL = [NSURL fileURLWithPath:filePath];
        //Warning: this doesn't load into the view on the simulator
        NSURLRequest *pathURLRequest = [NSURLRequest requestWithURL:pathURL];
        [someWebView loadRequest:pathURLRequest];
    }
</pre>

radar://6417654

]]>
        
    </content>
</entry>
<entry>
    <title>touchengine -- iPhone Google App Engine communication</title>
    <link rel="alternate" type="text/html" href="http://www.jonathansaggau.com/blog/2008/11/touchengine_iphone_google_app.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.jonathansaggau.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=133" title="touchengine -- iPhone Google App Engine communication" />
    <id>tag:www.jonathansaggau.com,2008:/blog//1.133</id>
    
    <published>2008-11-15T19:53:48Z</published>
    <updated>2008-11-15T20:06:09Z</updated>
    
    <summary>My friend Noah Gift, an awesome python programmer who wrote the very popular book Python for Unix and Linux System Administration and I are working on a new open source framework that aims to facilitate communication between the iPhone SDK and Google App engine. </summary>
    <author>
        <name>jonmarimba</name>
        
    </author>
            <category term="Cocoa" />
            <category term="Cocoa" />
            <category term="Python" />
            <category term="Technology Love" />
    
    <content type="html" xml:lang="en" xml:base="http://www.jonathansaggau.com/blog/">
        <![CDATA[My friend <a href="http://noahgift.com/">Noah Gift</a>, an awesome python programmer who wrote the very popular book <a href="http://www.amazon.com/gp/product/0596515820?ie=UTF8&tag=jonathansagga-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0596515820">Python for Unix and Linux System Administration</a><img src="http://www.assoc-amazon.com/e/ir?t=jonathansagga-20&l=as2&o=1&a=0596515820" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
 and I are working on a new open source framework that aims to facilitate communication between the <a href="http://developer.apple.com/iphone/">iPhone SDK</a> and <a href="http://appengine.google.com/">Google App engine</a>.  In the spirit of the open source mantra, "release early, release often," we've made it available <a href="http://code.google.com/p/touchengine/">here on Google Code</a> and is <a href="http://www.opensource.org/licenses/mit-license.php">MIT licensed</a>.  We're also working on a couple of apps that use the framework; we plan to eat our own dogfood so-to-speak.

<h1>Current features</h1>
<ul>
<li>Includes a slightly modified version of the <a href="http://docs.python.org/dev/library/plistlib.html">python plist library</a> to allow syndication of data from Google App Engine to the iPhone via xml plists. </li>
<li>Includes a generically useful caching plist <a href="http://code.google.com/p/touchengine/source/browse/#svn/trunk/iPhone/PlistLoader">downloader library</a> for the iPhone SDK that keeps the user in sync with Google App Engine data and allows offline access to that data.</li>
</ul>

<h1>Example Code</h1>
<ul>
<li><a href="http://code.google.com/p/touchengine/source/browse/#svn/trunk/GAE/isonnet"><em>isonnet</em></a>, a Google App Engine application that syndicates Shakespeare's Sonnets in plist form for consumption by the iPhone app.
<li><a href="http://code.google.com/p/touchengine/source/browse/#svn/trunk/iPhone/Sonnet"><em>Sonnet</em></a>, a viewer application for the iPhone, which we're going to release soon for free on the app store, that connects to our Google App Engine site to download, cache, and display Shakespeare's Sonnets.</li>
</ul>

<h1>Future Features / Informal Roadmap</h1>
<ul>
<li>Authentication with Google App Engine with the user's Google ID </li>
<li>Two-way communication and data sync between app engine and the iPhone SDK</li>
<li>Integration and automatic plist syndication of underlying Google App Engine Data Storage and objects </li>
<li>Support for Application skinning through plist syndication </li>
<li>Support for storage of the iPhone user's application preferences on Google App Engine.</li>
</ul>
Look for our article on <a href="http://www.ibm.com/developerworks/">IBM DeveloperWorks</a> coming soon.
<br/><br/>
If you have any questions or comments for us, please feel free to contact me at jonathan ((at)) thisdomainyou'reonrightnow ((dot com)).
<script type="text/javascript" src="http://www.assoc-amazon.com/s/link-enhancer?tag=jonathansagga-20&o=1">
</script>
<noscript>
    <img src="http://www.assoc-amazon.com/s/noscript?tag=jonathansagga-20" alt="" />
</noscript>

]]>
        
    </content>
</entry>
<entry>
    <title>Reverse DNS on the iPhone</title>
    <link rel="alternate" type="text/html" href="http://www.jonathansaggau.com/blog/2008/11/reverse_dns_on_the_iphone.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.jonathansaggau.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=132" title="Reverse DNS on the iPhone" />
    <id>tag:www.jonathansaggau.com,2008:/blog//1.132</id>
    
    <published>2008-11-14T23:43:59Z</published>
    <updated>2008-11-14T23:52:39Z</updated>
    
    <summary>You can actually get reverse DNS lookup on the iPhone.  Using res_query (so make sure you link against libresolv.dylib) to query DNS and dns_parse_packet from dns_utils.h to do the dirty work of parsing out the DNS server reply works rather well.</summary>
    <author>
        <name>jonmarimba</name>
        
    </author>
            <category term="Cocoa" />
            <category term="Cocoa" />
            <category term="Stupid Nerd Tricks" />
            <category term="Technology Hate" />
            <category term="Technology Love" />
    
    <content type="html" xml:lang="en" xml:base="http://www.jonathansaggau.com/blog/">
        <![CDATA[Reverse DNS via the usual OS X means doesn't seem to work on the iPhone.  It looks like this is a known bug/limitation. <a href="https://devforums.apple.com/message/7534#7534">The new apple developer forums</a> (login required) have a thread that's dedicated to the problem.  (rdar://problem/5929766 is mentioned there).  Apple seems to have used the eraser on some other of their DNS code on the iPhone. <a href="http://www.saurik.com/id/3">Saurik</a> has an interesting hack to work - around a perhaps related change in DNS behavior. 
<br /><br />
You can actually get reverse DNS lookup on the iPhone to work using <a href="http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/res_query.3.html">res_query</a> (which is in libresolv, so make sure you link against <em>libresolv.dylib</em>) to query DNS and <em>dns_parse_packet</em>, which you'll find in dns_utils.h, to do the work of parsing out the DNS server reply works rather well.  I could not get the recommended tools in <em>dns.h</em> to work, but I did discover that <em>res_query</em> returns the same raw reply from the DNS Server that <em>dns_parse_packet</em> expects from the utilities in <em>dns.h</em>. The code:
]]>
        <![CDATA[<pre>
#define T_PTR		12		/* domain name pointer */
#define C_IN		1		/* the arpa internet */
static const int kBufLen = 1500;

//takes a string like 1.1.168.192.in-addr.arpa and turns it into the hostname
char *_reverseDns(const char* arpaPoint)
{
    int len = -1;
    char buffer[kBufLen];
    res_init();
    
    int queryType = T_PTR; /* domain name pointer */ 
    int arpanet = C_IN; /* the arpa internet = 1*/
    len = res_query(arpaPoint, arpanet, queryType, (u_char *)buffer, kBufLen);
    char *resStr;
    dns_reply_t *reply;
    if (len > 0)
    {
        reply = dns_parse_packet(buffer, len);
        resStr = ((*(reply->answer))->data).PTR->name;
    }
    else
    {
        if (errno)
            fprintf(stderr, "Error, res_query() error value: %d\n", errno);
        if (61 == errno) 
            resStr = "Could not connect to DNS";
        else
            resStr = "DNS entry Not Found";
    }    
    return resStr;
}

//makes 192.168.1.1 into 1.1.168.192.in-addr.arpa
NSString *makeDNSLookupString(NSString *inString)
{
    NSString *eachString = @"";
    NSScanner *scanner = [NSScanner scannerWithString:inString];
    NSUInteger scanLocation = 0;
    NSUInteger stringLen = [inString length];
    NSString *outStr = @"";
    while([scanner scanUpToString:@"." intoString:&eachString])
    {
        eachString = [eachString stringByAppendingString:@"."];
        outStr = [eachString stringByAppendingString:outStr];
        scanLocation = [scanner scanLocation];
        if (scanLocation < stringLen)
            [scanner setScanLocation:scanLocation + 1]; // hop the . character
    }
    outStr = [outStr stringByAppendingString:@"in-addr.arpa"];
    return outStr;
}

NSString *reverseDNS(NSString *ipAddress)
{
    NSString *arpaString = makeDNSLookupString(ipAddress); 
    //NSLog(@"arpaString = %@", arpaString);
    NSString *returnString = [NSString stringWithCString:_reverseDns([arpaString cStringUsingEncoding:NSASCIIStringEncoding]) encoding:NSASCIIStringEncoding];
    return returnString;
}</pre>
You can find a simple example app that uses this <a href="http://jonathansaggau.com/HostNameStuff.tgz">here</a>. 
<br /><br />
<img src="http://www.jonathansaggau.com/blog/images/revDNS.jpg" alt="revDNS.jpg" border="0" width="320" height="480" />
<br /><br />
It also uses a nice trick from <a href="http://www.amazon.com/gp/product/0321555457?ie=UTF8&tag=jonathansagga-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0321555457">The iPhone Developer's Cookbook</a><img src="http://www.assoc-amazon.com/e/ir?t=jonathansagga-20&l=as2&o=1&a=0321555457" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />.  It's <a href="http://www.opensource.org/licenses/mit-license.php">MIT licensed</a>, so feel free to use it in your own app.  Consider this a workaround until apple comes up with something simpler.  This works for me installed on the iphone itself looking up addresses on the internet and on my local network (it loses the .local, but is otherwise aok).  It doesn't validate the ip address string you give it or check to see if DNS is even available, so you'll want to wrap it in some reachability and validation calls, etc (which I did not do in the demo app, but it fails fairly gracefully when you give it garbage input).
<br /><br />
Running <em>reverseDNS(@"192.168.1.139")</em> (which is the IP address of my imac) on the iPhone connected via wi-fi to my local network returns <em>@"FreakinIMac"</em> (which is the host name of my imac).  It even returns the DD-WRT hostname of my router.  It returns @"DNS entry Not Found if it can't find an entry or errs out and it will log errno if set by res_query to the console.  You'll probably want to wrap some error handling code around this if you plan to use it in a real app.
<br /><br />
Other useful stuff:
You can find the source for <em>libresolv</em> <a href="http://www.opensource.apple.com/darwinsource/10.5.5/">here</a>, which was quite
helpful.  The source to <a href="http://src.gnu-darwin.org/DarwinSourceArchive/expanded/netinfo/netinfo-324.6/resolver/dns.c">dns.c</a> and <a href="http://src.gnu-darwin.org/DarwinSourceArchive/expanded/netinfo/netinfo-324.6/resolver/dns_util.c">dns_util.c</a> proved useful as well.  A post <a href="http://lists.apple.com/archives/darwin-development/2004/May/msg00042.html">on an apple mailing list</a> also pointed me in a direction.  Having the source to the libraries you use is a great help.  Thanks to Apple for making these available; keep 'em coming!
<br /><br />
Note: If you want to log the whole parsed reply from the DNS server, use <em>dns_print_reply</em> (also in <em>dns_utils</em>) with <em>DNS_PRINT_ANSWER</em> as an arg.  There is probably a lot more you can do with this method of DNS lookup.  I'm guessing you can send pretty much any kind of DNS query and parse the result, just watch out for (and apply his genius patch, if necessary) that bug that Saurik found.
<br /><br />
Note: Watching network traffic with a packet sniffer like Wireshark is quite informative.  

<script type="text/javascript" src="http://www.assoc-amazon.com/s/link-enhancer?tag=jonathansagga-20&o=1">
</script>
<noscript>
    <img src="http://www.assoc-amazon.com/s/noscript?tag=jonathansagga-20" alt="" />
</noscript>

]]>
    </content>
</entry>
<entry>
    <title>iPhone Live!!!</title>
    <link rel="alternate" type="text/html" href="http://www.jonathansaggau.com/blog/2008/10/iphone_live.html" />
    <link rel="service.edit" type="application/atom+xml" href="http://www.jonathansaggau.com/blog/mt-atom.cgi/weblog/blog_id=1/entry_id=131" title="iPhone Live!!!" />
    <id>tag:www.jonathansaggau.com,2008:/blog//1.131</id>
    
    <published>2008-10-15T22:01:17Z</published>
    <updated>2008-10-15T22:01:27Z</updated>
    
    <summary>I&apos;m speaking at the iPhone Live conference with my friend Noah Gift. I&apos;m happy to announce that Aaron Hillegass from the Big Nerd Ranch has just agreed to sponsor the talk. Thanks Aaron! Today is the last day for attendees...</summary>
    <author>
        <name>jonmarimba</name>
        
    </author>
    
    <content type="html" xml:lang="en" xml:base="http://www.jonathansaggau.com/blog/">
        <![CDATA[I'm speaking at the <a href="http://en.oreilly.com/iphonelive2008">iPhone Live</a> conference with my friend Noah Gift.  I'm happy to announce that Aaron Hillegass from the <a href="http://www.bignerdranch.com/">Big Nerd Ranch</a> has just agreed to sponsor the talk.  Thanks Aaron!
<br /><br />
Today is the last day for attendees to save $125 off registration. 
Additionally, people who register can save an extra 20% by entering ip08gd20 at checkout - bringing the early reg total to a cool and reasonable $500.
<br /><br />
iPhoneLive
San Jose, CA -- November 18, 2008
Redefining Mobile Computing
<br /><br />]]>
        
    </content>
</entry>

</feed> 

