<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Ole Begemann: iPhone Development</title>
	
	<link>http://oleb.net</link>
	<description>iPhone Development, Cocoa and Objective-C</description>
	<lastBuildDate>Sun, 07 Mar 2010 17:53:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ole-begemann-dev-blog" /><feedburner:info uri="ole-begemann-dev-blog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>52.518333</geo:lat><geo:long>13.408333</geo:long><item>
		<title>If you want to learn Cocoa…</title>
		<link>http://feedproxy.google.com/~r/ole-begemann-dev-blog/~3/yKSQORYDnE4/</link>
		<comments>http://oleb.net/blog/2010/03/if-you-want-to-learn-cocoa/#comments</comments>
		<pubDate>Sun, 07 Mar 2010 14:59:58 +0000</pubDate>
		<dc:creator>Ole Begemann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://oleb.net/?p=392</guid>
		<description><![CDATA[&#8230;be prepared to write a lot more code than in your typical &#8220;scripting&#8221; language. Three examples (I am using Ruby for comparison because it is the scripting language I am most familiar with; things would look very much the same with Python or PHP):
1. Declare a small hash/dictionary of key-value pairs
Ruby:

person = &#123; 
  [...]]]></description>
			<content:encoded><![CDATA[<p>&#8230;be prepared to write a lot more code than in your typical &#8220;scripting&#8221; language. Three examples (I am using Ruby for comparison because it is the scripting language I am most familiar with; things would look very much the same with Python or PHP):</p>
<h3>1. Declare a small hash/dictionary of key-value pairs</h3>
<p><strong>Ruby:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">person = <span style="color:#006600; font-weight:bold;">&#123;</span> 
  <span style="color:#ff3333; font-weight:bold;">:name</span>           <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;John Appleseed&quot;</span>, 
  <span style="color:#ff3333; font-weight:bold;">:age</span>            <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">30</span>, 
  <span style="color:#ff3333; font-weight:bold;">:favorite_fruit</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span> <span style="color:#996600;">&quot;apple&quot;</span>, <span style="color:#996600;">&quot;banana&quot;</span>, <span style="color:#996600;">&quot;kiwi&quot;</span> <span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p><strong>Cocoa:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>person <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDictionary</span> dictionaryWithObjectsAndKeys<span style="color: #002200;">:</span>
                        <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;John Appleseed&quot;</span>,               <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;name&quot;</span>,
                        <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithInteger<span style="color: #002200;">:</span><span style="color: #2400d9;">30</span><span style="color: #002200;">&#93;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;age&quot;</span>,
                        <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSArray</span> arrayWithObjects<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;apple&quot;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;banana&quot;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;kiwi&quot;</span>, <span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>,
                                                         <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;favoriteFruit&quot;</span>,
                        <span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>Now which of these is easier to read?</p>
<h3>2. What day of the month is today?</h3>
<p><strong>Ruby:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">today = <span style="color:#CC00FF; font-weight:bold;">Date</span>.<span style="color:#9900CC;">today</span>                       <span style="color:#008000; font-style:italic;"># =&gt; #&lt;Date: 4910525/2,0,2299161&gt;</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Day of the month: %d&quot;</span> <span style="color:#006600; font-weight:bold;">%</span> today.<span style="color:#9900CC;">day</span>  <span style="color:#008000; font-style:italic;"># =&gt; Day of the month: 7</span></pre></div></div>

<p><strong>Cocoa:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSDate</span> <span style="color: #002200;">*</span>today <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDate</span> date<span style="color: #002200;">&#93;</span>;                        <span style="color: #11740a; font-style: italic;">// =&gt; 2010-03-07 15:15:26 +0100</span>
<span style="color: #400080;">NSCalendar</span> <span style="color: #002200;">*</span>calendar <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSCalendar</span> currentCalendar<span style="color: #002200;">&#93;</span>;  <span style="color: #11740a; font-style: italic;">// =&gt; &lt;__NSCFCalendar: 0x100400160&gt;</span>
<span style="color: #400080;">NSDateComponents</span> <span style="color: #002200;">*</span>components <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>calendar components<span style="color: #002200;">:</span>NSDayCalendarUnit
                                           fromDate<span style="color: #002200;">:</span>today<span style="color: #002200;">&#93;</span>;
NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Day of the month: %d&quot;</span>, <span style="color: #002200;">&#91;</span>components day<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;     <span style="color: #11740a; font-style: italic;">// =&gt; Day of the month: 7</span></pre></div></div>

<h3>3. Fetch something from the data store</h3>
<p><strong>Ruby on Rails (Active Record):</strong></p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">result = Person.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span>, <span style="color:#ff3333; font-weight:bold;">:conditions</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:first_name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;John&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>, <span style="color:#ff3333; font-weight:bold;">:order</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;created_at DESC&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p><strong>Cocoa (Core Data):</strong></p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSFetchRequest</span> <span style="color: #002200;">*</span>fetchRequest <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSFetchRequest</span> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #400080;">NSEntityDescription</span> <span style="color: #002200;">*</span>entity <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSEntityDescription</span> entityForName<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Person&quot;</span> inManagedObjectContext<span style="color: #002200;">:</span>self.managedObjectContext<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>fetchRequest setEntity<span style="color: #002200;">:</span>entity<span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #400080;">NSPredicate</span> <span style="color: #002200;">*</span>predicate <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSPredicate</span> predicateWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;firstName == %@&quot;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;John&quot;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>fetchRequest setPredicate<span style="color: #002200;">:</span>predicate<span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #400080;">NSSortDescriptor</span> <span style="color: #002200;">*</span>sortDescriptor <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSSortDescriptor</span> alloc<span style="color: #002200;">&#93;</span> initWithKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;creationDate&quot;</span> ascending<span style="color: #002200;">:</span><span style="color: #a61390;">NO</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>fetchRequest setSortDescriptors<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSArray</span> arrayWithObject<span style="color: #002200;">:</span>sortDescriptor<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>sortDescriptor release<span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>fetchError <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
<span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>fetchResult <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self.managedObjectContext executeFetchRequest<span style="color: #002200;">:</span>fetchRequest error<span style="color: #002200;">:&amp;</span>error<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>fetchRequest release<span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>Now I know this is not a fair comparison, Objective-C/Cocoa has many advantages over Ruby et al., you can&#8217;t compare Core Data to Active Record, etc. Still, I find the differences very striking, especially regarding the readability of the code.</p>
<img src="http://feeds.feedburner.com/~r/ole-begemann-dev-blog/~4/yKSQORYDnE4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://oleb.net/blog/2010/03/if-you-want-to-learn-cocoa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://oleb.net/blog/2010/03/if-you-want-to-learn-cocoa/</feedburner:origLink></item>
		<item>
		<title>Porting RRGlossCausticShader to the iPhone</title>
		<link>http://feedproxy.google.com/~r/ole-begemann-dev-blog/~3/-PGpupdKjzI/</link>
		<comments>http://oleb.net/blog/2010/02/porting-rrglosscausticshader-to-the-iphone/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 18:02:29 +0000</pubDate>
		<dc:creator>Ole Begemann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://oleb.net/?p=378</guid>
		<description><![CDATA[In September 2008, Matt Gallagher published Drawing gloss gradients in CoreGraphics, a very nice piece of code “that will draw a ‘gloss’ gradient in a single statement. All colors in the gradient are calculated from the single color parameter.”
Roy Ratcliffe later complemented Matt’s article with a generalized Objective-C class called RRGlossCausticShader that exposes a number [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_380" class="wp-caption alignright" style="width: 280px"><a href="http://oleb.net/wordpress/wp-content/media/gloss-caustic-shader-screenshot.png"><img class="size-full wp-image-380 " title="Screenshot of the iPhone sample app for the gloss caustic shader" src="http://oleb.net/wordpress/wp-content/media/gloss-caustic-shader-screenshot.png" alt="Screenshot of the iPhone sample app for the gloss caustic shader" width="270" height="519" /></a><p class="wp-caption-text">Screenshot of the iPhone sample app for the gloss caustic shader</p></div>
<p>In September 2008, Matt Gallagher published <a href="http://cocoawithlove.com/2008/09/drawing-gloss-gradients-in-coregraphics.html">Drawing gloss gradients in CoreGraphics</a>, a very nice piece of code “that will draw a ‘gloss’ gradient in a single statement. All colors in the gradient are calculated from the single color parameter.”</p>
<p>Roy Ratcliffe later <a href="http://blog.pioneeringsoftware.co.uk/2008/12/09/gloss-caustic-shading">complemented Matt’s article</a> with a generalized Objective-C class called <code>RRGlossCausticShader</code> that exposes a number of parameters to modify the gloss effect to your liking. <a href="http://github.com/royratcliffe/gloss-caustic-shader/tree/master">Roy’s code</a> also includes a nice OS X sample application that helps visualizing the effects of parameter changes on the final result.</p>
<p>Unfortunately, neither Matt’s original version nor Roy’s refactoring work on the iPhone out of the box, mainly because they rely on <a href="https://developer.apple.com/mac/library/documentation/Cocoa/Reference/ApplicationKit/Classes/NSColor_Class/Reference/Reference.html">NSColor</a>, which is only available on the Mac platform. I recently ported Roy’s code to the iPhone and also wrote a little iPhone sample app for it.</p>
<p>Porting was fairly easy:</p>
<ul>
<li>Use conditional compilation (<code>#if TARGET_OS_IPHONE</code>) to substitute <a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIColor_Class/index.html">UIColor</a> for NSColor.</li>
<li>Add some functionality that NSColor has but UIColor lacks, namely getting individual color component values and converting colors between RGB and HSB.</li>
</ul>
<p>For the iPhone sample app, I wanted to do a little more than just copy the existing OS X app, so I added a button to print the shader’s current settings to the debugger console. That way, you can play with the sliders until you find a shading you like and then just copy and paste the code from the console to your project to configure the shader with the correct settings. The app will also save the current settings to the user defaults on exit.</p>
<div id="attachment_381" class="wp-caption alignnone" style="width: 330px"><a href="http://oleb.net/wordpress/wp-content/media/gloss-caustic-shader-settings-console-screenshot.png"><img class="size-medium wp-image-381 " title="You can print the gloss caustic shader's current settings to the debugger console and copy and paste them into your code from there." src="http://oleb.net/wordpress/wp-content/media/gloss-caustic-shader-settings-console-screenshot-320x274.png" alt="Screenshot of the debugger console with the iPhone gloss caustic shader sample app running." width="320" height="274" /></a><p class="wp-caption-text">You can print the gloss caustic shader&#39;s current settings to the debugger console and copy and paste them into your code from there.</p></div>
<p>Here are a few example shadings that can be created with <code>RRGlossCausticShader</code>:</p>
<p><img class="alignnone size-full wp-image-389" title="Gloss caustic shader examples" src="http://oleb.net/wordpress/wp-content/media/gloss-caustic-shader-examples.png" alt="Gloss caustic shader examples" width="562" height="56" /></p>
<p>The code is available <a href="http://github.com/ole/gloss-caustic-shader">on my GitHub account</a>. I will also contact Roy and ask him to incorporate my modifications into his repository. Both his code and mine are released under the liberal MIT license.</p>
<img src="http://feeds.feedburner.com/~r/ole-begemann-dev-blog/~4/-PGpupdKjzI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://oleb.net/blog/2010/02/porting-rrglosscausticshader-to-the-iphone/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://oleb.net/blog/2010/02/porting-rrglosscausticshader-to-the-iphone/</feedburner:origLink></item>
		<item>
		<title>Book Review: Coders at Work</title>
		<link>http://feedproxy.google.com/~r/ole-begemann-dev-blog/~3/KOVlGpc57rM/</link>
		<comments>http://oleb.net/blog/2010/02/book-review-coders-at-work/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 17:53:14 +0000</pubDate>
		<dc:creator>Ole Begemann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://oleb.net/?p=329</guid>
		<description><![CDATA[ In 2007, Jessica Livingston wrote a book called Founders at Work, in which she interviewed a number of tech entrepeneurs about their experiences in the early days of their startups. I enjoyed that book very much, and so I was quite excited to see that Peter Seibel recently wrote what could be called the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.com/Coders-at-Work-Peter-Seibel/dp/1430219483/"><img class="size-thumbnail wp-image-366 alignright" title="Coders at Work book cover" src="http://oleb.net/wordpress/wp-content/media/coders-at-work-cover-133x200.jpg" alt="Coders at Work book cover" width="133" height="200" /></a> In 2007, Jessica Livingston wrote a book called <a href="http://www.amazon.com/Founders-Work-Stories-Startups-Problem-Solution/dp/1430210788/">Founders at Work</a>, in which she interviewed a number of tech entrepeneurs about their experiences in the early days of their startups. I enjoyed that book very much, and so I was quite excited to see that <a href="http://www.gigamonkeys.com/blog/">Peter Seibel</a> recently wrote what could be called the second part of what I hope will be a series of interview books. Instead of founders, this time it is all about programmers, and the title of the book is <a href="http://www.amazon.com/Coders-at-Work-Peter-Seibel/dp/1430219483/">Coders at Work: Reflections on the Craft of Programming</a> (released in late 2009).</p>
<p><em>Coders at Work</em> consists of extensive interviews (each interview some 40 pages long) with 15 of the best-known programmers of the last 4 decades:</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Jamie_Zawinski">Jamie Zawinski</a>, author of XEmacs and the Unix version of Netscape Navigator.</li>
<li><a href="http://en.wikipedia.org/wiki/Brad_Fitzpatrick">Brad Fitzpatrick</a>, creator of LiveJournal, author of memcached.</li>
<li><a href="http://en.wikipedia.org/wiki/Douglas_Crockford">Douglas Crockford</a>, creator of JSON.</li>
<li><a href="http://en.wikipedia.org/wiki/Brendan_Eich">Brendan Eich</a>, inventor of JavaScript.</li>
<li><a href="http://en.wikipedia.org/wiki/Joshua_Bloch">Joshua Bloch</a>, author of the Java Collections Framework.</li>
<li><a href="http://armstrongonsoftware.blogspot.com/">Joe Armstrong</a>, inventor of Erlang.</li>
<li><a href="http://en.wikipedia.org/wiki/Simon_Peyton_Jones">Simon Peyton Jones</a>, Co-creator of Haskell.</li>
<li><a href="http://en.wikipedia.org/wiki/Peter_Norvig">Peter Norvig</a>, Director of Research at Google.</li>
<li><a href="http://en.wikipedia.org/wiki/Guy_Steele">Guy Steele</a>, Co-designer of Scheme.</li>
<li><a href="http://en.wikipedia.org/wiki/Dan_Ingalls">Dan Ingalls</a>, principal creator of Smalltalk.</li>
<li><a href="http://en.wikipedia.org/wiki/L_Peter_Deutsch">L. Peter Deutsch</a>, author of Ghostscript and implementor of Smalltalk-80.</li>
<li><a href="http://en.wikipedia.org/wiki/Ken_Thompson">Ken Thompson</a>, creator of Unix.</li>
<li><a href="http://en.wikipedia.org/wiki/Frances_E._Allen">Fran Allen</a>, pioneer in optimizing compilers.</li>
<li><a href="http://www.codersatwork.com/bernie-cosell.html">Bernie Cosell</a>, one of the guys who wrote the first routers (Interface Message Processors) for the Arpanet.</li>
<li><a href="http://en.wikipedia.org/wiki/Donald_Knuth">Donald Knuth</a>, über-father and creator of TeX.</li>
</ul>
<p>The interviews follow the same broad structure: Peter Seibel asks everyone how they got into programming; how they learned it in the first place and how they perfected their skills; which programming languages they like and which they hate; which editors, IDEs and debugging tools they use; how they approach the design of a program, top-down or bottom-up; etc. In addition to the general questions, Seibel digs deep into the projects his subjects are famous for: How did they end up working on these projects? What was it like? How was the project team organized? What did you learn? What were the hardest problems to solve, the fiercest bugs to squash?</p>
<p>To me, the greatest insight came from the interviewees’ reflections on their craft: How do they think about themselves and how do they personally practice programming? Despite having quite different backgrounds, it was interesting to discover that many of them had a common philosophy when it came to approaching programming.</p>
<p>For example, many mentioned their desire to take things apart, to understand how stuff works, as one of the prime impulses that brought them into the field. Also, motivation is a very important factor for learning, and personal side projects were often the ones where they learned the most. On the question whether it made sense to write the umpteenth C compiler or image processing library instead of just taking one that is already available, Joe Armstrong said:</p>
<blockquote><p>The really good programmers spend a lot of time programming. I haven’t seen very good programmers who don’t spend a lot of time programming. … And you get better at it—you get quicker at it. The side effect of writing all this other stuff [side projects] is that when you get to doing ordinary problems, you can do them very quickly.</p></blockquote>
<h3 id="the_importance_of_reading_and_writing">The importance of reading and writing</h3>
<p>When asked whether they, as a programmer, think of themselves as a scientist or an engineer or an artist or a craftsman, some said they felt most like a writer whose job is to formulate their thoughts so that their audience — which comprises both the computer <em>and</em> readers of the source code — understands them best. You want to become a great programmer? Write <em>a lot</em> of code! Jamie Zawinski:</p>
<blockquote><p>It feels like you’re writing a story and you’re trying to express a concept to a very dumb person—the computer—who has a limited vocabulary.</p></blockquote>
<p>Similarly, nearly everyone mentioned that reading code is as important as writing it. Many said that reading other people’s source code (written either by more-experienced co-workers or the code of well-known open source projects) was a formative experience for their development as a programmer. Still, it struck me that these experiences mostly came from accidental exposures to great pieces of code. Almost none of the 15 had made it a personal habit to explicitly grab the source of an interesting piece of software and read over it for both learning and fun. Or, as Joshua Bloch put it, “When was the last time you sat down at night to read a beautiful piece of code?”</p>
<p>Short of attacking monster projects like the Linux kernel, how do we find the good code that is worth reading, the code that makes us better programmers by studying it? I think there is a great opportunity for blogs and other websites here to research and present the truly great pieces of code in open source projects in an easy-to-digest and informative form. Perhaps Peter Seibel’s new project, <a href="http://www.gigamonkeys.com/blog/2010/02/18/gigamonkeys-quarterly.html">Gigamonkeys Quarterly</a>, could partly evolve into something like this.</p>
<h3 id="historical_quality">Historical quality</h3>
<p>One reviewer of the book on Amazon:</p>
<blockquote><p>There is also a historical quality to the book. The majority of the people interviewed started programming in the 50s or the early 60s. One of the standard questions was “How did you learn to program?” and I thought it was quite interesting to read about the old computers they used, the punch cards etc. It was almost like little history lessons from the computing field. — <a href="http://www.amazon.com/review/R2OV0TG7MJGXGL/">Henrik Warne</a></p></blockquote>
<p>While this is certainly true and nice, I felt that the book lacked a certain balance between the “old guys” and the young coders of today who learned programming on and for the Web. Brad Fitzpatrick is basically the only representative of the Web generation of programmers. I think including more of his generation could have given readers further insight on the learning and practice of programming today. This is especially so since many of the interviewees, having learned their craft decades ago, lamented the complexity of today’s hardware and software and how much harder it is today to dig deep into how things work at the most basic level. So how do people learn to program these days and how to they cope with the fact that they will never understand how the machine they are writing code for actually works? For instance, I would have liked to see <a href="http://en.wikipedia.org/wiki/David_Heinemeier_Hansson">David Heinemeier Hansson</a> included in the book.</p>
<h3 id="wrap_up">Wrap-up</h3>
<p>If you want to learn more about <em>Coders at Work</em>, Peter Seibel talked about it on <a href="http://blog.stackoverflow.com/2009/09/podcast-69/">episode #69 of the Stack Overflow podcast</a>. He also held a <a href="http://www.youtube.com/watch?v=pQy22qPH7i4">one-hour long speech at Google</a> where he talks about a few anecdotes and some of the topics he addresses in the book.</p>
<p>I found <em>Coders at Work</em> entertaining and inspiring. Reading the book has provided me with long lists of more books I want to read and programming languages I want to learn. Highly recommended <em>Coders at Work</em> for programmers; not recommended for non-programmers who want to learn more about programmers and programming.</p>
<p>Finally, my favorite quote from the book is by Peter Seibel himself:</p>
<blockquote><p>Speaking of writing intricate code, I’ve noticed that people who are too smart, in a certain dimension anyway, make the worst code. Because they can actually fit the whole thing in their head they can write these great reams of spaghetti code.</p></blockquote>
<img src="http://feeds.feedburner.com/~r/ole-begemann-dev-blog/~4/KOVlGpc57rM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://oleb.net/blog/2010/02/book-review-coders-at-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://oleb.net/blog/2010/02/book-review-coders-at-work/</feedburner:origLink></item>
		<item>
		<title>Book Review: Cocoa Design Patterns</title>
		<link>http://feedproxy.google.com/~r/ole-begemann-dev-blog/~3/HN3r3cSeXLQ/</link>
		<comments>http://oleb.net/blog/2010/01/book-review-cocoa-design-patterns/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 17:00:40 +0000</pubDate>
		<dc:creator>Ole Begemann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://oleb.net/?p=331</guid>
		<description><![CDATA[
Although I pointed out a minor mistake in the book in an earlier post, I highly recommend Erik M. Buck’s and Donald A. Yacktman’s Cocoa Design Patterns (released in late 2009) to every Cocoa programmer who has worked through one or more beginner books to Objective-C and the Cocoa framework.
Many ways to structure a book
Many [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.com/Cocoa-Design-Patterns-Erik-Buck/dp/0321535022/"><img class="size-thumbnail wp-image-361 alignleft" title="Cover of Cocoa Design Patterns by Erik M. Buck and Donald A. Yacktman" src="http://oleb.net/wordpress/wp-content/media/cocoa-design-patterns-cover-155x200.jpg" alt="" width="155" height="200" /></a></p>
<p>Although I <a href="http://oleb.net/blog/2009/11/mutable-properties-of-immutable-objects/">pointed out a minor mistake</a> in the book in an earlier post, I highly recommend Erik M. Buck’s and Donald A. Yacktman’s <a href="http://www.amazon.com/Cocoa-Design-Patterns-Erik-Buck/dp/0321535022/">Cocoa Design Patterns</a> (released in late 2009) to every Cocoa programmer who has worked through one or more beginner books to Objective-C and the Cocoa framework.</p>
<h3 id="many_ways_to_structure_a_book">Many ways to structure a book</h3>
<p>Many books about Cocoa introduce the framework’s features by talking about one class (or a group of related classes) per chapter and creating a small sample application to show how a programmer would integrate this class into their own project. An example is Aaron Hillegass’s wildly popular <a href="http://www.amazon.com/Cocoa-Programming-Mac-OS-3rd/dp/0321503619/">Cocoa Programming for Mac OS X</a>. After a general introduction to some of Cocoa’s key concepts, Hillegass mostly introduces specific features like <code>NSUndoManager</code>, window controllers, <code>NSUserDefaults</code>, table views, event handling etc. by explaining the class interfaces of these features and how to implement them. If a feature requires a further explanation how it works under the hood, this is worked into the flow of the chapter. This practical approach is a great way for programmers to learn how to use a framework like Cocoa (and <em>Cooca Programming for Mac OS X</em> is a very good book, everyone should read it). However, sometimes it can leave you a little in the dark about what is going on under the hood.</p>
<h3 id="how_does_it_work_and_why_did_they_design_it_this_way">How does it work and why did they design it this way?</h3>
<p>In contrast, <em>Cocoa Design Patterns</em> is built around the questions, <em>How does it work and why did they design it this way?</em>, with specific applications of the design patterns mentioned in the relevant places. Each chapter of the book is devoted to one specific design pattern and its implementation in Cocoa. This is especially beneficial because in Cocoa, many problems are solved a little differently than in other popular frameworks, partly due to the dynamic nature of Objective-C. The authors spend a great deal explaining the motivation behind both the patterns themselves and their implementation. If you have read the classic <a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612/">“Gang of Four” book</a> on design patterns, you will recognize most of the patterns (even if they often have different names), and this book is a perfect addition.</p>
<p>Here are a few of the patterns discussed in the book that I found most helpful:</p>
<ul>
<li>Model-View-Controller as the grand pattern that structures the entire framework.</li>
<li>Dynamic Creation of objects and the many places throughout the framework this feature of the Objective-C runtime is used, from scripting to unarchiving to plug-in architectures.</li>
<li>The ever-present Delegate pattern.</li>
<li>The target-action mechanism.</li>
<li>Invocations and their role in the undo/redo process.</li>
<li>The Flyweight pattern and how it is employed by <code>NSNumber</code> and <code>NSCell</code> to save memory and performance.</li>
<li>Proxies and Forwarding and how this can be used to implement Higher Order Messaging.</li>
</ul>
<p>The book is a little Mac-centric in that it does not specifically talk about the iPhone and some of the examples mentioned only apply to the Mac. That part is small, though, and I would say <em>Cocoa Design Patterns</em> is equally useful to iPhone developers. Again, highly recommended for intermediate Cocoa developers.</p>
<img src="http://feeds.feedburner.com/~r/ole-begemann-dev-blog/~4/HN3r3cSeXLQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://oleb.net/blog/2010/01/book-review-cocoa-design-patterns/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://oleb.net/blog/2010/01/book-review-cocoa-design-patterns/</feedburner:origLink></item>
		<item>
		<title>CHDataStructures on the iPhone</title>
		<link>http://feedproxy.google.com/~r/ole-begemann-dev-blog/~3/wQUWrezslF0/</link>
		<comments>http://oleb.net/blog/2009/12/chdatastructures-on-the-iphone/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 18:00:37 +0000</pubDate>
		<dc:creator>Ole Begemann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://oleb.net/?p=335</guid>
		<description><![CDATA[With NSArray, NSDictionary, NSSet and their subclasses, the Foundation framework provides a number of basic collection classes. If you need more specialized or advanced collection data structures, there is a good chance that Quinn Taylor&#8217;s CHDataStructures framework already has what you need. CHDataStructures is open source under a very liberal license and well-tested. It includes collection classes [...]]]></description>
			<content:encoded><![CDATA[<p>With NSArray, NSDictionary, NSSet and their subclasses, the <a href="http://developer.apple.com/mac/library/documentation/cocoa/Reference/Foundation/ObjC_classic/Intro/IntroFoundation.html">Foundation framework</a> provides a number of basic collection classes. If you need more specialized or advanced collection data structures, there is a good chance that Quinn Taylor&#8217;s <a href="http://cocoaheads.byu.edu/code/CHDataStructures">CHDataStructures framework</a> already has what you need. CHDataStructures is open source under a very liberal license and well-tested. It includes collection classes for different types of trees, specialized dictionaries and sets, linked lists, and many more.</p>
<p>I recently helped Quinn to make the CHDataStructures project iPhone-compatible. You can now grab the latest version from the repository and either build a static library to include in your iPhone projects or add the entire code to your project. The <a href="http://dysart.cs.byu.edu/chsvn/CHDataStructures/README.html">readme file</a> includes detailed installation instructions.</p>
<p>Even though CHDataStructures included virtually no OS X-specific code, we had to tweak the build configuration to make it work on the iPhone as seamlessly as possible:</p>
<ul>
<li>Unfortunately, Apple does not support <a href="http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WhatAreFrameworks.html">frameworks</a> (so useful!) or dynamic libraries on the iPhone, so we have to build a static libary (or include all the code directly in our iPhone projects). And since we are dealing with two different architectures (ARMv6 on the iPhone and i386 on the iPhone Simulator), we actually need to build different versions of the static library.</li>
<li><a href="http://developer.apple.com/mac/library/DOCUMENTATION/DeveloperTools/Conceptual/UnitTesting/0-Introduction/introduction.html">Unit Testing in Xcode</a> means that the tests are run from a script during the build phase and test results show up in Xcode&#8217;s Build Results window. This is great if you are developing for the same platform your development system runs on, which is usually the case (or close enough) if you write OS X apps. If you develop for the iPhone, your build runs on an Intel machine but you want your unit tests run against the ARM architecture. To accomplish this, you need a separate iPhone unit testing app that installs on the device, runs all unit tests upon launch, outputs the results to the console, and quits. Apple has <a title="iPhone Unit Testing Guide" href="http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iphone_development/135-Unit_Testing_Applications/unit_testing_applications.html#//apple_ref/doc/uid/TP40007959-CH20-SW6">a good how-to on this</a>.</li>
</ul>
<p>I highly recommend CHDataStructures to anyone who needs more than the standard collection classes.</p>
<img src="http://feeds.feedburner.com/~r/ole-begemann-dev-blog/~4/wQUWrezslF0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://oleb.net/blog/2009/12/chdatastructures-on-the-iphone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://oleb.net/blog/2009/12/chdatastructures-on-the-iphone/</feedburner:origLink></item>
		<item>
		<title>Mutable Properties of Immutable Objects</title>
		<link>http://feedproxy.google.com/~r/ole-begemann-dev-blog/~3/TWBLfPmGMz8/</link>
		<comments>http://oleb.net/blog/2009/11/mutable-properties-of-immutable-objects/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 21:30:25 +0000</pubDate>
		<dc:creator>Ole Begemann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://oleb.net/?p=333</guid>
		<description><![CDATA[Objects are called immutable if their state cannot be changed after initialization. While less flexible than their mutable counterparts, immutable objects have a lot of advantages. For instance, callers of a method that takes an immutable object as a parameter need not fear that the method might change the object. Also, thread safety is much [...]]]></description>
			<content:encoded><![CDATA[<p>Objects are called immutable if their state cannot be changed after initialization. While less flexible than their mutable counterparts, immutable objects have a lot of advantages. For instance, callers of a method that takes an immutable object as a parameter need not fear that the method might change the object. Also, thread safety is much easier to ensure if the objects shared by multiple threads are immutable.</p>
<p>For these and other reasons, it is often a good idea to make your own custom classes immutable, too. If you do so, it is important that all properties of your class also return immutable objects. I found an example of what not to do in the otherwise excellent book <a href="http://www.cocoadesignpatterns.com/">Cocoa Design Patterns</a> by Erik M. Buck and Donald A. Yacktman: on page 144, they define a class that has a read-only property returning an NSMutableDictionary:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> WordInformation <span style="color: #002200;">:</span> <span style="color: #400080;">NSObject</span>
<span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// ...</span>
    <span style="color: #400080;">NSMutableDictionary</span> <span style="color: #002200;">*</span>puzzleSpecificAttributes;
<span style="color: #002200;">&#125;</span>
<span style="color: #11740a; font-style: italic;">// ...</span>
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>readonly, copy<span style="color: #002200;">&#41;</span> <span style="color: #400080;">NSMutableDictionary</span> <span style="color: #002200;">*</span>puzzleSpecificAttributes;
&nbsp;
<span style="color: #a61390;">@end</span></pre></div></div>

<p>This totally defies the purpose of immutability. Even though the property itself is read-only, users of the class are free to modify the mutable dictionary that is returned by the class&#8217;s getter. If your class relies internally on the dictionary not being changed, things can get really ugly.</p>
<p>How do we avoid this? The public-facing property must be an NSDictionary:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>readonly<span style="color: #002200;">&#41;</span> <span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span>puzzleSpecificAttributes;</pre></div></div>

<p>But chances are that, internally, you would still like to keep the mutable dictionary. In that case, rename the instance variable so that it does not conflict with the name of the read-only property and, in the implementation of your class, write a custom getter that converts the mutable to an immutable dictionary:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@implementation</span> WordInformation
&nbsp;
@dynamic puzzleSpecificAttributes;
&nbsp;
<span style="color: #11740a; font-style: italic;">// ...</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSDictionary</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>puzzleSpecificAttributes <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// mutablePuzzleSpecificAttributes is the mutable instance variable</span>
    <span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDictionary</span> dictionaryWithDictionary<span style="color: #002200;">:</span>mutablePuzzleSpecificAttributes<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// ...</span>
<span style="color: #a61390;">@end</span></pre></div></div>

<img src="http://feeds.feedburner.com/~r/ole-begemann-dev-blog/~4/TWBLfPmGMz8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://oleb.net/blog/2009/11/mutable-properties-of-immutable-objects/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://oleb.net/blog/2009/11/mutable-properties-of-immutable-objects/</feedburner:origLink></item>
		<item>
		<title>OBShapedButton: Non-rectangular buttons on the iPhone</title>
		<link>http://feedproxy.google.com/~r/ole-begemann-dev-blog/~3/GlpX0b2n8qY/</link>
		<comments>http://oleb.net/blog/2009/10/obshapedbutton-non-rectangular-buttons-on-the-iphone/#comments</comments>
		<pubDate>Sat, 17 Oct 2009 16:53:47 +0000</pubDate>
		<dc:creator>Ole Begemann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://oleb.net/?p=322</guid>
		<description><![CDATA[UIButton has always been capable of displaying buttons with arbitrary non-rectangular shapes. All you have to do is use PNG images with alpha channels to define the transparent parts of the bounds rectangle.
While a button&#8217;s shape may be arbitrary, UIButton always responds to touches within its entire bounds, however. This could cause problems and confusion [...]]]></description>
			<content:encoded><![CDATA[<p><code><a title="UIButton Class Reference" href="http://www.devworld.apple.com/iphone/library/documentation/UIKit/Reference/UIButton_Class/UIButton/UIButton.html">UIButton</a></code> has always been capable of displaying buttons with arbitrary non-rectangular shapes. All you have to do is use PNG images with alpha channels to define the transparent parts of the bounds rectangle.</p>
<p>While a button&#8217;s shape may be arbitrary, UIButton always responds to touches within its entire bounds, however. This could cause problems and confusion for the users, especially when multiple non-rectangular buttons are placed close together so that their frames overlap.</p>
<p><code>OBShapedButton</code> is a replacement for UIButton that solves this issue. Instances of OBShapedButton only respond to touches where the button image is non-transparent. Here&#8217;s how to use it:</p>
<ul>
<li><a title="OBShapedButton repository on GitHub" href="http://github.com/ole/OBShapedButton">Get the code from GitHub</a>.</li>
<li>Add <code>OBShapedButton.h</code>, <code>OBShapedButton.m</code>, <code>UIImage+ColorAtPixel.h</code>, and <code>UIImage+ColorAtPixel.m</code> to your Xcode project.</li>
<li>Design your UI in Interface Builder with UIButtons as usual. Set the Button type to Custom and provide transparent PNG images for the different control states as needed.</li>
<li>In the Identity Inspector in Interface Builder, set the Class of the button to OBShapedButton.</li>
</ul>
<p>That&#8217;s it! Build and run the enclosed demo project to check it out. I am releasing this under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT license</a>.</p>
<img src="http://feeds.feedburner.com/~r/ole-begemann-dev-blog/~4/GlpX0b2n8qY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://oleb.net/blog/2009/10/obshapedbutton-non-rectangular-buttons-on-the-iphone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://oleb.net/blog/2009/10/obshapedbutton-non-rectangular-buttons-on-the-iphone/</feedburner:origLink></item>
		<item>
		<title>The Apple Symbols font: a great repository for iPhone button icons</title>
		<link>http://feedproxy.google.com/~r/ole-begemann-dev-blog/~3/uEdsib4G6gE/</link>
		<comments>http://oleb.net/blog/2009/10/apple-symbols-font-repository-for-iphone-icons/#comments</comments>
		<pubDate>Thu, 01 Oct 2009 15:30:44 +0000</pubDate>
		<dc:creator>Ole Begemann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://oleb.net/?p=300</guid>
		<description><![CDATA[For iPhone developers looking for icons to use in buttons, toolbars, navigation bars and tab bars, there are a few good resources available, for example Joseph Wain&#8217;s excellent (and free!) collection of 130 icons and Eddie Wilson&#8217;s set of 160 iPhone UI icons ($69). These are not only beautifully designed but also already have the [...]]]></description>
			<content:encoded><![CDATA[<p>For iPhone developers looking for icons to use in buttons, toolbars, navigation bars and tab bars, there are a few good resources available, for example Joseph Wain&#8217;s excellent (and free!) <a title="Glyphish: 130 free icons for iPhone applications" href="http://www.glyphish.com/">collection of 130 icons</a> and Eddie Wilson&#8217;s <a href="http://www.eddit.com/shop/iphone_ui_icon_set/">set of 160 iPhone UI icons</a> ($69). These are not only beautifully designed but also already have the right sizes and format for use in toolbars and tab bars.</p>
<p>If you are not afraid of making your own PNGs, there is another free and hidden treasure in every Mac OS X installation: the <a title="Wikipedia: Apple Symbols" href="http://en.wikipedia.org/wiki/Apple_Symbols">Apple Symbols</a> font. It contains many of the icons Apple uses in the built-in iPhone apps and makes them readily available for your own buttons.</p>
<h3>Background: standard buttons in the iPhone SDK</h3>
<p>The set of standard buttons that Apple ships with the iPhone SDK is quite limited in both number and context. For instance, the standard toolbar buttons can only be used inside a <code>UIBarButtonItem</code> on a toolbar or navigation bar. Now, this is a good thing, I hear you say, because it enforces consistent UIs. And I agree to a point. Specifically, I urge you to follow Apple&#8217;s Human Interface Guidelines and use the system-provided buttons for (and only for) <a title="iPhone Human Interface Guidelines: Standard Buttons for Use in Toolbars and Navigation Bars" href="http://developer.apple.com/iphone/library/documentation/UserExperience/Conceptual/MobileHIG/SystemProvided/SystemProvided.html#//apple_ref/doc/uid/TP40006556-CH15-SW14">their documented meanings</a> or you risk the rejection of your app.</p>
<div id="attachment_301" class="wp-caption aligncenter" style="width: 330px"><img class="size-full wp-image-301" title="iPhone Toolbar Icons" src="http://oleb.net/wordpress/wp-content/media/iphone-toolbar-icons.png" alt="Icons for buttons, toolbars/navigation bars and tab bars shipped with the iPhone SDK" width="320" height="480" /><p class="wp-caption-text">Icons for buttons, toolbars/navigation bars and tab bars shipped with the iPhone SDK</p></div>
<h3>Apple Symbols to the rescue</h3>
<p>If the standard buttons do not cover your needs or ff you need to use one of the standard toolbar buttons outside of a toolbar (in a simple <code>UIButton</code>, for example), you are out of luck. But Apple Symbols contains many more standard icons for your icon-making pleasure. Open the OS X Character Viewer in Glyph View, select the Apple Symbols font and scroll down to the very end of the Glyph Catalog:</p>
<div id="attachment_305" class="wp-caption aligncenter" style="width: 601px"><img class="size-full wp-image-305" title="Apple Symbols Font Glyphs Table" src="http://oleb.net/wordpress/wp-content/media/apple-symbols-font-glyphs-table.png" alt="The Apple Symbols font in Character Viewer" width="591" height="781" /><p class="wp-caption-text">The Apple Symbols font in Character Viewer</p></div>
<p>Making a button from one of these glyphs is as simple as inserting it into Photoshop or any other graphics software that can work with fonts, resizing it, and saving it as a transparent PNG. Use about 20⨉20 pixels for toolbar and navbar icons, and about 30⨉30 pixels for tab bar icons and other buttons.</p>
<h3>Am I allowed to do this?</h3>
<p>I am not a lawyer but I have not found any restrictions that would forbid the use of these glyphs in your apps. This is what the <a href="http://images.apple.com/legal/sla/docs/macosx106.pdf">Mac OS X license agreement</a> has to say about fonts:</p>
<blockquote><p>D. Fonts. Subject to the terms and conditions of this License, you may use the fonts included with the Apple Software to display and print content while running the Apple Software; however, you may only embed fonts in content if that is permitted by the embedding restrictions accompanying the font in question. These embedding restrictions can be found in the Font Book/Preview/Show Font Info panel.</p></blockquote>
<p>And Font Book lists no license or embedding restrictions for Apple Symbols:</p>
<p><img class="aligncenter size-full wp-image-308" title="Apple Symbols Font Info" src="http://oleb.net/wordpress/wp-content/media/apple-symbols-font-info.png" alt="Apple Symbols Font Info" width="435" height="247" /></p>
<img src="http://feeds.feedburner.com/~r/ole-begemann-dev-blog/~4/uEdsib4G6gE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://oleb.net/blog/2009/10/apple-symbols-font-repository-for-iphone-icons/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://oleb.net/blog/2009/10/apple-symbols-font-repository-for-iphone-icons/</feedburner:origLink></item>
		<item>
		<title>Updated iTunes Connect Financial Reports to HTML script</title>
		<link>http://feedproxy.google.com/~r/ole-begemann-dev-blog/~3/mrtPKiGvmIg/</link>
		<comments>http://oleb.net/blog/2009/09/updated-itunes-connect-financial-reports-to-html-script/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 21:21:00 +0000</pubDate>
		<dc:creator>Ole Begemann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://oleb.net/?p=283</guid>
		<description><![CDATA[A user of my iTunes Connect Financial Reports to HTML script notified me that the script did not work on the file format that Apple used for their Financial Reports until January, 2009. The fix was relatively simple so the new version should support both formats.
I used the occasion for a few more changes:

I renamed [...]]]></description>
			<content:encoded><![CDATA[<p>A user of my <a href="http://oleb.net/blog/2009/09/formatting-itunes-connect-financial-reports/">iTunes Connect Financial Reports to HTML script</a> notified me that the script did not work on the file format that Apple used for their Financial Reports until January, 2009. The fix was relatively simple so the new version should support both formats.</p>
<p>I used the occasion for a few more changes:</p>
<ul>
<li>I renamed the script to <code>itunesconnect2html.rb</code>.</li>
<li>I moved the HTML template to a separate file (instead of inlining the HTML code in the script), which makes the HTML much easier to customize and the code a lot cleaner. Win-win! <a href="http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/index.html">ERB</a> connects the two.</li>
<li>Added a <a href="http://github.com/ole/itunesconnect-financialreports/blob/master/README.txt">README.txt</a> with some documentation.</li>
<li>Fixed a bug that caused a crash when calling the script from another folder.</li>
<li>Moved the whole thing to GitHub.</li>
</ul>
<p>Please get <a href="http://github.com/ole/itunesconnect-financialreports">the updated code from GitHub</a>. I&#8217;d appreciate your feedback and/or bug reports.</p>
<img src="http://feeds.feedburner.com/~r/ole-begemann-dev-blog/~4/mrtPKiGvmIg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://oleb.net/blog/2009/09/updated-itunes-connect-financial-reports-to-html-script/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://oleb.net/blog/2009/09/updated-itunes-connect-financial-reports-to-html-script/</feedburner:origLink></item>
		<item>
		<title>Managing the Network Activity Indicator</title>
		<link>http://feedproxy.google.com/~r/ole-begemann-dev-blog/~3/uXutBqS1jeI/</link>
		<comments>http://oleb.net/blog/2009/09/managing-the-network-activity-indicator/#comments</comments>
		<pubDate>Thu, 10 Sep 2009 07:30:13 +0000</pubDate>
		<dc:creator>Ole Begemann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://oleb.net/?p=277</guid>
		<description><![CDATA[iPhone developers should use the little network activity indicator in the iPhone&#8217;s status bar to inform the user when their app accesses the network. Showing or hiding the indicator is simple:

&#91;&#91;UIApplication sharedApplication&#93; setNetworkActivityIndicatorVisible:YES&#93;;

Most people probably call this method from their view controllers. This works fine until you have to deal with multiple concurrent tasks that [...]]]></description>
			<content:encoded><![CDATA[<p>iPhone developers should use the little network activity indicator in the iPhone&#8217;s status bar to inform the user when their app accesses the network. Showing or hiding the indicator is simple:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIApplication sharedApplication<span style="color: #002200;">&#93;</span> setNetworkActivityIndicatorVisible<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>Most people probably call this method from their view controllers. This works fine until you have to deal with multiple concurrent tasks that access the network and/or multiple view controllers that are active simultaneously. For example, you might be running a HTTP request to download data from a webservice in the background and using a <code>MKMapView</code> instance that accesses the network whenever the user moves the map to a new location.</p>
<p>If you access the <code>networkActivityIndicatorVisible</code> property directly from multiple methods in these cases, chances are that you hide the indicator when the first task has finished even though your app continues to access the network. You would need to implement a counter to remember how often the network activity indicator has been shown and hidden to manage it correctly. If your code is spread among multiple view controllers, this gets even more cumbersome.</p>
<p>This &#8220;problem&#8221; is admittedly a small aspect of usability but the solution is so simple and elegant that I think it is worth doing even if you do not deal with multiple concurrent network activity tasks in your app.</p>
<p>Since the network activity indicator is displayed outside of your app&#8217;s window, the logical place to manage it is not a view controller but the application delegate. I have written a short method in my app delegate that uses a static variable to keep track of the number of times the activity indicator was asked to show or hide:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setNetworkActivityIndicatorVisible<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>setVisible <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">static</span> NSInteger NumberOfCallsToSetVisible <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>setVisible<span style="color: #002200;">&#41;</span> 
        NumberOfCallsToSetVisible<span style="color: #002200;">++</span>;
    <span style="color: #a61390;">else</span> 
        NumberOfCallsToSetVisible<span style="color: #002200;">--</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// The assertion helps to find programmer errors in activity indicator management.</span>
    <span style="color: #11740a; font-style: italic;">// Since a negative NumberOfCallsToSetVisible is not a fatal error, </span>
    <span style="color: #11740a; font-style: italic;">// it should probably be removed from production code.</span>
    NSAssert<span style="color: #002200;">&#40;</span>NumberOfCallsToSetVisible &gt;<span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Network Activity Indicator was asked to hide more often than shown&quot;</span><span style="color: #002200;">&#41;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Display the indicator as long as our static counter is &gt; 0.</span>
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIApplication sharedApplication<span style="color: #002200;">&#93;</span> setNetworkActivityIndicatorVisible<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>NumberOfCallsToSetVisible &gt; <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>This method alone is then responsible for the actual call to the <code>UIApplication</code> instance to show or hide the indicator. All view controllers call the method on the app delegate instead:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#40;</span>MyAppDelegate <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIApplication sharedApplication<span style="color: #002200;">&#93;</span> delegate<span style="color: #002200;">&#93;</span> setNetworkActivityIndicatorVisible<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;</pre></div></div>

<img src="http://feeds.feedburner.com/~r/ole-begemann-dev-blog/~4/uXutBqS1jeI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://oleb.net/blog/2009/09/managing-the-network-activity-indicator/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://oleb.net/blog/2009/09/managing-the-network-activity-indicator/</feedburner:origLink></item>
		<item>
		<title>Formatting iTunes Connect Financial Reports</title>
		<link>http://feedproxy.google.com/~r/ole-begemann-dev-blog/~3/w3-RG4bJ4Ak/</link>
		<comments>http://oleb.net/blog/2009/09/formatting-itunes-connect-financial-reports/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 10:00:07 +0000</pubDate>
		<dc:creator>Ole Begemann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://oleb.net/?p=264</guid>
		<description><![CDATA[Update 2009-09-23: There is an updated version of the script available. Please see the corresponding blog post and get the newest version of the code from GitHub.
The monthly financial reports Apple provides to iPhone developers in iTunes Connect are plain tab-separated text files. To print those reports for our tax accountants or the taxman, we [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update 2009-09-23: There is an updated version of the script available. Please <a href="http://oleb.net/blog/2009/09/updated-itunes-connect-financial-reports-to-html-script/">see the corresponding blog post</a> and <a href="http://github.com/ole/itunesconnect-financialreports">get the newest version of the code from GitHub</a>.</strong></p>
<p>The monthly financial reports Apple provides to iPhone developers in iTunes Connect are plain tab-separated text files. To print those reports for our tax accountants or the taxman, we must apply a little formatting. Since importing text files into a spreadsheet involves some manual work (some columns have to be marked as numeric or text) and I do not need to do further calculations with the data at the moment, I wrote a Ruby script that converts Apple&#8217;s text files into printable HTML tables.</p>
<p>To use the script, download all financial reports from iTunes Connect into a folder and run the script as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>financialreport_to_html.rb <span style="color: #000000; font-weight: bold;">*</span>.txt</pre></div></div>

<p>The script will create a .html file with the same name for every file you specify on the command line. You can use the <code>-o</code> option to force it to overwrite existing files.</p>
<p>The script uses a settings file in <a href="http://www.yaml.org/">YAML</a> format to configure things like column headings, column types and which columns to exclude from the formatted page (there&#8217;s a lot of columns to fit on one page). Have a look at <code>financialreport_to_html_settings.yaml</code> to see the available options.</p>
<p>The HTML template code, complete with CSS, is directly embedded in the script file. I opted for a simple table that looks good when printed but it should be easy for you to adapt the styling to your needs. The only thing you still have to do manually is to set your printer to landscape format as the page orientation cannot be specified in CSS.</p>
<p>The result looks like this:</p>
<div id="attachment_271" class="wp-caption aligncenter" style="width: 410px"><img class="size-full wp-image-271 " title="Output from financialreport_to_html.rb" src="http://oleb.net/wordpress/wp-content/media/financialreport_to_html-output-screenshot.png" alt="Output from financialreport_to_html.rb" width="400" height="282" /><p class="wp-caption-text">Output from financialreport_to_html.rb</p></div>
<p>Download the script: <span style="text-decoration: line-through;">financialreport_to_html.zip</span><a href="http://github.com/ole/itunesconnect-financialreports">Get the newest version from GitHub</a>. You can do whatever you want with it. I hope you find it useful.</p>
<img src="http://feeds.feedburner.com/~r/ole-begemann-dev-blog/~4/w3-RG4bJ4Ak" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://oleb.net/blog/2009/09/formatting-itunes-connect-financial-reports/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://oleb.net/blog/2009/09/formatting-itunes-connect-financial-reports/</feedburner:origLink></item>
		<item>
		<title>Songtext stopped working</title>
		<link>http://feedproxy.google.com/~r/ole-begemann-dev-blog/~3/bvBsA-Xf41U/</link>
		<comments>http://oleb.net/blog/2009/08/songtext-stopped-working/#comments</comments>
		<pubDate>Mon, 03 Aug 2009 09:17:50 +0000</pubDate>
		<dc:creator>Ole Begemann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[LyricWiki]]></category>
		<category><![CDATA[Songtext]]></category>

		<guid isPermaLink="false">http://oleb.net/?p=258</guid>
		<description><![CDATA[As of this morning, Songtext is no longer working. LyricWiki, the site Songtext obtained its lyrics from, was required by music publishers to cripple their API in such a way that apps like Songtext no longer have direct access to the lyrics. This effecticely breaks Songtext and many other iPhone lyrics apps that also used LyricWiki [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_259" class="wp-caption alignright" style="width: 232px"><img class="size-medium wp-image-259" title="Songtext displaying error message" src="http://oleb.net/wordpress/wp-content/media/songtext-stopped-working-screenshot-222x320.png" alt="Songtext displaying error message" width="222" height="320" /><p class="wp-caption-text">Songtext displaying error message</p></div>
<p>As of this morning, Songtext is no longer working. <a href="http://lyricwiki.org">LyricWiki</a>, the site Songtext obtained its lyrics from, was required by music publishers to cripple their <a href="http://en.wikipedia.org/wiki/API">API</a> in such a way that apps like Songtext <a href="http://groups.google.com/group/lyricwiki-api/browse_thread/thread/733ccd919d654040">no longer have direct access to the lyrics</a>. This effecticely breaks Songtext and many other iPhone lyrics apps that also used LyricWiki as their source.</p>
<p>I am very sorry to all users but at the moment there is nothing I (or LyricWiki) can do about this.</p>
<p>I would like to thank the guys at LyricWiki for their efforts in providing an API in the first place. And special thanks for providing users of Songtext and other apps with a clear error message that should minimize support requests for app developers:</p>
<blockquote><p>Unfortunately, due to licensing restrictions from some of the major music publishers we can no longer return lyrics through the LyricWiki API (where this application gets some or all of its lyrics).</p>
<p>The lyrics for this song can be found at the following URL: &#8230;</p>
<p>(Please note: this is not the fault of the developer who created this application, but is a restriction imposed by music publishers themselves.)</p></blockquote>
<p>I sincerely hope that the music publishers are working on a solution that would allow for the existence of lyrics apps in the future. The popularity of some of these apps clearly shows that there is a demand. Instead of only crippling third-party solutions, they should provide their own APIs (with their own licensing model if they feel they need to be compensated).</p>
<img src="http://feeds.feedburner.com/~r/ole-begemann-dev-blog/~4/bvBsA-Xf41U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://oleb.net/blog/2009/08/songtext-stopped-working/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://oleb.net/blog/2009/08/songtext-stopped-working/</feedburner:origLink></item>
		<item>
		<title>I removed Songtext from the App Store</title>
		<link>http://feedproxy.google.com/~r/ole-begemann-dev-blog/~3/Swj0DgaTGAE/</link>
		<comments>http://oleb.net/blog/2009/07/i-removed-songtext-from-the-app-store/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 22:24:52 +0000</pubDate>
		<dc:creator>Ole Begemann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://oleb.net/?p=247</guid>
		<description><![CDATA[As of today, Songtext is no longer available as I just removed it from the App Store.
Unfortunately, this also means that there will be no updates for existing users in the foreseeable future. Sorry.
I want to thank everybody who has downloaded Songtext in the last 2 weeks for your support and positive feedback. I hope [...]]]></description>
			<content:encoded><![CDATA[<p>As of today, Songtext is no longer available as I just removed it from the App Store.</p>
<p>Unfortunately, this also means that there will be no updates for existing users in the foreseeable future. Sorry.</p>
<p>I want to thank everybody who has downloaded Songtext in the last 2 weeks for your support and positive feedback. I hope you still enjoy using the app.</p>
<img src="http://feeds.feedburner.com/~r/ole-begemann-dev-blog/~4/Swj0DgaTGAE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://oleb.net/blog/2009/07/i-removed-songtext-from-the-app-store/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://oleb.net/blog/2009/07/i-removed-songtext-from-the-app-store/</feedburner:origLink></item>
		<item>
		<title>LyricWiki is down, Songtext showing errors</title>
		<link>http://feedproxy.google.com/~r/ole-begemann-dev-blog/~3/Dg0LNhETeXI/</link>
		<comments>http://oleb.net/blog/2009/07/lyricwiki-is-down-songtext-showing-errors/#comments</comments>
		<pubDate>Sun, 19 Jul 2009 10:21:24 +0000</pubDate>
		<dc:creator>Ole Begemann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[LyricWiki]]></category>
		<category><![CDATA[Songtext]]></category>

		<guid isPermaLink="false">http://oleb.net/?p=243</guid>
		<description><![CDATA[Sorry to all folks who are seeing the &#8220;Error loading lyrics&#8221; message in Songtext at the moment. LyricWiki, the site Songtext gets the lyrics from, is down this Sunday morning. I hope it will be back up soon and I will keep posting updates here.
I apologize that Songtext does not work at the moment but [...]]]></description>
			<content:encoded><![CDATA[<p>Sorry to all folks who are seeing the &#8220;Error loading lyrics&#8221; message in <a href="http://songtextapp.com">Songtext</a> at the moment. <a href="http://lyricwiki.org">LyricWiki</a>, the site Songtext gets the lyrics from, is down this Sunday morning. I hope it will be back up soon and I will keep posting updates here.</p>
<p>I apologize that Songtext does not work at the moment but unfortunately there is nothing I can do about it.</p>
<p><strong>Update July 19th, 2009, 16:00 CEST:</strong> LyricWiki is back up again after a downtime of about 5 hours. Songtext should be working again. Sorry again to everybody who got only error messages today.</p>
<img src="http://feeds.feedburner.com/~r/ole-begemann-dev-blog/~4/Dg0LNhETeXI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://oleb.net/blog/2009/07/lyricwiki-is-down-songtext-showing-errors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://oleb.net/blog/2009/07/lyricwiki-is-down-songtext-showing-errors/</feedburner:origLink></item>
		<item>
		<title>Lyrics apps for the iPhone: a market overview</title>
		<link>http://feedproxy.google.com/~r/ole-begemann-dev-blog/~3/1vKJqJVK80A/</link>
		<comments>http://oleb.net/blog/2009/07/iphone-lyrics-apps-market-overview/#comments</comments>
		<pubDate>Tue, 14 Jul 2009 17:45:47 +0000</pubDate>
		<dc:creator>Ole Begemann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[competition]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[lyrics]]></category>
		<category><![CDATA[market overview]]></category>
		<category><![CDATA[Songtext]]></category>

		<guid isPermaLink="false">http://oleb.net/?p=64</guid>
		<description><![CDATA[Update July 24, 2009: I removed this post because Songtext is no longer available on the App Store.
]]></description>
			<content:encoded><![CDATA[<p><em>Update July 24, 2009: I removed this post because </em><a href="http://oleb.net/blog/2009/07/i-removed-songtext-from-the-app-store/"><em>Songtext is no longer available on the App Store</em></a><em>.</em></p>
<img src="http://feeds.feedburner.com/~r/ole-begemann-dev-blog/~4/1vKJqJVK80A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://oleb.net/blog/2009/07/iphone-lyrics-apps-market-overview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://oleb.net/blog/2009/07/iphone-lyrics-apps-market-overview/</feedburner:origLink></item>
		<item>
		<title>The Music Player Framework in iPhone SDK 3.0</title>
		<link>http://feedproxy.google.com/~r/ole-begemann-dev-blog/~3/aalFKTnPX7A/</link>
		<comments>http://oleb.net/blog/2009/07/the-music-player-framework-in-the-iphone-sdk/#comments</comments>
		<pubDate>Mon, 13 Jul 2009 13:53:55 +0000</pubDate>
		<dc:creator>Ole Begemann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[iPhone SDK]]></category>

		<guid isPermaLink="false">http://oleb.net/blog/2009/07/the-music-player-framework-in-the-iphone-sdk/</guid>
		<description><![CDATA[
  In version 3.0 of the iPhone SDK, Apple gave us access to the iPod library on the iPhone and and easy-to-use interface to control music playback. In this post, I want to give an overview of these APIs and how I used them in the development of Songtext.

Getting started: MPMusicPlayerController

  You need [...]]]></description>
			<content:encoded><![CDATA[<p>
  In version 3.0 of the iPhone SDK, Apple gave us access to the iPod library on the iPhone and and easy-to-use interface to control music playback. In this post, I want to give an overview of these APIs and how I used them in the development of <a href="http://songtextapp.com" title="Songtext: Lyrics for the iPhone done right">Songtext</a>.
</p>
<h3>Getting started: MPMusicPlayerController</h3>
<p>
  You need to add <code>MediaPlayer.framework</code> to your target in Xcode and <code>#import &lt;MediaPlayer/MediaPlayer.h&gt;</code>. To control music playback, we use an instance of <code><a href="http://developer.apple.com/iphone/library/documentation/MediaPlayer/Reference/MPMusicPlayerController_ClassReference/Reference/Reference.html" title="MPMusicPlayerController Class Reference">MPMusicPlayerController</a></code>. There are two types of music players. The <code>iPodMusicPlayer</code> is a reference to the music player instance used by the iPod app. Any settings you change, such as the shuffle or repeat modes, will be changed in the iPod app, too. If the iPod is playing when your application starts, the music will continue playing and you can access the current song and skip back and forward through the currently active playlist. When your app quits, the music will continue playing. I imagine this mode is very handy for most utility apps that try to improve your music listening experience by interacting with the iPod.
</p>
<p>
  In contrast, <code>applicationMusicPlayer</code> gives you a music player whose settings you can change independently of the iPod app. This is probably the way to go if your app is a game and you want to give the user the ability to choose the background music from their library. In Songtext, we&#8217;ll use <code>iPodMusicPlayer</code> because we want to know which song is playing when our app launches:
</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> MPMusicPlayerController <span style="color: #002200;">*</span>musicPlayer;
...
self.musicPlayer <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>MPMusicPlayerController iPodMusicPlayer<span style="color: #002200;">&#93;</span>;</pre></div></div>

<p></code></p>
<p>
  The music player uses <a href="http://devworld.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNotification_Class/Reference/Reference.html" title="NSNotification Class Reference">notifications</a> to inform you about changes of:
</p>
<ul>
<li>the current song (<code>MPMusicPlayerControllerNowPlayingItemDidChangeNotification</code>),</li>
<li>the play/paused/stopped state (<code>MPMusicPlayerControllerPlaybackStateDidChangeNotification</code>), or</li>
<li>the volume (<code>MPMusicPlayerControllerVolumeDidChangeNotification</code>).</li>
</ul>
<p>
  So the next thing you typically do is to register yourself as an observer for the notifications you are interested in, e.g. in <code>viewDidLoad</code>. We want to receive all 3 notifications:
</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Register for music player notifications</span>
<span style="color: #400080;">NSNotificationCenter</span> <span style="color: #002200;">*</span>notificationCenter <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNotificationCenter</span> defaultCenter<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>notificationCenter addObserver<span style="color: #002200;">:</span>self 
                       selector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>handleNowPlayingItemChanged<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span>
                           name<span style="color: #002200;">:</span>MPMusicPlayerControllerNowPlayingItemDidChangeNotification 
                         object<span style="color: #002200;">:</span>self.musicPlayer<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>notificationCenter addObserver<span style="color: #002200;">:</span>self 
                       selector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>handlePlaybackStateChanged<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span>
                           name<span style="color: #002200;">:</span>MPMusicPlayerControllerPlaybackStateDidChangeNotification 
                         object<span style="color: #002200;">:</span>self.musicPlayer<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>notificationCenter addObserver<span style="color: #002200;">:</span>self 
                       selector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>handleExternalVolumeChanged<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span>
                           name<span style="color: #002200;">:</span>MPMusicPlayerControllerVolumeDidChangeNotification 
                         object<span style="color: #002200;">:</span>self.musicPlayer<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>self.musicPlayer beginGeneratingPlaybackNotifications<span style="color: #002200;">&#93;</span>;</pre></div></div>

<p></code></p>
<p>
  There is one other related notification that is sent by the iPod media library when the contents of the library change, e.g. when you sync your device with iTunes. You must listen to this notification if your app creates its playlists that need to be updated after library changes. To do so, register yourself as an observer for <code>MPMediaLibraryDidChangeNotification</code> notifications and call:
</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>MPMediaLibrary defaultMediaLibrary<span style="color: #002200;">&#93;</span> beginGeneratingLibraryChangeNotifications<span style="color: #002200;">&#93;</span></pre></div></div>

<p></code></p>
<p>
  The notification handlers are where you update your UI in response to changes in the player&#8217;s state:
</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// When the now playing item changes, update song info labels and artwork display.</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>handleNowPlayingItemChanged<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>notification <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// Ask the music player for the current song.</span>
    MPMediaItem <span style="color: #002200;">*</span>currentItem <span style="color: #002200;">=</span> self.musicPlayer.nowPlayingItem;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Display the artist, album, and song name for the now-playing media item.</span>
    <span style="color: #11740a; font-style: italic;">// These are all UILabels.</span>
    self.songLabel.text   <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>currentItem valueForProperty<span style="color: #002200;">:</span>MPMediaItemPropertyTitle<span style="color: #002200;">&#93;</span>;
    self.artistLabel.text <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>currentItem valueForProperty<span style="color: #002200;">:</span>MPMediaItemPropertyArtist<span style="color: #002200;">&#93;</span>;
    self.albumLabel.text  <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>currentItem valueForProperty<span style="color: #002200;">:</span>MPMediaItemPropertyAlbumTitle<span style="color: #002200;">&#93;</span>;    
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Display album artwork. self.artworkImageView is a UIImageView.</span>
    CGSize artworkImageViewSize <span style="color: #002200;">=</span> self.artworkImageView.bounds.size;
    MPMediaItemArtwork <span style="color: #002200;">*</span>artwork <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>currentItem valueForProperty<span style="color: #002200;">:</span>MPMediaItemPropertyArtwork<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>artwork <span style="color: #002200;">!=</span> <span style="color: #a61390;">nil</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        self.artworkImageView.image <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>artwork imageWithSize<span style="color: #002200;">:</span>artworkImageViewSize<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #002200;">&#123;</span>
        self.artworkImageView.image <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// When the playback state changes, set the play/pause button appropriately.</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>handlePlaybackStateChanged<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>notification <span style="color: #002200;">&#123;</span>
    MPMusicPlaybackState playbackState <span style="color: #002200;">=</span> self.musicPlayer.playbackState;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>playbackState <span style="color: #002200;">==</span> MPMusicPlaybackStatePaused || playbackState <span style="color: #002200;">==</span> MPMusicPlaybackStateStopped<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #002200;">&#91;</span>self.playPauseButton setTitle<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Play&quot;</span> forState<span style="color: #002200;">:</span>UIControlStateNormal<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span> <span style="color: #a61390;">else</span> <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>playbackState <span style="color: #002200;">==</span> MPMusicPlaybackStatePlaying<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #002200;">&#91;</span>self.playPauseButton setTitle<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Pause&quot;</span> forState<span style="color: #002200;">:</span>UIControlStateNormal<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// When the volume changes, sync the volume slider</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>handleExternalVolumeChanged<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>notification <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// self.volumeSlider is a UISlider used to display music volume.</span>
    <span style="color: #11740a; font-style: italic;">// self.musicPlayer.volume ranges from 0.0 to 1.0.</span>
    <span style="color: #002200;">&#91;</span>self.volumeSlider setValue<span style="color: #002200;">:</span>self.musicPlayer.volume animated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p></code></p>
<h3>Accessing song metadata: MPMediaItem</h3>
<div id="attachment_111" class="wp-caption alignright" style="width: 223px"><img src="http://oleb.net/wordpress/wp-content/media/MPMediaPickerController-single-selection-mode-213x320.png" alt="MPMediaPickerController in single-selection mode" title="MPMediaPickerController in single-selection mode" width="213" height="320" class="size-medium wp-image-111"><p class="wp-caption-text">MPMediaPickerController in single-selection mode. Unfortunately, Apple does not provide context information about the selected song.</p></div>
<p>
  A song is represented by an instance of the <code><a href="http://developer.apple.com/iphone/library/documentation/MediaPlayer/Reference/MPMediaItem_ClassReference/Reference/Reference.html" title="MPMediaItem Class Reference">MPMediaItem</a></code> class. As you see in the code above, we access the song metadata with the <code>valueForProperty:</code>method. Available properties include pretty much all the data that is available in iTunes: title, artist, album title and artist, genre, composer, duration, track/disc number, album artwork, rating, lyrics, last played date, and play and skip counts. The <a href="http://developer.apple.com/iphone/library/documentation/MediaPlayer/Reference/MPMediaItem_ClassReference/Reference/Reference.html#//apple_ref/doc/constant_group/General_Media_Item_Property_Keys">complete list of properties</a> is available in the documentation. That&#8217;s a huge amount of data for all kinds of interesting statistics or organizing apps. I am sure we will see a lot of those on the App Store in the coming months.
</p>
<h4>No write access to iPod library</h4>
<p>
  Unfortunately, we won&#8217;t see apps that require write access to the iPod library anytime soon. The entire <code>MPMediaItem</code> API is read-only at the moment. That is also the reason why Songtext cannot write the lyrics it downloads into the song files themselves to make them available outside the application. I hope Apple gives us write access in a future version of the SDK.
</p>
<h4>Unreliable access to lyrics</h4>
<p>
  While <code>MPMediaItem</code> provides access to the lyrics of a song stored in the iTunes library, I found this to be unreliable. Songtext checks if a song already has lyrics attached and if so, does not try to download them from the web. Unfortunately, this does not work all the time as sometimes, <code>-[MPMediaItem valueForProperty:MPMediaItemPropertyLyrics]</code> returns <code>nil</code> even if lyrics are present. I was not able to reproduce the exact conditions under which this error occurs. So beware if you rely on this to work properly.
</p>
<h3>A song selection UI: MPMediaPickerController</h3>
<p>
  Similar to the built-in image picker, Apple provides a complete user interface to select songs from the media library. All we need to do is create an instance of <code><a href="http://developer.apple.com/iphone/library/documentation/MediaPlayer/Reference/MPMediaPickerController_ClassReference/Reference/Reference.html" title="MPMediaPickerController Class Reference">MPMediaPickerController</a></code>, present it to the user as a modal view controller and implement the <code><a href="http://developer.apple.com/iphone/library/documentation/MediaPlayer/Reference/MPMediaPickerControllerDelegate_ProtocolReference/Reference/Reference.html" title="MPMediaPickerControllerDelegate Protocol Reference">MPMediaPickerControllerDelegate</a></code> protocol:
</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// MusicPlayerDemoViewController.h</span>
<span style="color: #a61390;">@interface</span> MusicPlayerDemoViewController <span style="color: #002200;">:</span> UIViewController <span style="color: #002200;">&amp;</span>lt;MPMediaPickerControllerDelegate<span style="color: #002200;">&amp;</span>gt; <span style="color: #002200;">&#123;</span>
...
<span style="color: #002200;">&#125;</span>
...
<span style="color: #11740a; font-style: italic;">// This action should open the media picker</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>openMediaPicker<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender;
<span style="color: #a61390;">@end</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// MusicPlayerDemoViewController.m</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>openMediaPicker<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender <span style="color: #002200;">&#123;</span>
    MPMediaPickerController <span style="color: #002200;">*</span>mediaPicker <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>MPMediaPickerController alloc<span style="color: #002200;">&#93;</span> initWithMediaTypes<span style="color: #002200;">:</span>MPMediaTypeMusic<span style="color: #002200;">&#93;</span>;
    mediaPicker.delegate <span style="color: #002200;">=</span> self;
    mediaPicker.allowsPickingMultipleItems <span style="color: #002200;">=</span> <span style="color: #a61390;">NO</span>; <span style="color: #11740a; font-style: italic;">// this is the default   </span>
    <span style="color: #002200;">&#91;</span>self presentModalViewController<span style="color: #002200;">:</span>mediaPicker animated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>mediaPicker release<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>                                   
&nbsp;
<span style="color: #11740a; font-style: italic;">// Media picker delegate methods</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>mediaPicker<span style="color: #002200;">:</span> <span style="color: #002200;">&#40;</span>MPMediaPickerController <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>mediaPicker didPickMediaItems<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>MPMediaItemCollection <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>mediaItemCollection <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// We need to dismiss the picker</span>
  <span style="color: #002200;">&#91;</span>self dismissModalViewControllerAnimated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #11740a; font-style: italic;">// Assign the selected item(s) to the music player and start playback.</span>
  <span style="color: #002200;">&#91;</span>self.musicPlayer stop<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>self.musicPlayer setQueueWithItemCollection<span style="color: #002200;">:</span>mediaItemCollection<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>self.musicPlayer play<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>mediaPickerDidCancel<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>MPMediaPickerController <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>mediaPicker <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// User did not select anything</span>
    <span style="color: #11740a; font-style: italic;">// We need to dismiss the picker</span>
    <span style="color: #002200;">&#91;</span>self dismissModalViewControllerAnimated<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p></code></p>
<h3>Limitations of the media picker</h3>
<div id="attachment_110" class="wp-caption alignright" style="width: 223px"><img src="http://oleb.net/wordpress/wp-content/media/MPMediaPickerController-multiple-selection-mode-213x320.png" alt="MPMediaPickerController in multiple-selection mode" title="MPMediaPickerController in multiple-selection mode" width="213" height="320" class="size-medium wp-image-110"><p class="wp-caption-text">MPMediaPickerController in multiple-selection mode. This works like the editing of the On-The-Go playlist in the iPod app.</p></div>
<p>
  This is all great and simple. The media picker has one huge drawback, though: it does not provide the context from which a song was picked. It is impossible to tell whether the user selected a song from a certain playlist, from an album, or from the Songs tab. All you get back is the single MPMediaItem the user tapped. Therefore, we cannot construct a play queue in the way the iPod does, depending on the context from which the user picked the song. The Next/Previous buttons will not work as expected anymore, and the user would have to pick another song each time the current one ends (the player will just stop at the end of the song). I think this can be very confusing for the user because your app functions differently, depending on whether the user selected a song in the iPod or directly in your app. And that is the reason why Songtext does not have the capability of selecting a new song from inside the app at the moment. Let&#8217;s hope Apple improves the media picker in the future.
</p>
<p>
  The media picker also has a multiple selection mode that can be enabled by setting its <code>allowsPickingMultipleItems</code> property to <code>YES</code>. This mode works like the editing of the On-The-Go playlist in the iPod app and can also be quite confusing for the user in my opinion.
</p>
<h3>Querying the iPod library with MPMediaQuery</h3>
<p>
  If you want to build a custom media picker UI or select songs programmatically without user interaction, you can do so by building queries with <code><a href="http://developer.apple.com/iphone/library/documentation/MediaPlayer/Reference/MPMediaQuery_ClassReference/Reference/Reference.html" title="MPMediaQuery Class Reference">MPMediaQuery</a></code> and <code><a href="http://developer.apple.com/iphone/library/documentation/MediaPlayer/Reference/MPMediaPropertyPredicate_ClassReference/Reference/Reference.html" title="MPMediaPropertyPredicate Class Reference">MPMediaPropertyPredicate</a></code>. I will cover these classes in a future post.
</p>
<h3>Download the demo project</h3>
<p>
  I have prepared a little demo project that implements most of the things I have talked about in this post: <a href="http://oleb.net/wordpress/wp-content/media/MusicPlayerDemo.zip">Download MusicPlayerDemo.zip</a>. You can do whatever you want with the code, no strings attached.</p>
<img src="http://feeds.feedburner.com/~r/ole-begemann-dev-blog/~4/aalFKTnPX7A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://oleb.net/blog/2009/07/the-music-player-framework-in-the-iphone-sdk/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://oleb.net/blog/2009/07/the-music-player-framework-in-the-iphone-sdk/</feedburner:origLink></item>
		<item>
		<title>Announcing Songtext: Lyrics for the iPhone</title>
		<link>http://feedproxy.google.com/~r/ole-begemann-dev-blog/~3/ztAxgiANZ8c/</link>
		<comments>http://oleb.net/blog/2009/07/announcing-songtext-lyrics-for-iphone/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 13:35:10 +0000</pubDate>
		<dc:creator>Ole Begemann</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[Songtext]]></category>

		<guid isPermaLink="false">http://oleb.net/?p=3</guid>
		<description><![CDATA[Yay! Songtext, my first iPhone app, got released last night. Songtext can download the lyrics for the songs you are listening to on your iPhone or iPod touch. It uses the huge database of LyricWiki, containing more than 700,000 songs. The price is $0.99. Check it out at songtextapp.com if you are interested or go right [...]]]></description>
			<content:encoded><![CDATA[<p>Yay! <a href="http://songtextapp.com">Songtext</a>, my first iPhone app, got released last night. Songtext can download the lyrics for the songs you are listening to on your iPhone or iPod touch. It uses the huge database of <a href="http://lyricwiki.org">LyricWiki</a>, containing more than 700,000 songs. The price is $0.99. Check it out at <a href="http://songtextapp.com">songtextapp.com</a> if you are interested or go <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=321171760&amp;mt=8">right to the the App Store</a>.</p>
<p><img class="alignnone size-full wp-image-340" title="iphone-screenshot-joshwoodward1" src="http://oleb.net/wordpress/wp-content/media/iphone-screenshot-joshwoodward1.png" alt="iphone-screenshot-joshwoodward1" width="220" height="470" /> <img class="size-full wp-image-12" title="iphone-songtext-screenshot-settings" src="http://oleb.net/wordpress/wp-content/media/iphone-songtext-screenshot-settings.png" alt="An iPhone displaying the Songtext settings page" width="220" height="470" /></p>
<p><em>Lyrics of the song &#8220;On Brevity&#8221; by </em><a href="http://www.joshwoodward.com/"><em>Josh Woodward</em></a><em> (</em><a href="http://creativecommons.org/licenses/by/3.0/us/"><em>License: Creative Commons Attribution</em></a><em>)</em></p>
<h3>Blogging about iPhone development</h3>
<p>To celebrate the occasion, I am starting this blog about software development. I plan to write about the lessons I learned during the development of Songtext and other projects I am working on. I am going to concentrate on the iPhone SDK, Cocoa, and Objective-C at first but might include more topics in the future.</p>
<p>I also plan to share my experiences as an individual developer for the iPhone platform, so expect posts about the App Store review process, the iPhone SDK community and my sales performance on the App Store.</p>
<img src="http://feeds.feedburner.com/~r/ole-begemann-dev-blog/~4/ztAxgiANZ8c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://oleb.net/blog/2009/07/announcing-songtext-lyrics-for-iphone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://oleb.net/blog/2009/07/announcing-songtext-lyrics-for-iphone/</feedburner:origLink></item>
	</channel>
</rss>
