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

<channel>
	<title>Cocoanetics &#187; Drops</title>
	<atom:link href="http://www.cocoanetics.com/author/drops/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cocoanetics.com</link>
	<description>Our DNA is written in Objective-C</description>
	<lastBuildDate>Wed, 08 Feb 2012 15:51:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>GeoCorder 1.3.2</title>
		<link>http://www.cocoanetics.com/2012/02/geocorder-1-3-2/</link>
		<comments>http://www.cocoanetics.com/2012/02/geocorder-1-3-2/#comments</comments>
		<pubDate>Wed, 08 Feb 2012 15:49:59 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Updates]]></category>
		<category><![CDATA[GeoCorder]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5937</guid>
		<description><![CDATA[Here&#8217;s another maintenance release fixing a crashing bug in the About section. Changes Fixed: Crash on trying to open usage instructions Added: More detailed explanation of accuracy and filter settings This update, like the one before it, goes out for the paid version of GeoCorder first. If the issues are resolved once this comes into the store then we&#8217;ll update the ad-sponsored version, too.]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/02/geocorder-1-3-2/"></g:plusone></div><p>Here&#8217;s another maintenance release fixing a crashing bug in the About section.</p>
<h3>Changes</h3>
<ul>
<li>Fixed: Crash on trying to open usage instructions</li>
<li>Added: More detailed explanation of accuracy and filter settings</li>
</ul>
<p>This update, like the one before it, goes out for the paid version of GeoCorder first. If the issues are resolved once this comes into the store then we&#8217;ll update the ad-sponsored version, too.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5937&amp;md5=36eb0acd6222cc4eff6f0b6fed224f40" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/02/geocorder-1-3-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5937&amp;md5=36eb0acd6222cc4eff6f0b6fed224f40" type="text/html" />"
	</item>
		<item>
		<title>DTRichTextEditor / DTCoreText News</title>
		<link>http://www.cocoanetics.com/2012/02/dtrichtexteditor-dtcoretext-news/</link>
		<comments>http://www.cocoanetics.com/2012/02/dtrichtexteditor-dtcoretext-news/#comments</comments>
		<pubDate>Wed, 08 Feb 2012 14:07:46 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Parts]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5929</guid>
		<description><![CDATA[You might have noticed &#8211; if you follow the DTCoreText project on GitHub &#8211; that I made many changes on this Open Source project. The most recent change was that somebody donated a CocoaPods spec for the project and thus forced me to give it a version number. The reason being that pods are usually pointing to a specific tag in a GitHub repository. This way people using the project via CocoaPods can be certain that they are getting a stable version. So I stumbled into this, but when trying to think of a good version number I could only come up with &#8220;1.0.0&#8243;. DTCoreText has matured sufficiently to call it that. Hey, earlier versions made it into quite a few popular apps, including Float. There are tons of performance improvements, additional features and most importantly the parser has been replaced with libxml2. This makes it both faster and able to deal with any kind of HTML you throw at it. DTCoreText has two parts: first it creates NSAttributedString instances from HTML, second it displays these properly. CATextLayer would be able to take attributed strings, but it ignores paragraph attributes and cannot draw images. DTCoreText  has an ingenious mechanism where you can supply your own UIViews for each attachment. Label Buy an ad here Attachments can be generic &#60;object&#62;s, &#60;video&#62;s or even &#60;img&#62;. DTCoreText takes care of the drawing and leaving some space and then tells you precisely the size you need to provide for your image views. Of course, if you don&#8217;t need any special treatments then images can also be drawn together with the text. What is the connection between DTCoreText and DTRichTextEditor? To make up a rich text editor you need multiple parts which are all in separate projects. To render the display: DTCoreText To accept text input, provide selection and show a loupe: DTRichTextEditor (which includes DTLoupeView) To copy and paste HTML: DTWebArchive DTRichTextEditor is being sold for €500 and includes DTLoupeView priced at €150. You can also purchase the Loupe separately if you don&#8217;t want to full text editing, but just the magnifier. DTWebArchive and DTCoreText are Open Source projects which you can use at no charge, provided that you credit Cocoanetics as authors. You can purchase Non-Attribution Licenses for €75 a piece so that you don&#8217;t have to mention us. Several people have asked me about the exact terms of these Non-Attribution Licenses. I introduced these as a way for developers to sponsor the ongoing development in exchange for not having to mention Cocoanetics in the app. You get a clear conscience and the good feeling to have supported something that saved you hours and hours of work. You get an invoice for your accountant so you can even expense this payment. But I have no way of checking if you do adhere to the terms, or if you use the components without attributing them properly. Hey, it is YOUR KARMA. If my Open Source projects save you a single hour of development time, then the investment in this license should be easily worth it. Of course I would be over the moon if somebody told me that he wanted to purchase 12 such licenses for 12 of his clients. Hey, do what you feel that is fair, ok? If you do the math you&#8217;ll find that this is indeed a bargain: DTCoreText &#8230; €75 DTWebArchive &#8230; €75 DTLoupeView &#8230; €150 DTRichTextEditor &#8230; €200 Something that you cannot get elsewhere &#8230; €500 Actually that gets me thinking, I should maybe increase the prices. I just convinced myself that this is all way too cheap&#8230; DTRichTextEditor Updated, Too Now with DTCoreText gone gold I also updated DTRichTextEditor to include all these great advances. The project too comes with a Demo app that shows how to interact with the component as well as demonstrates how to integrate the editor. The above mentioned components are sub-projects of this with the two Open Source ones being a clone of the GitHub repo on my Subversion server. Technically the demo (or your own app for that matter) only needs to link in the libDTRichTextEditor static library and copy the DTLoupe.bundle (containing the loupe images) into the app bundle. If you inspect the Demo settings you see how this is done. It is generally wise to add the items you need to the dependencies so that Xcode will know to refresh these if they are modified. In the linked libraries you see a heap of Apple frameworks and that we link in libxml2 as well as the static libDTRichTextEditor which aggregates the objects from the other three projects into one convenient library. HINT: There is one (non-obvious) maneuver you have to know to be able to get a resource bundle created in a sub-project in the list of bundle resources. You [...]]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/02/dtrichtexteditor-dtcoretext-news/"></g:plusone></div><p>You might have noticed &#8211; if you follow the DTCoreText project on GitHub &#8211; that I made many changes on this Open Source project. The most recent change was that somebody donated a CocoaPods spec for the project and thus forced me to give it a version number. The reason being that pods are usually pointing to a specific tag in a GitHub repository. This way people using the project via CocoaPods can be certain that they are getting a stable version.</p>
<p>So I stumbled into this, but when trying to think of a good version number I could only come up with &#8220;1.0.0&#8243;. DTCoreText has matured sufficiently to call it that. Hey, earlier versions made it into quite a few popular apps, <a title="Start Floating" href="http://www.cocoanetics.com/2011/07/start-floating/">including Float</a>. There are tons of performance improvements, additional features and most importantly the parser has been replaced with libxml2. This makes it both faster and able to deal with any kind of HTML you throw at it.</p>
<p>DTCoreText has two parts: first it creates NSAttributedString instances from HTML, second it displays these properly. CATextLayer would be able to take attributed strings, but it ignores paragraph attributes and cannot draw images. DTCoreText  has an ingenious mechanism where you can supply your own UIViews for each attachment.</p>
<p><span id="more-5929"></span></p>
<div class="inner_ad_block">
<div id="advman-7" class="widget Advman_Widget">
<h3 class="widgettitle"></h3>
<p><!-- BuySellAds.com Zone Code --></p>
<div id="bsap_1260346" class="bsarocks bsap_fc3166ea4a479e0fdb4251fbe92a1219"></div>
<p><!-- End BuySellAds.com Zone Code --></div>
<div id="text-21" class="widget widget_text">
<h3 class="widgettitle">Label</h3>
<div class="textwidget">
<div class="advert-notice"><a href="http://buysellads.com/buy/detail/56639/zone/1260346">Buy an ad here</a></div>
</div></div>
</div>
<p>Attachments can be generic &lt;object&gt;s, &lt;video&gt;s or even &lt;img&gt;. DTCoreText takes care of the drawing and leaving some space and then tells you precisely the size you need to provide for your image views. Of course, if you don&#8217;t need any special treatments then images can also be drawn together with the text.</p>
<h3>What is the connection between DTCoreText and DTRichTextEditor?</h3>
<p>To make up a rich text editor you need multiple parts which are all in separate projects.</p>
<ul>
<li>To render the display: <a href="https://github.com/Cocoanetics/DTCoreText">DTCoreText</a></li>
<li>To accept text input, provide selection and show a loupe: <a href="http://www.cocoanetics.com/parts/DTRichTextEditor/">DTRichTextEditor</a> (which includes <a href="http://www.cocoanetics.com/parts/DTLoupeView/">DTLoupeView</a>)</li>
<li>To copy and paste HTML: <a href="https://github.com/Cocoanetics/DTWebArchive">DTWebArchive</a></li>
</ul>
<p>DTRichTextEditor is being sold for €500 and includes DTLoupeView priced at €150. You can also purchase the Loupe separately if you don&#8217;t want to full text editing, but just the magnifier.</p>
<div>DTWebArchive and DTCoreText are Open Source projects which you can use at no charge, provided that you credit Cocoanetics as authors. You can purchase Non-Attribution Licenses for €75 a piece so that you don&#8217;t have to mention us.</div>
<p>Several people have asked me about the exact terms of these Non-Attribution Licenses. I introduced these as a way for developers to sponsor the ongoing development in exchange for not having to mention Cocoanetics in the app. You get a clear conscience and the good feeling to have supported something that saved you hours and hours of work. You get an invoice for your accountant so you can even expense this payment.</p>
<p>But I have no way of checking if you do adhere to the terms, or if you use the components without attributing them properly. Hey, it is YOUR KARMA. If my Open Source projects save you a single hour of development time, then the investment in this license should be easily worth it.</p>
<p>Of course I would be over the moon if somebody told me that he wanted to purchase 12 such licenses for 12 of his clients. Hey, do what you feel that is fair, ok?</p>
<p>If you do the math you&#8217;ll find that this is indeed a bargain:</p>
<p>DTCoreText &#8230; €75<br />
DTWebArchive &#8230; €75<br />
DTLoupeView &#8230; €150<br />
DTRichTextEditor &#8230; €200</p>
<p>Something that you cannot get elsewhere &#8230; €500</p>
<p>Actually that gets me thinking, I should maybe increase the prices. I just convinced myself that this is all way too cheap&#8230;</p>
<h3>DTRichTextEditor Updated, Too</h3>
<p>Now with DTCoreText gone gold I also updated DTRichTextEditor to include all these great advances. The project too comes with a Demo app that shows how to interact with the component as well as demonstrates how to integrate the editor. The above mentioned components are sub-projects of this with the two Open Source ones being a clone of the GitHub repo on my Subversion server.</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-02-08-um-2.30.53-PM.png"><img class="alignnone size-full wp-image-5932" title="DTRichTextEditor Externals" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-02-08-um-2.30.53-PM.png" alt="" width="286" height="602" /></a></p>
<p>Technically the demo (or your own app for that matter) only needs to link in the libDTRichTextEditor static library and copy the DTLoupe.bundle (containing the loupe images) into the app bundle. If you inspect the Demo settings you see how this is done.</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-02-08-um-2.38.19-PM.png"><img class="alignnone size-full wp-image-5934" title="Settings" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-02-08-um-2.38.19-PM.png" alt="" width="600" height="740" /></a></p>
<p>It is generally wise to add the items you need to the dependencies so that Xcode will know to refresh these if they are modified. In the linked libraries you see a heap of Apple frameworks and that we link in libxml2 as well as the static libDTRichTextEditor which aggregates the objects from the other three projects into one convenient library.</p>
<p><strong>HINT:</strong> There is one (non-obvious) maneuver you have to know to be able to get a resource bundle created in a sub-project in the list of bundle resources. You need to expand the sub-project so that you can see the products group (yellow folder). Then choose the project root to see the targets. Finally drag the bundle product from the sub-project into the &#8220;Copy Bundle Resources&#8221;. Xcode is smart enough to know where to copy the product from.</p>
<p>With the above setup Xcode will build all necessary parts for the one or two necessary architectures and merge it all together nicely. For further tips regarding what you need to know when using Sub-Projects refer to my earlier article on <a title="Sub-Projects in Xcode" href="http://www.cocoanetics.com/2011/12/sub-projects-in-xcode/">Sub-Projects</a> and <a title="Helping Xcode Find Library Headers" href="http://www.cocoanetics.com/2012/01/helping-xcode-find-library-headers/">Header Magic</a>.</p>
<h3>Conclusion</h3>
<p>I happen to like the concept of self-contained pieces very much and what I learned over the past few weeks of how to do it right enabled me to use them in a large scale component as DTRichTextEditor, bringing together multiple bits and pieces.</p>
<p>Of course development will go on, mostly on the Open Source elements. And there are several items still missing that I am guilty of procrastinating. I want  to provide a time-limited binary version of the framework for testing and evaluation. There are many items on the to do list for DTCoreText itself. I need a better quick start guide to do justice to the dozens of users who are funding the development efforts. And there really should be some AppleDoc-style documentation.</p>
<p>While I do like writing, I don&#8217;t like writing documentation as much. So I&#8217;ll do that when I get around to it&#8230; <img src='http://www.cocoanetics.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5929&amp;md5=64697f1af206355ce59202cb4df6ec8b" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/02/dtrichtexteditor-dtcoretext-news/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5929&amp;md5=64697f1af206355ce59202cb4df6ec8b" type="text/html" />"
	</item>
		<item>
		<title>Autoingest.java &#8211; in Objective-C</title>
		<link>http://www.cocoanetics.com/2012/02/autoingest-java-in-objective-c/</link>
		<comments>http://www.cocoanetics.com/2012/02/autoingest-java-in-objective-c/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 09:31:28 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5925</guid>
		<description><![CDATA[We are lobbying since 2009 to get Apple to publish a proper API for downloading all kinds of reports. The first reaction we got was prohibition of ITC scraping. The second reaction was that Apple created the Mobile ITC app which unfortunately lacks any kind of possibility to get the reports out or get monetary amounts. The third reaction was a half-harted publishing of a Java class that is able to download daily and weekly sales reports. This changes today, at least if you are like me and feel uneasy to use Java for downloading reports. Label Buy an ad here The DTITCReportDownloader project is a complete rewrite of the Autoingest Java class in proper Objective-C. This way we iOS and Mac developers can at least download these two kinds of reports without having to have a JVM installed. Please support our cause by duping Radar rdar://6807195 which is still lacking any kind of response. I was told back in 2009 that &#8220;if enough developers wanted it&#8221; Apple would finally give us the API we are wishing for. On GitHub: https://github.com/Cocoanetics/DTITCReportDownloader]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/02/autoingest-java-in-objective-c/"></g:plusone></div><p>We are <a href="http://www.cocoanetics.com/2009/04/petition-itunes-sales-report-api/">lobbying since 2009</a> to get Apple to publish a proper API for downloading all kinds of reports.</p>
<p>The first reaction we got was <a href="http://www.cocoanetics.com/2009/03/apple-rejects-incredibly-useful-itunes-report-app/">prohibition of ITC scraping</a>. The second reaction was that Apple created the Mobile ITC app which unfortunately lacks any kind of possibility to get the reports out or get monetary amounts. The third reaction was a half-harted publishing of a Java class that is able to download daily and weekly sales reports.</p>
<p>This changes today, at least if you are like me and feel uneasy to use Java for downloading reports.</p>
<p><span id="more-5925"></span></p>
<div class="inner_ad_block">
<div id="advman-7" class="widget Advman_Widget">
<h3 class="widgettitle"></h3>
<p><!-- BuySellAds.com Zone Code --></p>
<div id="bsap_1260346" class="bsarocks bsap_fc3166ea4a479e0fdb4251fbe92a1219"></div>
<p><!-- End BuySellAds.com Zone Code --></div>
<div id="text-21" class="widget widget_text">
<h3 class="widgettitle">Label</h3>
<div class="textwidget">
<div class="advert-notice"><a href="http://buysellads.com/buy/detail/56639/zone/1260346">Buy an ad here</a></div>
</div></div>
</div>
<p><a href="https://github.com/Cocoanetics/DTITCReportDownloader">The DTITCReportDownloader project</a> is a complete rewrite of the Autoingest Java class in proper Objective-C. This way we iOS and Mac developers can at least download these two kinds of reports without having to have a JVM installed.</p>
<p>Please support our cause by duping Radar <a href="http://openradar.appspot.com/radar?id=51416">rdar://6807195</a> which is still lacking any kind of response. I was told back in 2009 that &#8220;if enough developers wanted it&#8221; Apple would finally give us the API we are wishing for.</p>
<p>On GitHub: <a href="https://github.com/Cocoanetics/DTITCReportDownloader">https://github.com/Cocoanetics/DTITCReportDownloader</a></p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5925&amp;md5=17b8cea7a919c2a7b75064303c8227ea" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/02/autoingest-java-in-objective-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5925&amp;md5=17b8cea7a919c2a7b75064303c8227ea" type="text/html" />"
	</item>
		<item>
		<title>Podcast #023 &#8211; &#8220;Happy New &#8230; February&#8221;</title>
		<link>http://www.cocoanetics.com/2012/02/podcast-023/</link>
		<comments>http://www.cocoanetics.com/2012/02/podcast-023/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 14:37:30 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Podcast]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5901</guid>
		<description><![CDATA[We&#8217;re rebooting the Cocoanetics Podcast. The last episode had been over a year ago. Happy New &#8230; February Please comment, tweet or mail your suggestions on topics that are of interested to iOS (and by extension Cocoa developers in general). The new title song &#8220;Cocoa Cookin&#8217;&#8221; was composed and produced by Jamie Harper.]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/02/podcast-023/"></g:plusone></div><p>We&#8217;re rebooting the Cocoanetics Podcast. The last episode had been over a year ago.</p>
<p><strong>Happy New &#8230; February</strong></p>

<p>Please comment, tweet or mail your suggestions on topics that are of interested to iOS (and by extension Cocoa developers in general).</p>
<p>The new title song &#8220;Cocoa Cookin&#8217;&#8221; was composed and produced by <a href="http://www.jamieharpermusic.com/">Jamie Harper</a>.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5901&amp;md5=5f555127b18a9590931a8900d4ba3dfc" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/02/podcast-023/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.cocoanetics.com/files/Cocoanetics_023.mp3" length="21741314" type="audio/mpeg" />
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5901&amp;md5=5f555127b18a9590931a8900d4ba3dfc" type="text/html" />"
	</item>
		<item>
		<title>Radar: &#8220;CoreText Line Spacing Bug&#8221;</title>
		<link>http://www.cocoanetics.com/2012/02/radar-coretext-line-spacing-bug/</link>
		<comments>http://www.cocoanetics.com/2012/02/radar-coretext-line-spacing-bug/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 09:34:14 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Bug Reports]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5897</guid>
		<description><![CDATA[I finally got around to report an annoying bug in CoreText that has been bugging us in DTCoreText until I wrote a method to correct line origins as a workaround. rdar://10810114 The annoying thing about this bug is that it adds visual noise to otherwise pristinely rendered text. Especially on larger font sizes you see that additional space appears before each CTLine that ends with a paragraph break (\n). UPDATE: This is a duplicate of rdar://9931615. Label Buy an ad here CoreText Line Spacing Bug Summary CoreText inserts too much space before any line that ends with a \n. This extra space depends on the font and font size. On large print this causes visual noise by not being uniform. Steps to Reproduce Create a CTFrame from a CTFrameSetter with a string that is long enough to wrap and that contains paragraph breaks. Use a non-UI font, like for example AriaMT. Expected Results Line origins should be spaced by exactly the same distance for identical text and identical attributes. Actual Results Each line that ends with a paragraph break is shifted down. With the system UI font, size 54 baselines are spaced exactly 64 pixels apart. With ArialMT, size 54, baseline spacing differs between 62 and 65. Regression This has been a bug since before iOS 4.3. Notes This does not occur with all fonts, Using a system font the spacing is precisely correct. I have attached a project to demonstrate the issue. See TextView.m. It appears that the text metrics for an (invisible) paragraph glyph are miscalculated. Since the glyph is not visible you&#8217;d expect neither and ascender nor descender value. But instead the descender is too large. If you walk through the entire line and get the maximum ascenders and descenders the value is correct if you omit the \n in this calculation. In short: A trailing \n messes up the font metrics for the entire CTLine. Attachment: CoreTextLineOrigins Demo Project]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/02/radar-coretext-line-spacing-bug/"></g:plusone></div><p>I finally got around to report an annoying bug in CoreText that has been bugging us in DTCoreText until I wrote a method to correct line origins as a workaround. <a href="http://openradar.appspot.com/10810114">rdar://10810114</a></p>
<p>The annoying thing about this bug is that it adds visual noise to otherwise pristinely rendered text. Especially on larger font sizes you see that additional space appears before each CTLine that ends with a paragraph break (\n).</p>
<p>UPDATE: This is a duplicate of rdar://9931615.</p>
<p><span id="more-5897"></span></p>
<div class="inner_ad_block">
<div id="advman-7" class="widget Advman_Widget">
<h3 class="widgettitle"></h3>
<p><!-- BuySellAds.com Zone Code --></p>
<div id="bsap_1260346" class="bsarocks bsap_fc3166ea4a479e0fdb4251fbe92a1219"></div>
<p><!-- End BuySellAds.com Zone Code --></div>
<div id="text-21" class="widget widget_text">
<h3 class="widgettitle">Label</h3>
<div class="textwidget">
<div class="advert-notice"><a href="http://buysellads.com/buy/detail/56639/zone/1260346">Buy an ad here</a></div>
</div></div>
</div>
<h2>CoreText Line Spacing Bug</h2>
<h3>Summary</h3>
<p>CoreText inserts too much space before any line that ends with a \n. This extra space depends on the font and font size. On large print this causes visual noise by not being uniform.</p>
<h3>Steps to Reproduce</h3>
<p>Create a CTFrame from a CTFrameSetter with a string that is long enough to wrap and that contains paragraph breaks. Use a non-UI font, like for example AriaMT.</p>
<h3>Expected Results</h3>
<p>Line origins should be spaced by exactly the same distance for identical text and identical attributes.</p>
<h3>Actual Results</h3>
<p>Each line that ends with a paragraph break is shifted down. With the system UI font, size 54 baselines are spaced exactly 64 pixels apart. With ArialMT, size 54, baseline spacing differs between 62 and 65.</p>
<h3>Regression</h3>
<p>This has been a bug since before iOS 4.3.</p>
<h3>Notes</h3>
<p>This does not occur with all fonts, Using a system font the spacing is precisely correct. I have attached a project to demonstrate the issue. See TextView.m.</p>
<p>It appears that the text metrics for an (invisible) paragraph glyph are miscalculated. Since the glyph is not visible you&#8217;d expect neither and ascender nor descender value. But instead the descender is too large. If you walk through the entire line and get the maximum ascenders and descenders the value is correct if you omit the \n in this calculation.</p>
<p>In short: A trailing \n messes up the font metrics for the entire CTLine.</p>
<p>Attachment: <a href="http://www.cocoanetics.com/files/CoreTextLineOrigins.zip">CoreTextLineOrigins Demo Project</a></p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5897&amp;md5=da7f3adbd2a6faada13b6babff489c17" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/02/radar-coretext-line-spacing-bug/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5897&amp;md5=da7f3adbd2a6faada13b6babff489c17" type="text/html" />"
	</item>
		<item>
		<title>Xcode Build Rules</title>
		<link>http://www.cocoanetics.com/2012/02/xcode-build-rules/</link>
		<comments>http://www.cocoanetics.com/2012/02/xcode-build-rules/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 18:25:31 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Recipes]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5887</guid>
		<description><![CDATA[When I moved the default CSS rules into a separate file I was facing the old dilemma: how can I embed this in the static library but still be able to easily add contents to it via Xcode. I previously explained how you can turn any file into a c-Byte-array. But this still required manual work. I did a bit of researching and found that on regular Linux systems people seem to have a tool named objcopy which can copy files as their are into an object file (.o) which can be linked together to the final binary by the linker. But unfortunately this tool does not come with Xcode. So it is out of the question because I want everybody to be able to build DTCoreText. Xcode Build Rules come to the rescue. They can automate any kind of preprocessing you like and it turns out they are an easy solution for this very problem. Label Buy an ad here There are essentially three kinds of source file that Xcode knows how to deal with (greatly simplified): c, c++ or Objective-C source code, or any code that can be somehow compiled header files other files &#8220;Other files&#8221;, if you add them to a target, are treated as resources that simply get copied into your app bundle. And now I&#8217;ll teach you how you can make any kind of file compilable. Be it some textures that you are compressing for building your game, or be it some resource that you want to embed into your binary. Make a Build Rule When Xcode is asked to compile a file it has a set of rules how it does that. So what we are going to do is to add our own rule how a css file is turned into a .c file. And for .c files are something that Xcode has a built-in rule for. So it can happen that you have two or more daisy chained rules that hand off their results to each other. It is somewhat inconvenient that you cannot define rules globally. Instead you have to repeat your custom rules for each target. To add your own rule, go into the projects info where you see your targets and on the target you want the rule for add it like shown. This rule matches all files that end with .css (asterisk is a wildcard) and executes a custom script: cd &#34;$INPUT_FILE_DIR&#34; # move into file dir, otherwise xxd takes the full path for the symbol /usr/bin/xxd -i &#34;$INPUT_FILE_NAME&#34; &#34;$DERIVED_SOURCES_DIR/$INPUT_FILE_BASE.css.c&#34; # builds a c file with a hex array I&#8217;m moving into the folder of the input file first because xxd will always take the full passed file path and turn it into the name of the c-array. This way it will just be named default_c and the length will be in default_c_len. The above rule is all it takes to teach Xcode how to turn a .css file into a .c file. Now the next step is to make sure that we are actually compiling the default.css file as opposed to copying it together with the other resources. Compile not Copy You can see that default.css is compiled by having it in the Compile Sources section of the Build Phases. If you build the project you see two hints about what happens now. Towards the top of the build log you see the preprocessing of the file. A little further down you see how the intermediate c file is being compiled. Further down the library tool puts all object files into the library archive. If you don&#8217;t believe me, you can employ the nm tool to inspect the symbols in the final product. nm DemoApp &#124; grep default_c 00045474 D _default_css 00045fe0 D _default_css_len These are the two symbols from the default.css.c file that made it into the final product. This guide wouldn&#8217;t be complete if I didn&#8217;t show you how to get to these symbols. Accessing the Objectified File I told you above that xxd uses the passed file name to make two variables, one for the c-style array, one for the length. Only change is that it has to turn the file name characters into a legal symbol, so dots are turned into underscores. In DTCSSStylesheet.m I am accessing this array like so. I define these two variables as external which prompts the linker to insert their correct address. + &#40;DTCSSStylesheet *&#41;defaultStyleSheet // external symbols generated via custom build rule and xxd extern unsigned char default_css&#91;&#93;; extern unsigned int default_css_len; &#125; And to get the string out of them is just as easy: + &#40;DTCSSStylesheet *&#41;defaultStyleSheet &#123; // get the data from the external symbol NSData *data = &#91;NSData dataWithBytes:default_css length:default_css_len&#93;; NSString *cssString = &#91;&#91;NSString alloc&#93; initWithData:data encoding:NSUTF8StringEncoding&#93;; &#160; return &#91;&#91;DTCSSStylesheet alloc&#93; initWithStyleBlock:cssString&#93;; &#125; This [...]]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/02/xcode-build-rules/"></g:plusone></div><p>When I moved the default CSS rules into a separate file I was facing the old dilemma: how can I embed this in the static library but still be able to easily add contents to it via Xcode. I previously explained how you can <a title="Embedding Binary Resources" href="http://www.cocoanetics.com/2010/10/embedding-binary-resources/">turn any file into a c-Byte-array</a>. But this still required manual work.</p>
<p>I did a bit of researching and found that on regular Linux systems people seem to have a tool named objcopy which can copy files as their are into an object file (.o) which can be linked together to the final binary by the linker. But unfortunately this tool does not come with Xcode. So it is out of the question because I want everybody to be able to build DTCoreText.</p>
<p>Xcode Build Rules come to the rescue. They can automate any kind of preprocessing you like and it turns out they are an easy solution for this very problem.</p>
<p><span id="more-5887"></span></p>
<div class="inner_ad_block">
<div id="advman-7" class="widget Advman_Widget">
<h3 class="widgettitle"></h3>
<p><!-- BuySellAds.com Zone Code --></p>
<div id="bsap_1260346" class="bsarocks bsap_fc3166ea4a479e0fdb4251fbe92a1219"></div>
<p><!-- End BuySellAds.com Zone Code --></div>
<div id="text-21" class="widget widget_text">
<h3 class="widgettitle">Label</h3>
<div class="textwidget">
<div class="advert-notice"><a href="http://buysellads.com/buy/detail/56639/zone/1260346">Buy an ad here</a></div>
</div></div>
</div>
<p>There are essentially three kinds of source file that Xcode knows how to deal with (greatly simplified):</p>
<ul>
<li>c, c++ or Objective-C source code, or any code that can be somehow compiled</li>
<li>header files</li>
<li>other files</li>
</ul>
<p>&#8220;Other files&#8221;, if you add them to a target, are treated as resources that simply get copied into your app bundle.</p>
<p>And now I&#8217;ll teach you how you can make any kind of file compilable. Be it some textures that you are compressing for building your game, or be it some resource that you want to embed into your binary.</p>
<h3>Make a Build Rule</h3>
<p>When Xcode is asked to compile a file it has a set of rules how it does that. So what we are going to do is to add our own rule how a css file is turned into a .c file. And for .c files are something that Xcode has a built-in rule for. So it can happen that you have two or more daisy chained rules that hand off their results to each other.</p>
<p>It is somewhat inconvenient that you cannot define rules globally. Instead you have to repeat your custom rules for each target.</p>
<p>To add your own rule, go into the projects info where you see your targets and on the target you want the rule for add it like shown.</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-02-03-um-7.02.06-PM.png"><img class="alignnone  wp-image-5889" title="Add a rule" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-02-03-um-7.02.06-PM.png" alt="" width="633" height="254" /></a></p>
<p>This rule matches all files that end with .css (asterisk is a wildcard) and executes a custom script:</p>

<div class="wp_codebox"><table><tr id="p58875"><td class="code" id="p5887code5"><pre class="objc" style="font-family:monospace;">cd <span style="color: #bf1d1a;">&quot;$INPUT_FILE_DIR&quot;</span>  <span style="color: #6e371a;"># move into file dir, otherwise xxd takes the full path for the symbol</span>
<span style="color: #002200;">/</span>usr<span style="color: #002200;">/</span>bin<span style="color: #002200;">/</span>xxd <span style="color: #002200;">-</span>i <span style="color: #bf1d1a;">&quot;$INPUT_FILE_NAME&quot;</span> <span style="color: #bf1d1a;">&quot;$DERIVED_SOURCES_DIR/$INPUT_FILE_BASE.css.c&quot;</span> <span style="color: #6e371a;"># builds a c file with a hex array</span></pre></td></tr></table></div>

<p>I&#8217;m moving into the folder of the input file first because xxd will always take the full passed file path and turn it into the name of the c-array. This way it will just be named default_c and the length will be in default_c_len.</p>
<p>The above rule is all it takes to teach Xcode how to turn a .css file into a .c file. Now the next step is to make sure that we are actually compiling the default.css file as opposed to copying it together with the other resources.</p>
<h3>Compile not Copy</h3>
<p>You can see that default.css is compiled by having it in the Compile Sources section of the Build Phases.</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-02-03-um-7.06.22-PM.png"><img class="alignnone  wp-image-5890" title="Compile css file" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-02-03-um-7.06.22-PM.png" alt="" width="629" height="207" /></a></p>
<p>If you build the project you see two hints about what happens now. Towards the top of the build log you see the preprocessing of the file. A little further down you see how the intermediate c file is being compiled.</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-02-03-um-7.07.55-PM.png"><img class="alignnone  wp-image-5891" title="Preprocessing and Compiling" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-02-03-um-7.07.55-PM.png" alt="" width="631" height="214" /></a></p>
<p>Further down the library tool puts all object files into the library archive. If you don&#8217;t believe me, you can employ the nm tool to inspect the symbols in the final product.</p>

<div class="wp_codebox"><table><tr id="p58876"><td class="code" id="p5887code6"><pre class="sh" style="font-family:monospace;">nm DemoApp | grep default_c
00045474 D _default_css
00045fe0 D _default_css_len</pre></td></tr></table></div>

<p>These are the two symbols from the default.css.c file that made it into the final product.</p>
<p>This guide wouldn&#8217;t be complete if I didn&#8217;t show you how to get to these symbols.</p>
<h3>Accessing the Objectified File</h3>
<p>I told you above that xxd uses the passed file name to make two variables, one for the c-style array, one for the length. Only change is that it has to turn the file name characters into a legal symbol, so dots are turned into underscores.</p>
<p>In DTCSSStylesheet.m I am accessing this array like so. I define these two variables as external which prompts the linker to insert their correct address.</p>

<div class="wp_codebox"><table><tr id="p58877"><td class="code" id="p5887code7"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span>DTCSSStylesheet <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>defaultStyleSheet
<span style="color: #11740a; font-style: italic;">// external symbols generated via custom build rule and xxd</span>
<span style="color: #a61390;">extern</span> <span style="color: #a61390;">unsigned</span> <span style="color: #a61390;">char</span> default_css<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #a61390;">extern</span> <span style="color: #a61390;">unsigned</span> <span style="color: #a61390;">int</span> default_css_len;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>And to get the string out of them is just as easy:</p>

<div class="wp_codebox"><table><tr id="p58878"><td class="code" id="p5887code8"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span>DTCSSStylesheet <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>defaultStyleSheet
<span style="color: #002200;">&#123;</span>
   <span style="color: #11740a; font-style: italic;">// get the data from the external symbol</span>
   <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/"><span style="color: #400080;">NSData</span></a> <span style="color: #002200;">*</span>data <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/"><span style="color: #400080;">NSData</span></a> dataWithBytes<span style="color: #002200;">:</span>default_css length<span style="color: #002200;">:</span>default_css_len<span style="color: #002200;">&#93;</span>;
   <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>cssString <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> alloc<span style="color: #002200;">&#93;</span> initWithData<span style="color: #002200;">:</span>data encoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span>;
&nbsp;
   <span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>DTCSSStylesheet alloc<span style="color: #002200;">&#93;</span> initWithStyleBlock<span style="color: #002200;">:</span>cssString<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>This works because I know that all my source files are UTF8 encoded, i.e. one byte per (normal) character. It is quite handy to have the default_css_len integer telling us the length of the array, because in c an array is just a pointer to the first byte.</p>
<h3>Conclusion</h3>
<p>If you know how to employ custom build rules to your advantage many tasks that you would have previously run external scripts for now become part of the build process. What you can do with this knowledge is only limited by your imagination &#8230; and your scripting skills.</p>
<p>But the general advantage of build rules versus external programs is that they are part of the project. So if they use standard commands they are portable to other developer&#8217;s machines. Perfect for Open Source projects.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5887&amp;md5=4af7587e6b75dcc81ddd9ca30897f36d" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/02/xcode-build-rules/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5887&amp;md5=4af7587e6b75dcc81ddd9ca30897f36d" type="text/html" />"
	</item>
		<item>
		<title>iWoman 2.0.5</title>
		<link>http://www.cocoanetics.com/2012/02/iwoman-2-0-5/</link>
		<comments>http://www.cocoanetics.com/2012/02/iwoman-2-0-5/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 17:17:21 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Updates]]></category>
		<category><![CDATA[iWoman]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5883</guid>
		<description><![CDATA[This is a maintenance update. There was a bug in DTAboutViewController which caused a crash under iOS 5. Change Fixed: Crash on iOS 5 when opening About Section The update has been submitted to Apple for approval. Update Feb 8th: Ready for Sale. It should be available shortly.]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/02/iwoman-2-0-5/"></g:plusone></div><p>This is a maintenance update. There was a bug in <a href="http://www.cocoanetics.com/parts/dtaboutviewcontroller/">DTAboutViewController</a> which caused a crash under iOS 5.</p>
<h3>Change</h3>
<ul>
<li>Fixed: Crash on iOS 5 when opening About Section</li>
</ul>
<p>The update has been submitted to Apple for approval.</p>
<p>Update Feb 8th: Ready for Sale. It should be available shortly.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5883&amp;md5=de635343e7b090f1dcbaf62c0c51755e" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/02/iwoman-2-0-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5883&amp;md5=de635343e7b090f1dcbaf62c0c51755e" type="text/html" />"
	</item>
		<item>
		<title>What To Talk About?</title>
		<link>http://www.cocoanetics.com/2012/02/what-to-talk-about/</link>
		<comments>http://www.cocoanetics.com/2012/02/what-to-talk-about/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 17:39:38 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Podcast]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5879</guid>
		<description><![CDATA[My iOS-related Podcast started out as &#8220;Dr. Touch Podcast&#8221; and later we rebranded ourselves to the more unique &#8220;Cocoanetics Podcast&#8221;. Though the topics always revolved around iOS development, Apple in general ans the people involved in our profession. After an extended hiatus planning has begun to revive the podcast. I like to invite your comments, wishes and ideas as to what you would like to see &#8211; or more precisely hear &#8211; in a podcast that focusses on your daily bread and butter. Label Buy an ad here This impetus actually came from a composer by the name of Jamie Harper. A couple of weeks ago he contacted me offering his services. I thought to myself &#8220;well if I get new theme music for the podcast then I&#8217;ll relaunch it&#8221;. I was kind of thinking that I could probably either not afford the composition or that this would take a long time to get done. Often you are dealing with people who vocally offer some great services only to disappoint you and never deliver. But Mr. Harper delivered and he delivered very well. Not only did he compose a very nice intro jingle, but also made me a shorter and longer outro. And he did that at an exceptionally affordable rate. You&#8217;ll hear this music on the next show that I shall record. Speaking of which &#8230; In the past I would always to a summary of iOS development news focussing on the kinds of news that would only half-heartedly be covered by the mainstream media which focusses on Apple products and the consumer end. Sometimes I had the opportunity to interview industry leaders like Ortwin Gentz from Futuretap. Those podcast episodes where always good fun. Finally I did speculate quite a bit on the future direction that Apple hints at with their actions. Crystal ball looking if you will. I like to talk and voice my opinion, that is one half why I want to do a podcast (because the established networks keep ignoring me). The other reason for &#8220;why now?&#8221; is that there really is no dedicated iOS development news podcast. If you are interested in how great Marco Arment or his coffee is, then there&#8217;s a show for you. But nothing really covers stuff that I as a pro developer find interesting. So here&#8217;s your chance to help shape the future of the Cocoanetics podcast. What are you interested in? What is niche enough to not be covered by others? Also, let me know if you want to be on the show and get some free advertising for your apps and services. You get airtime if you let me ask you some in depth questions in an interview. Your comments welcome, either via the public comments or if you don&#8217;t want anybody to know just drop me a mail.]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/02/what-to-talk-about/"></g:plusone></div><p>My iOS-related Podcast started out as &#8220;Dr. Touch Podcast&#8221; and later we rebranded ourselves to the more unique &#8220;Cocoanetics Podcast&#8221;. Though the topics always revolved around iOS development, Apple in general ans the people involved in our profession.</p>
<p>After an extended hiatus planning has begun to revive the podcast. I like to invite your comments, wishes and ideas as to what you would like to see &#8211; or more precisely hear &#8211; in a podcast that focusses on your daily bread and butter.</p>
<p><span id="more-5879"></span></p>
<div class="inner_ad_block">
<div id="advman-7" class="widget Advman_Widget">
<h3 class="widgettitle"></h3>
<p><!-- BuySellAds.com Zone Code --></p>
<div id="bsap_1260346" class="bsarocks bsap_fc3166ea4a479e0fdb4251fbe92a1219"></div>
<p><!-- End BuySellAds.com Zone Code --></div>
<div id="text-21" class="widget widget_text">
<h3 class="widgettitle">Label</h3>
<div class="textwidget">
<div class="advert-notice"><a href="http://buysellads.com/buy/detail/56639/zone/1260346">Buy an ad here</a></div>
</div></div>
</div>
<p>This impetus actually came from a composer by the name of Jamie Harper. A couple of weeks ago he contacted me offering his services. I thought to myself &#8220;well if I get new theme music for the podcast then I&#8217;ll relaunch it&#8221;.</p>
<p>I was kind of thinking that I could probably either not afford the composition or that this would take a long time to get done. Often you are dealing with people who vocally offer some great services only to disappoint you and never deliver.</p>
<p>But Mr. Harper delivered and he delivered very well. Not only did he compose a very nice intro jingle, but also made me a shorter and longer outro. And he did that at an exceptionally affordable rate. You&#8217;ll hear this music on the next show that I shall record.</p>
<p>Speaking of which &#8230; In the past I would always to a summary of iOS development news focussing on the kinds of news that would only half-heartedly be covered by the mainstream media which focusses on Apple products and the consumer end.</p>
<p>Sometimes I had the opportunity to interview industry leaders like Ortwin Gentz from Futuretap. Those podcast episodes where always good fun.</p>
<p>Finally I did speculate quite a bit on the future direction that Apple hints at with their actions. Crystal ball looking if you will. I like to talk and voice my opinion, that is one half why I want to do a podcast (because the established networks keep ignoring me).</p>
<p>The other reason for &#8220;why now?&#8221; is that there really is no dedicated iOS development news podcast. If you are interested in how great Marco Arment or his coffee is, then there&#8217;s a show for you. But nothing really covers stuff that I as a pro developer find interesting.</p>
<p>So here&#8217;s your chance to help shape the future of the Cocoanetics podcast. What are you interested in? What is niche enough to not be covered by others?</p>
<p>Also, let me know if you want to be on the show and get some free advertising for your apps and services. You get airtime if you let me ask you some in depth questions in an interview.</p>
<p>Your comments welcome, either via the public comments or if you don&#8217;t want anybody to know just drop me a mail.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5879&amp;md5=78c0f5d46b121118ab3132bbc7d252c5" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/02/what-to-talk-about/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5879&amp;md5=78c0f5d46b121118ab3132bbc7d252c5" type="text/html" />"
	</item>
		<item>
		<title>My Terminal is Less Boring Than Yours</title>
		<link>http://www.cocoanetics.com/2012/02/my-terminal-is-less-boring-than-yours/</link>
		<comments>http://www.cocoanetics.com/2012/02/my-terminal-is-less-boring-than-yours/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 14:57:41 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Mac]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5875</guid>
		<description><![CDATA[There&#8217;s a category of developers &#8211; probably coming from other Linux-based desktops &#8211; who are feeling at home in the console (aka terminal). Especially when working with SCM systems like Git or Subversion you&#8217;re often faster committing or updating doing that via short commands as compared to Xcode. Unfortunately Apple did not think to make the console a nice thing to look at from the get go. Let me show you quickly how you can geek up your terminal as well. Your colleagues will be impressed. Label Buy an ad here It&#8217;s really simple. You need to add these lines to your .profile which resides in your user home directory. If the file does not exist, create it. export CLICOLOR=1 export LSCOLORS=Gxfxcxdxbxegedabagacad The first line activates color support for the CLI (command line interface), the second line specifies which colors to use for certain kinds of things. When this is set every new console window will emit special ANSI sequences to set the colors. You also need to enable these colors for your terminal. Make sure you have set your terminal emulation to xterm-color in Preferences &#8211; Advanced in the Terminal app. While you are here you can also set up some other things for how the Terminal should be styled. I prefer the &#8220;Pro&#8221; style which has a tinted glass background, sort of like a holographic display which you can see through. The above settings will make your terminal look like this: If these colors are not your style, don&#8217;t fret, Geoff Greer has build a cool online generator to piece together the LSCOLORS code. Just make your own color finger print and paste it into your .profile. There&#8217;s more! Git also sports several color options: git config color.branch auto git config color.diff auto git config color.interactive auto git config color.status auto &#8230; or you use the catch-all setting which includes all of the above: git config color.ui true This adds splashes of colors here and there, for examples a git diff: Many other tools also support a color option, for example viewing a command&#8217;s man page is so much more interesting with a touch of color. If you have additional suggestions on how to make better use of color in terminal please don&#8217;t hesitate to comment below.]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/02/my-terminal-is-less-boring-than-yours/"></g:plusone></div><p>There&#8217;s a category of developers &#8211; probably coming from other Linux-based desktops &#8211; who are feeling at home in the console (aka terminal). Especially when working with SCM systems like Git or Subversion you&#8217;re often faster committing or updating doing that via short commands as compared to Xcode.</p>
<p>Unfortunately Apple did not think to make the console a nice thing to look at from the get go. Let me show you quickly how you can geek up your terminal as well. Your colleagues will be impressed.</p>
<p><span id="more-5875"></span></p>
<div class="inner_ad_block">
<div id="advman-7" class="widget Advman_Widget">
<h3 class="widgettitle"></h3>
<p><!-- BuySellAds.com Zone Code --></p>
<div id="bsap_1260346" class="bsarocks bsap_fc3166ea4a479e0fdb4251fbe92a1219"></div>
<p><!-- End BuySellAds.com Zone Code --></div>
<div id="text-21" class="widget widget_text">
<h3 class="widgettitle">Label</h3>
<div class="textwidget">
<div class="advert-notice"><a href="http://buysellads.com/buy/detail/56639/zone/1260346">Buy an ad here</a></div>
</div></div>
</div>
<p>It&#8217;s really simple. You need to add these lines to your .profile which resides in your user home directory. If the file does not exist, create it.</p>

<div class="wp_codebox"><table><tr id="p587512"><td class="code" id="p5875code12"><pre class="sh" style="font-family:monospace;">export CLICOLOR=1
export LSCOLORS=Gxfxcxdxbxegedabagacad</pre></td></tr></table></div>

<p>The first line activates color support for the CLI (command line interface), the second line specifies which colors to use for certain kinds of things. When this is set every new console window will emit special ANSI sequences to set the colors.</p>
<p>You also need to enable these colors for your terminal. Make sure you have set your terminal emulation to <strong>xterm-color</strong> in Preferences &#8211; Advanced in the Terminal app. While you are here you can also set up some other things for how the Terminal should be styled. I prefer the &#8220;Pro&#8221; style which has a tinted glass background, sort of like a holographic display which you can see through.</p>
<p>The above settings will make your terminal look like this:</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-02-01-um-3.28.25-PM.png"><img class="alignnone size-full wp-image-5876" title="Terminal in color" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-02-01-um-3.28.25-PM.png" alt="" width="622" height="466" /></a></p>
<p>If these colors are not your style, don&#8217;t fret, Geoff Greer has build a cool online generator to <a href="http://geoff.greer.fm/lscolors/">piece together the LSCOLORS code</a>. Just make your own color finger print and paste it into your .profile.</p>
<p>There&#8217;s more! Git also sports several color options:</p>

<div class="wp_codebox"><table><tr id="p587513"><td class="code" id="p5875code13"><pre class="sh" style="font-family:monospace;">git config color.branch auto
git config color.diff auto
git config color.interactive auto
git config color.status auto</pre></td></tr></table></div>

<p>&#8230; or you use the catch-all setting which includes all of the above:</p>

<div class="wp_codebox"><table><tr id="p587514"><td class="code" id="p5875code14"><pre class="sh" style="font-family:monospace;">git config color.ui true</pre></td></tr></table></div>

<p>This adds splashes of colors here and there, for examples a git diff:</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-02-01-um-3.37.02-PM.png"><img class="alignnone size-full wp-image-5877" title="git diff with color" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-02-01-um-3.37.02-PM.png" alt="" width="760" height="578" /></a></p>
<p>Many other tools also support a color option, for example viewing a command&#8217;s man page is so much more interesting with a touch of color. If you have additional suggestions on how to make better use of color in terminal please don&#8217;t hesitate to comment below.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5875&amp;md5=d60a537041a534936e78adc10aacf110" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/02/my-terminal-is-less-boring-than-yours/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5875&amp;md5=d60a537041a534936e78adc10aacf110" type="text/html" />"
	</item>
		<item>
		<title>GitHub Fork, Fix, Pull Request</title>
		<link>http://www.cocoanetics.com/2012/01/github-fork-fix-pull-request/</link>
		<comments>http://www.cocoanetics.com/2012/01/github-fork-fix-pull-request/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 13:10:03 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Recipes]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5859</guid>
		<description><![CDATA[In this post I will to demonstrate how you can contribute to an Open Source project hosted on GitHub. I previously blogged about how you can make and apply patches, which is certainly one way. But on GitHub there is an even cooler method, one that is also less work on the project maintainer. Label Buy an ad here For the sake of this tutorial I shall pretend that there is an issue with a project by Matt Galloway, then I&#8217;ll fork his project. After fixing the issue I will push my changes online to my fork and finally notify Matt about these changes via a so-called &#8220;Pull Request&#8221;. A prerequisite for this tutorial is to have your GitHub account and local git set up previously. Step 1 &#8211; We have an Issue Your first thought should be to document that in GitHub&#8217;s excellent bug tracking system. Each Open Source project there has a list of Issues (which are the bugs and feature requests). I found two things to improve in the project and so I added two issues. We could hope for the project&#8217;s owner to fix that for us, but &#8211; being smart developers &#8211; we can also proceed to fix the issues ourselves. From the get go we won&#8217;t have writing access to the GitHub repository (unless the owner gives it to us, which is rare). You can see that this is the case if you only see the HTTP and Git Read-Only options on the repo URL: The usual method is to make a copy of this project in our own area on GitHub where we CAN write to. This copy is what they call a &#8220;Fork&#8221;. Step 2 &#8211; Stick a Fork in it To make a fork you klick the &#8220;Fork&#8221; button at the top right of the project main page. After some &#8220;hardcore forking action&#8221; you end up on your own copy of the project. And there is now an extra option &#8220;SSH&#8221; telling you that you have read and write access to that. A fork is a complete copy of the original project including all previous history. The reason for this that with Git every copy of a repository is always a full clone, so that each clone can also serve as a backup. This illustrates the distributed nature of Git, as opposed to centralized Source Code Management (SCM) systems like Subversion which has a central server. Step 3 &#8211; Clone Wars To work on our copy of the project we need to clone it to our hard disk. You can use the excellent official GitHub app but personally I prefer to work in terminal. I open terminal, go to a place where I want the copy of the project to be and issue the command: git clone git@github.com:Cocoanetics/ios-library-with-resources.git The URL used is the SSH one I copied from the web page. This results in a ios-library-with-resources folder appearing in the current working directory. Step 4 &#8211; Fix-Tours Now we can do our changes. So I open the Xcode project. The first thing I am fixing for this example is to add the two sub-project products as dependency so that they get automatically built if somebody builds the containing app. You see an M (for Modified) appear next to the root of the project tree which means that the project file has been modified. Each such fix should become one commit. So we right-click on MyLibraryTest, Source Control, Commit Selected Files. This opens a dialog that shows which files were modified and prompts for a commit message. Since we fixed issue number #001 with that we also add this tag, because later we will see that GitHub conveniently links this commit with the issue via this number. This committing basically saves the current state in your local Git repository (your clone) and adds your message to that. Actually it did a bit more than that, because Git has a an extra step called &#8220;staging&#8221; before committing. In staging you select the modifications you want to be part of the commit by Adding them to the staging area. The second part then does this saving. If you do this via the Xcode interface you don&#8217;t need this staging phase because you specifically selected the files to commit already via the project navigator. The second issue to fix is to change a build setting on the sub-project. This time the M appears next to the MyLibrary.xcodeproj which really means the project.pbxproj file contained in the MyLibrary.xcodeproj bundle. (Remember that a bundle is a folder that looks like a file) This time let&#8217;s do the committing on the command like, like a real pro. First let&#8217;s see the status. git status # On branch master # Your branch is ahead of 'origin/master' by 1 commit. # # [...]]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/01/github-fork-fix-pull-request/"></g:plusone></div><p>In this post I will to demonstrate how you can contribute to an Open Source project hosted on GitHub. I previously blogged about <a title="How to Make and Apply Patches" href="http://www.cocoanetics.com/2011/12/how-to-make-and-apply-patches/">how you can make and apply patches</a>, which is certainly one way. But on GitHub there is an even cooler method, one that is also less work on the project maintainer.</p>
<p><span id="more-5859"></span></p>
<div class="inner_ad_block">
<div id="advman-7" class="widget Advman_Widget">
<h3 class="widgettitle"></h3>
<p><!-- BuySellAds.com Zone Code --></p>
<div id="bsap_1260346" class="bsarocks bsap_fc3166ea4a479e0fdb4251fbe92a1219"></div>
<p><!-- End BuySellAds.com Zone Code --></div>
<div id="text-21" class="widget widget_text">
<h3 class="widgettitle">Label</h3>
<div class="textwidget">
<div class="advert-notice"><a href="http://buysellads.com/buy/detail/56639/zone/1260346">Buy an ad here</a></div>
</div></div>
</div>
<p>For the sake of this tutorial I shall pretend that there is an issue with a project by Matt Galloway, then I&#8217;ll fork his project. After fixing the issue I will push my changes online to my fork and finally notify Matt about these changes via a so-called &#8220;Pull Request&#8221;.</p>
<p>A prerequisite for this tutorial is to have your GitHub account and local git <a href="http://www.cocoanetics.com/2011/01/starting-an-opensource-project-on-github/">set up previously</a>.</p>
<h3>Step 1 &#8211; We have an Issue</h3>
<p>Your first thought should be to document that in GitHub&#8217;s excellent bug tracking system. Each Open Source project there has a list of Issues (which are the bugs and feature requests). I found two things to improve in the project and so I added two issues.</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-12.53.44-PM.png"><img class="alignnone  wp-image-5860" title="Issue" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-12.53.44-PM.png" alt="" width="650" height="524" /></a></p>
<p>We could hope for the project&#8217;s owner to fix that for us, but &#8211; being smart developers &#8211; we can also proceed to fix the issues ourselves. From the get go we won&#8217;t have writing access to the GitHub repository (unless the owner gives it to us, which is rare). You can see that this is the case if you only see the HTTP and Git Read-Only options on the repo URL:</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-1.00.19-PM.png"><img class="alignnone  wp-image-5861" title="Read-Only" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-1.00.19-PM.png" alt="" width="637" height="79" /></a></p>
<p>The usual method is to make a copy of this project in our own area on GitHub where we CAN write to. This copy is what they call a &#8220;Fork&#8221;.</p>
<h3>Step 2 &#8211; Stick a Fork in it</h3>
<p>To make a fork you klick the &#8220;Fork&#8221; button at the top right of the project main page. After some &#8220;hardcore forking action&#8221; you end up on your own copy of the project. And there is now an extra option &#8220;SSH&#8221; telling you that you have read and write access to that.</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-1.03.02-PM.png"><img class="alignnone  wp-image-5862" title="Forked" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-1.03.02-PM.png" alt="" width="758" height="165" /></a></p>
<p>A fork is a complete copy of the original project including all previous history. The reason for this that with Git every copy of a repository is always a full clone, so that each clone can also serve as a backup. This illustrates the distributed nature of Git, as opposed to centralized Source Code Management (SCM) systems like Subversion which has a central server.</p>
<h3>Step 3 &#8211; Clone Wars</h3>
<p>To work on our copy of the project we need to clone it to our hard disk. You can use the excellent <a href="http://mac.github.com/">official GitHub app</a> but personally I prefer to work in terminal. I open terminal, go to a place where I want the copy of the project to be and issue the command:</p>

<div class="wp_codebox"><table><tr id="p585918"><td class="code" id="p5859code18"><pre class="objc" style="font-family:monospace;">git clone git@github.com<span style="color: #002200;">:</span>Cocoanetics<span style="color: #002200;">/</span>ios<span style="color: #002200;">-</span>library<span style="color: #002200;">-</span>with<span style="color: #002200;">-</span>resources.git</pre></td></tr></table></div>

<p>The URL used is the SSH one I copied from the web page. This results in a ios-library-with-resources folder appearing in the current working directory.</p>
<h3>Step 4 &#8211; Fix-Tours</h3>
<p>Now we can do our changes. So I open the Xcode project.</p>
<p>The first thing I am fixing for this example is to add the two sub-project products as dependency so that they get automatically built if somebody builds the containing app.</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-1.17.57-PM.png"><img class="alignnone  wp-image-5863" title="Issue 1" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-1.17.57-PM.png" alt="" width="608" height="335" /></a></p>
<p>You see an M (for Modified) appear next to the root of the project tree which means that the project file has been modified. Each such fix should become one commit. So we right-click on MyLibraryTest, Source Control, Commit Selected Files. This opens a dialog that shows which files were modified and prompts for a commit message.</p>
<p>Since we fixed issue number #001 with that we also add this tag, because later we will see that GitHub conveniently links this commit with the issue via this number.</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-1.24.03-PM.png"><img class="alignnone  wp-image-5864" title="First commit" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-1.24.03-PM.png" alt="" width="608" height="326" /></a></p>
<p>This committing basically saves the current state in your local Git repository (your clone) and adds your message to that. Actually it did a bit more than that, because Git has a an extra step called &#8220;staging&#8221; before committing.</p>
<p>In staging you select the modifications you want to be part of the commit by Adding them to the staging area. The second part then does this saving. If you do this via the Xcode interface you don&#8217;t need this staging phase because you specifically selected the files to commit already via the project navigator.</p>
<p>The second issue to fix is to change a build setting on the sub-project.</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-1.33.27-PM.png"><img class="alignnone  wp-image-5865" title="Issue 2" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-1.33.27-PM.png" alt="" width="557" height="271" /></a></p>
<p>This time the M appears next to the MyLibrary.xcodeproj which really means the project.pbxproj file contained in the MyLibrary.xcodeproj bundle. (Remember that a bundle is a folder that looks like a file)</p>
<p>This time let&#8217;s do the committing on the command like, like a real pro. First let&#8217;s see the status.</p>

<div class="wp_codebox"><table><tr id="p585919"><td class="code" id="p5859code19"><pre class="sh" style="font-family:monospace;">git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changes not staged for commit:
#   (use &quot;git add ...&quot; to update what will be committed)
#   (use &quot;git checkout -- ...&quot; to discard changes in working directory)
#
#	modified:   MyLibrary/MyLibrary.xcodeproj/project.pbxproj
#
no changes added to commit (use &quot;git add&quot; and/or &quot;git commit -a&quot;)</pre></td></tr></table></div>

<p>This shows that we are ahead of our fork (origin/master) by 1 commit, which is the previous one we did. And it shows that the project file for the sub-project was modified. We issue a &#8220;git commit -a&#8221; which stages all modified files for the commit and immediately prompts us for a commit message in the currently set up text editor.</p>
<p>There is a second shortcut that GitHub recognizes besides the #002 tag. If you write &#8220;closes&#8221; or &#8220;fixes&#8221; in front of the hashtag it not only references the issue, but also marks it as closed. How convenient!</p>
<p>&#8220;Set Skip Install YES for resource bundle to prevent copying that into Archive. closes #002&#8243;</p>
<p>I type my message into the VIM that opened and save/exit via ESC, :wq, ENTER.</p>
<p>Now we have two local commits (git log to see them), next we need to push them to our online repository. We just had modifications to the project file in these two examples, but &#8211; trust me &#8211; it works just as well for code changes.</p>
<h3>Step 5 &#8211; Push Up</h3>
<p>When we cloned the project to our local hard disk Git was nice enough to automatically configure the location where it came from as so called &#8220;Remote&#8221;, the default name is &#8220;origin&#8221;. You can have multiple remote places set up and choose which to push.</p>
<p>The command for us is:</p>

<div class="wp_codebox"><table><tr id="p585920"><td class="code" id="p5859code20"><pre class="sh" style="font-family:monospace;">git push origin master</pre></td></tr></table></div>

<p>&#8220;origin&#8221; is the remote I told you about, &#8220;master&#8221; means that you are pushing this to the master branch, which is the default branch.</p>
<p>To check if our changes have really arrived online I like to check the commits view on GitHub. And indeed they have.</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-1.50.45-PM.png"><img class="alignnone  wp-image-5866" title="Commits have landed" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-1.50.45-PM.png" alt="" width="756" height="249" /></a></p>
<p>We could end here and many people do. They just make a copy of an Open Source project for the case that the original repository disappears. But since we are playing nice we want to offer our improvements to the original project&#8217;s owner.</p>
<h3>Step 6 &#8211; I just called to say &#8220;Please Pull Me!&#8221;</h3>
<p>Just like for the fork we find a &#8220;Pull Request&#8221; button at the top right of the GitHub website of our fork. Push it and you get a nice overview of what is contained in the request.</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-1.56.06-PM.png"><img class="alignnone  wp-image-5867" title="Pull Request" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-1.56.06-PM.png" alt="" width="660" height="500" /></a></p>
<p>There are some advanced options regarding milestones and assignments, but we&#8217;ll ignore these for now. You&#8217;ll notice that the pull request automatically generates a new number, #3 in our case. So you can not only reference issues with your commit messages, but the same thing is possible for pull requests.</p>
<p>The final step is not for us, but for the original project&#8217;s owner to perform.</p>
<h3>Step 7 &#8211; Accepted!</h3>
<p>As owner of a GitHub repo it is up to you whether you want to accept the changes into your repository. If you kept your commits small and &#8211; for code changes &#8211; added some good comments to aid understanding then the owner will be happy to accept them. It saves him from doing the work that you did and all he needs is to push the green merge button.</p>
<p><a href="http://www.cocoanetics.com/files/Screen-Shot-2012-01-26-at-13.41.53.png"><img class="alignnone  wp-image-5871" title="Accepting" src="http://www.cocoanetics.com/files/Screen-Shot-2012-01-26-at-13.41.53.png" alt="" width="669" height="422" /></a></p>
<p>The button to accept the changes is only green if the merge of the code can be performed automatically. If the author did some changes on his own that conflict with yours then the button is gray stating that the changes cannot be merged automatically. In this unfortunate situation either one of you needs to pull the other&#8217;s changes and manually resolve the merging conflicts. But this is a topic for another day.</p>
<h3>Conclusion</h3>
<p>I suggest you find yourself a a GitHub project to contribute to and try out this process to shed the timid feeling. It really is quite idiot proof.</p>
<p>People put their projects on GitHub not only so that you get free source code to use in your apps. They also hope that other developers might find and fix bugs. And every once in a while you see a pull request that makes you think &#8220;OMG I&#8217;m not worthy!&#8221; because those are the gems that really teach you something.</p>
<p>And this is why they call it collaborative coding.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5859&amp;md5=450103b7bf2d416c4504c16e867994e4" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/01/github-fork-fix-pull-request/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5859&amp;md5=450103b7bf2d416c4504c16e867994e4" type="text/html" />"
	</item>
		<item>
		<title>iPhone User Interface Cookbook</title>
		<link>http://www.cocoanetics.com/2012/01/iphone-user-interface-cookbook/</link>
		<comments>http://www.cocoanetics.com/2012/01/iphone-user-interface-cookbook/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 07:37:55 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5851</guid>
		<description><![CDATA[A month ago I was contacted by PacktPub with a &#8220;Review Request&#8221; and was provided with a ePub copy of the book for this exact purpose. PacktPub &#8211; which I had never heard of before &#8211; apparently is trying to get traction on the iOS developer market with a dozen books on the subject matter. But this pales in comparison to the hundreds of books they published for non-iOS ecosystems (Microsoft, Web, Java, etc.) Is it just me or does it seem like more and more iOS developer are hoping to supplement their living from getting book royalties? At the end of my procrastination I sat down and forced myself to read the first half of the book, taking notes to give this book a fair and balanced review. A word of caution: this will be a tragic comedy of epic proportions. In Austria we have a saying: &#8220;Nothing is useless, it can always serve as a bad example&#8221;. It is my hope that this bad example serves to improve the overall quality of literature on our favorite subject matter. Label Buy an ad here The title of the work suggests that this book is not meant to be read in a linear fashion. You&#8217;d expect from a &#8220;Cookbook&#8221; to find &#8220;Recipes&#8221; for individual things that you would look up should you need to cook them. In the chapter about the book&#8217;s copyright you can read: Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. So far so good, but who is this book meant for? In the words of the author: The iPhone Interface Cookbook is written from the ground up for people who are new to iOS or application interface design in general. Each chapter discusses the reasoning and design strategy behind critical interface components, as well as how to best integrate each into any iPhone or iPad application. Detailed and straight-forward recipes help give guidance and build understanding far beyond what is offered through Apple&#8217;s Human Interface Guidelines. From these two parts of information &#8211; and possibly the short author&#8217;s bio &#8211; you come to expect a highly polished work that may sit on the shelf of a fledgling iOS developer getting his feet wet on his first couple of apps. A reference manual for design, if you will. This puts me at odds with the premise. Neither am I fledgling, nor am I designer. I love to code and generally I like to delegate designing UI and UX to the companies that hire me. After having realized this I gave the book a second chance in my head: if it is worth the expense maybe I could recommend it to those designers sitting in my client&#8217;s companies for reference? As an iOS contractor you often have to deal with companies that have established themselves on non-iOS platforms and now &#8211; due to public and marketing pressures &#8211; they also want an iOS app. Generally their in-house designers will know how to design a Windows app or website. Often I have wished for being able to recommend to them a guide as to what they have to do differently when designing for our platform. This book isn&#8217;t that either. Maybe I was &#8220;holding it wrong&#8221; because I read the book from the front cover to slightly more than half when I had to abort the mission. I&#8217;m detail oriented by nature and so I found boatloads of errors, formatting problems and blatant omissions with which I filled a note on Evernote with. For example this is how e-mail addresses are formatted throughout. What do you think if you see this? At first I attributed the problems I was seeing to the ePub format. Apparently the publisher did not invest in this being properly edited. Neither from a formatting point of view nor in terms of technical correctness. Each chapter in the book slavishly follows this structure: Getting ready, How to do it&#8230;, How it works&#8230;, There&#8217;s more&#8230;, See also. The general style hides some interesting information in a tone ripe with fluff and half-truths. And what&#8217;s even more annoying is that these mini-sections all take up space in the index which is destroying that as well. In this example you can see the worthless index. Why in god&#8217;s name would I want to directly jump to a There&#8217;s more in a section? You have no way of quickly getting an overview of what &#8220;Recipe&#8221; would be the right one for a real-life design case. Except wade through these superfluous entries of sub-sections. I admitted that I am probably a) not the right person and b) not reading it correctly. But the problems with [...]]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/01/iphone-user-interface-cookbook/"></g:plusone></div><p>A month ago I was contacted by <a href="https://www.packtpub.com/books/iphone">PacktPub</a> with a &#8220;Review Request&#8221; and was provided with a ePub copy of the book for this exact purpose. PacktPub &#8211; which I had never heard of before &#8211; apparently is trying to get traction on the iOS developer market with a dozen books on the subject matter. But this pales in comparison to the hundreds of books they published for non-iOS ecosystems (Microsoft, Web, Java, etc.)</p>
<p>Is it just me or does it seem like more and more iOS developer are hoping to supplement their living from getting book royalties?</p>
<p>At the end of my procrastination I sat down and forced myself to read the first half of the book, taking notes to give this book a fair and balanced review. A word of caution: this will be a tragic comedy of epic proportions.</p>
<p>In Austria we have a saying: <em>&#8220;Nothing is useless, it can always serve as a bad example&#8221;</em>. It is my hope that this bad example serves to improve the overall quality of literature on our favorite subject matter.</p>
<p><span id="more-5851"></span></p>
<div class="inner_ad_block">
<div id="advman-7" class="widget Advman_Widget">
<h3 class="widgettitle"></h3>
<p><!-- BuySellAds.com Zone Code --></p>
<div id="bsap_1260346" class="bsarocks bsap_fc3166ea4a479e0fdb4251fbe92a1219"></div>
<p><!-- End BuySellAds.com Zone Code --></div>
<div id="text-21" class="widget widget_text">
<h3 class="widgettitle">Label</h3>
<div class="textwidget">
<div class="advert-notice"><a href="http://buysellads.com/buy/detail/56639/zone/1260346">Buy an ad here</a></div>
</div></div>
</div>
<p>The title of the work suggests that this book is not meant to be read in a linear fashion. You&#8217;d expect from a &#8220;Cookbook&#8221; to find &#8220;Recipes&#8221; for individual things that you would look up should you need to cook them. In the chapter about the book&#8217;s copyright you can read:</p>
<blockquote><p>Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied.</p></blockquote>
<p>So far so good, but who is this book meant for? In the words of the author:</p>
<blockquote><p>The iPhone Interface Cookbook is written from the ground up for people who are new to iOS or application interface design in general. Each chapter discusses the reasoning and design strategy behind critical interface components, as well as how to best integrate each into any iPhone or iPad application. Detailed and straight-forward recipes help give guidance and build understanding far beyond what is offered through Apple&#8217;s Human Interface Guidelines.</p></blockquote>
<p>From these two parts of information &#8211; and possibly the short author&#8217;s bio &#8211; you come to expect a highly polished work that may sit on the shelf of a fledgling iOS developer getting his feet wet on his first couple of apps. A reference manual for design, if you will.</p>
<p>This puts me at odds with the premise. Neither am I fledgling, nor am I designer. I love to code and generally I like to delegate designing UI and UX to the companies that hire me. After having realized this I gave the book a second chance in my head: if it is worth the expense maybe I could recommend it to those designers sitting in my client&#8217;s companies for reference?</p>
<p>As an iOS contractor you often have to deal with companies that have established themselves on non-iOS platforms and now &#8211; due to public and marketing pressures &#8211; they also want an iOS app. Generally their in-house designers will know how to design a Windows app or website. Often I have wished for being able to recommend to them a guide as to what they have to do differently when designing for our platform.</p>
<p>This book isn&#8217;t that either.</p>
<p>Maybe I was &#8220;holding it wrong&#8221; because I read the book from the front cover to slightly more than half when I had to abort the mission. I&#8217;m detail oriented by nature and so I found boatloads of errors, formatting problems and blatant omissions with which I filled a note on Evernote with.</p>
<p>For example this is how e-mail addresses are formatted throughout. What do you think if you see this?</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-07.58.16.png"><img class="alignnone size-full wp-image-5854" title="Wrong formatting of e-mails" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-26-um-07.58.16.png" alt="" width="335" height="96" /></a></p>
<p>At first I attributed the problems I was seeing to the ePub format. Apparently the publisher did not invest in this being properly edited. Neither from a formatting point of view nor in terms of technical correctness.</p>
<p>Each chapter in the book slavishly follows this structure: Getting ready, How to do it&#8230;, How it works&#8230;, There&#8217;s more&#8230;, See also. The general style hides some interesting information in a tone ripe with fluff and half-truths.</p>
<p>And what&#8217;s even more annoying is that these mini-sections all take up space in the index which is destroying that as well. In this example you can see the worthless index. Why in god&#8217;s name would I want to directly jump to a There&#8217;s more in a section? You have no way of quickly getting an overview of what &#8220;Recipe&#8221; would be the right one for a real-life design case. Except wade through these superfluous entries of sub-sections.</p>
<p><a href="http://www.cocoanetics.com/files/IMG_0048.png"><img class="alignnone  wp-image-5853" title="The problematic index" src="http://www.cocoanetics.com/files/IMG_0048.png" alt="" width="461" height="614" /></a></p>
<p>I admitted that I am probably a) not the right person and b) not reading it correctly. But the problems with this book go far beyond the formatting.</p>
<p>Somehow I am getting the feeling that the individual chapters in this book might have been articles on a blog, that somebody just copy/pasted together and replaced all instances of &#8220;article&#8221; with &#8220;recipe&#8221; and &#8220;blog&#8221; with &#8220;book&#8221;. Is that truly the way how modern developers expect their information to be diced?</p>
<p>For one thing you&#8217;d expect from an experienced iOS developer to know how to spell the name of our IDE correctly. Instead Cameron (or is it a lawman editor?) insists on spelling it <strong>XCode</strong>. This book couldn&#8217;t have been edited on a Mac because even my WordPress autocorrected that to Xcode. Purists might call this a blatant disregard for what is holy.</p>
<p>There are many more examples of misspelled classes, apps or terms we iOS developers deal with every day. To give a second example: WebKit is one word, not two.</p>
<p>Ok, there are formatting problems (ePub&#8217;s fault), there are technical editing problems. To top it off there are factual problems as well.</p>
<p>The author details how to generated certificates on the provisioning portal, but omits the simple information that you can just connect your device via USB, click on the &#8220;User for Development&#8221; button in Xcode Organizer and have Xcode auto-provision the device in your &#8220;iOS Team Provisioning Profile&#8221;.</p>
<p>Then there is much commingling. Alert Views are thrown in together with modal view controllers. Later they are mashed up with push notifications and local notifications. And the rationalization for why everything is modal:  <em>&#8220;iOS is a highly modal operating system, forcing one application at a time upon the user.&#8221;</em></p>
<p>There are 4 step guides where the second and third step are identical, just worded differently. There are in-depth explanations about topic that a designer has no interest in, and the interesting topics are covered incompletely. In truth I found two or three nuggets of information buried deep in what I read. For example I found the explanation on <a href="http://en.wikipedia.org/wiki/Fitts's_law">Fitt&#8217;s Law</a> quite interesting, didn&#8217;t know that.</p>
<p>Sooner or later you realize that the statement from the Copyright section is a lie. &#8220;Every effort&#8221; was definitely <em>not</em> made and the information isn&#8217;t presented at an acceptable level of &#8220;accuracy&#8221;.</p>
<p>The second promise that the publisher did not keep is who the book is for. Where are the explanations &#8220;far beyond&#8221; of what you can find in Apple&#8217;s HIG? Where are the chapters that I can recommend to the UI/UX designer working at my client&#8217;s?</p>
<p>I had to stop reading half way through, when I had accumulated 3 screenfuls of &#8220;bugs&#8221;. I am not getting paid to correct this book, so that amount exceeded the level of bullish!t I was willing to put up with. My job is to evaluate whether this work of art is worthy of your attention.</p>
<p>By now you should fathom my opinion.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5851&amp;md5=ad60b93b5c1876c9b2e90f344800522b" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/01/iphone-user-interface-cookbook/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5851&amp;md5=ad60b93b5c1876c9b2e90f344800522b" type="text/html" />"
	</item>
		<item>
		<title>DTCoreText &#8211; New Formula!</title>
		<link>http://www.cocoanetics.com/2012/01/dtcoretext-new-formula/</link>
		<comments>http://www.cocoanetics.com/2012/01/dtcoretext-new-formula/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 08:02:06 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5844</guid>
		<description><![CDATA[I chose this article&#8217;s title to try and grab your attention. Well, the product is still the same and does the same. The only difference is one that is under the hood. And as such it is your job &#8211; should you choose to accept it &#8211; to marvel at the benefits that the new old parsing engine brings us. Label Buy an ad here Ever since my friends at scribd showed me a first prototype for HTML parsing based on libxml2 I was &#8211; admittedly &#8211; jealous. This prototype basically worked by having libxml2 parse out the individual paragraphs of an article and then display each paragraph in its own cell of a UITableView. Back then I brushed off the suggestion and went with something I understood: NSScanner. All the C-code necessary to deal with libxml2 seemed overly daunting, so I went with a simple basic structure for the parsing, something like this (pseudocode) while &#40;there_is_more&#41; &#123; if &#40;we_scanned_a_tag&#41; &#123; if &#40;is_tag_a&#41; &#123; // a specific code &#125; else if &#40;is_tag_b&#41; &#123; // b specific code &#125; else if ... &#125; else &#123; // we must be inside a tag &#160; // deal with skipping over a tag that is incomplete, i.e. crap &#160; if &#40;we_scanned_some_text_before_the_next_tag_open&#41; &#123; // append the text with correct formatting to the output &#125; &#125; &#125; This structure had grown organically as I added support for additional tags and it went into the initWithHTML category method because that seemed to be the logical place. Little did I think ahead that this approach would preclude the possibility of having an event-based parser do callbacks into my code, because that would mean adding these event-handling methods to NSAttributedString. Even the above pseudocode  is long, you can imagine how much of a Spaghetti the origin code became. Much of the problem didn&#8217;t actually come from all these tags, those where simply a big if-statement. Complexity came from having to deal with all these special cases where HTML might not be well-formed. In my Open Source genstrings2 I saw how much faster pure C-code performs than NSScanner which also served to rekindle my wish to switch to libxml2 because this is also written in low-level highly optimized C. I approached libxml2 in several steps: Jealousy &#8211; &#8220;Boy wouldn&#8217;t it be great, but I&#8217;m afraid that this is out of my league&#8221; Announce Intention &#8211; I wrote an issue on GitHub hoping for somebody to step forward Do an Experiment and Document &#8211; I googled a bit and put together Part 1 of my libxml HTML tutorial. Write a Wrapper &#8211; For Part 2 of my libxml HTML tutorial I wrote an Objective-C wrapper for libxml2. Astonishment &#8211; The feeling you get when you find that you begin to understand the C-code needed Benchmark &#8211; I removed all string building code and compared the raw parsing performance of both approaches Transform the Pasta &#8211; Moved the code for building the attributed string into an aptly named class and have this driven from events generated by the new HTML parser. The final step I called like this because if you break up Spaghetti code into several logical pieces and then layer these into several layers that&#8217;s a different kind of Pasta, that&#8217;s called Lasagne. For step 6, the comparison I moved the NSScanner parsing loop into its own class and directly compared the running time on my iPhone 4S resulting in this tweet: War&#38;Peace HTML (3.4 MB), NSScanner: 4.264s, libxml2: 1.398s = 3x as fast on single thread, plus latter fixes HTML structure At this stage it was clear to me that I need no extra self-convincing. So I went to work in a branch of the project. Most of the work was simply copy/pasting the attributed string building code into the right place, tag start, tag end or the characters found event method. This also allowed for omitting some workarounds that where needed to deal with non-well-formed HTML. The second big BIG advantage of libxml2 is that its HTML parser fixes up the structure for you and also adds a missing html and body tag so that you end up with a perfect structure. It even adds a &#60;/br&#62; right after a &#60;br&#62;. Even though this is completely unnecessary it still makes the HTML look like perfect XML. Much nicer to work with. While I was doing the migrating new issues and pull requests with fixes stated to come in putting me a bit under stress because I needed to include the fixes in both branches. Which is why I decided to merge the branch back into master at the earliest possible time. The initWithHTML method has shrunken to a much more manageable size: - &#40;id&#41;initWithHTML:&#40;NSData *&#41;data options:&#40;NSDictionary *&#41;options documentAttributes:&#40;NSDictionary **&#41;dict &#123; // only with valid data if &#40;!&#91;data length&#93;&#41; &#123; [...]]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/01/dtcoretext-new-formula/"></g:plusone></div><p>I chose this article&#8217;s title to try and grab your attention. Well, the product is still the same and does the same. The only difference is one that is under the hood. And as such it is your job &#8211; should you choose to accept it &#8211; to marvel at the benefits that the new old parsing engine brings us.</p>
<p><span id="more-5844"></span></p>
<div class="inner_ad_block">
<div id="advman-7" class="widget Advman_Widget">
<h3 class="widgettitle"></h3>
<p><!-- BuySellAds.com Zone Code --></p>
<div id="bsap_1260346" class="bsarocks bsap_fc3166ea4a479e0fdb4251fbe92a1219"></div>
<p><!-- End BuySellAds.com Zone Code --></div>
<div id="text-21" class="widget widget_text">
<h3 class="widgettitle">Label</h3>
<div class="textwidget">
<div class="advert-notice"><a href="http://buysellads.com/buy/detail/56639/zone/1260346">Buy an ad here</a></div>
</div></div>
</div>
<p>Ever since my friends at scribd showed me a first prototype for HTML parsing based on libxml2 I was &#8211; admittedly &#8211; jealous. This prototype basically worked by having libxml2 parse out the individual paragraphs of an article and then display each paragraph in its own cell of a UITableView. Back then I brushed off the suggestion and went with something I understood: NSScanner.</p>
<p>All the C-code necessary to deal with libxml2 seemed overly daunting, so I went with a simple basic structure for the parsing, something like this (pseudocode)</p>

<div class="wp_codebox"><table><tr id="p584423"><td class="code" id="p5844code23"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">while</span> <span style="color: #002200;">&#40;</span>there_is_more<span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#123;</span>
   <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>we_scanned_a_tag<span style="color: #002200;">&#41;</span>
   <span style="color: #002200;">&#123;</span>
      <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>is_tag_a<span style="color: #002200;">&#41;</span>
      <span style="color: #002200;">&#123;</span>
         <span style="color: #11740a; font-style: italic;">// a specific code</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>is_tag_b<span style="color: #002200;">&#41;</span>
      <span style="color: #002200;">&#123;</span>
         <span style="color: #11740a; font-style: italic;">//  b specific code</span>
      <span style="color: #002200;">&#125;</span>
      <span style="color: #a61390;">else</span> <span style="color: #a61390;">if</span> ...
   <span style="color: #002200;">&#125;</span>
   <span style="color: #a61390;">else</span>
   <span style="color: #002200;">&#123;</span>
      <span style="color: #11740a; font-style: italic;">// we must be inside a tag</span>
&nbsp;
      <span style="color: #11740a; font-style: italic;">// deal with skipping over a tag that is incomplete, i.e. crap</span>
&nbsp;
      <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>we_scanned_some_text_before_the_next_tag_open<span style="color: #002200;">&#41;</span>
      <span style="color: #002200;">&#123;</span>
         <span style="color: #11740a; font-style: italic;">// append the text with correct formatting to the output</span>
      <span style="color: #002200;">&#125;</span>
   <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>This structure had grown organically as I added support for additional tags and it went into the initWithHTML category method because that seemed to be the logical place. Little did I think ahead that this approach would preclude the possibility of having an event-based parser do callbacks into my code, because that would mean adding these event-handling methods to NSAttributedString.</p>
<p>Even the above pseudocode  is long, you can imagine how much of a Spaghetti the origin code became. Much of the problem didn&#8217;t actually come from all these tags, those where simply a big if-statement. Complexity came from having to deal with all these special cases where HTML might not be well-formed.</p>
<p>In my Open Source <a title="C-Code outperforms NSScanner" href="http://www.cocoanetics.com/2012/01/c-code-outperforms-nsscanner/">genstrings2</a> I saw how much faster pure C-code performs than NSScanner which also served to rekindle my wish to switch to libxml2 because this is also written in low-level highly optimized C.</p>
<p>I approached libxml2 in several steps:</p>
<ol>
<li><strong>Jealousy</strong> &#8211; &#8220;Boy wouldn&#8217;t it be great, but I&#8217;m afraid that this is out of my league&#8221;</li>
<li><strong>Announce Intention</strong> &#8211; I wrote an <a href="https://github.com/Cocoanetics/DTCoreText/issues/70">issue on GitHub</a> hoping for somebody to step forward</li>
<li><strong>Do an Experiment and Document</strong> &#8211; I googled a bit and put together <a title="Taming HTML Parsing with libxml (1)" href="http://www.cocoanetics.com/2011/09/taming-html-parsing-with-libxml-1/">Part 1 of my libxml HTML tutorial</a>.</li>
<li><strong>Write a Wrapper</strong> &#8211; For <a title="Taming HTML Parsing with libxml (2)" href="http://www.cocoanetics.com/2012/01/taming-html-parsing-with-libxml-2/">Part 2 of my libxml HTML tutorial</a> I wrote an Objective-C wrapper for libxml2.</li>
<li><strong>Astonishment</strong> &#8211; The feeling you get when you find that you begin to understand the C-code needed</li>
<li><strong>Benchmark</strong> &#8211; I removed all string building code and compared the raw parsing performance of both approaches</li>
<li><strong>Transform the Pasta</strong> &#8211; Moved the code for building the attributed string into an aptly named class and have this driven from events generated by the new HTML parser.</li>
</ol>
<p>The final step I called like this because if you break up Spaghetti code into several logical pieces and then layer these into several layers that&#8217;s a different kind of Pasta, that&#8217;s called <em>Lasagne</em>.</p>
<p>For step 6, the comparison I moved the NSScanner parsing loop into its own class and directly compared the running time on my iPhone 4S resulting in this tweet:</p>
<blockquote><p>War&amp;Peace HTML (3.4 MB), NSScanner: 4.264s, libxml2: 1.398s = 3x as fast on single thread, plus latter fixes HTML structure</p></blockquote>
<p>At this stage it was clear to me that I need no extra self-convincing. So I went to work in a branch of the project. Most of the work was simply copy/pasting the attributed string building code into the right place, tag start, tag end or the characters found event method. This also allowed for omitting some workarounds that where needed to deal with non-well-formed HTML.</p>
<p>The second big BIG advantage of libxml2 is that its HTML parser fixes up the structure for you and also adds a missing html and body tag so that you end up with a perfect structure. It even adds a &lt;/br&gt; right after a &lt;br&gt;. Even though this is completely unnecessary it still makes the HTML look like perfect XML. Much nicer to work with.</p>
<p>While I was doing the migrating new issues and pull requests with fixes stated to come in putting me a bit under stress because I needed to include the fixes in both branches. Which is why I decided to merge the branch back into master at the earliest possible time.</p>
<p>The initWithHTML method has shrunken to a much more manageable size:</p>

<div class="wp_codebox"><table><tr id="p584424"><td class="code" id="p5844code24"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>initWithHTML<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/"><span style="color: #400080;">NSData</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>data options<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/"><span style="color: #400080;">NSDictionary</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>options documentAttributes<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/"><span style="color: #400080;">NSDictionary</span></a> <span style="color: #002200;">**</span><span style="color: #002200;">&#41;</span>dict
<span style="color: #002200;">&#123;</span>
	<span style="color: #11740a; font-style: italic;">// only with valid data</span>
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>data length<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
&nbsp;
		<span style="color: #a61390;">return</span> <span style="color: #a61390;">nil</span>;
	<span style="color: #002200;">&#125;</span>
&nbsp;
	DTHTMLAttributedStringBuilder	<span style="color: #002200;">*</span>stringBuilder <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>DTHTMLAttributedStringBuilder alloc<span style="color: #002200;">&#93;</span> initWithHTML<span style="color: #002200;">:</span>data options<span style="color: #002200;">:</span>options documentAttributes<span style="color: #002200;">:</span>dict<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #002200;">&#91;</span>stringBuilder buildString<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span>stringBuilder generatedAttributedString<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>&nbsp;</p>
<h3>Benchmark after the Merge</h3>
<p>And of course I did some further benchmarking on my iPhone 4S to compare the resulting speed increase. All tests where done by simply adding two NSLogs at the beginning and end of the initWithHTML method and subtracting the timestamps. Note that this is just the time for building the attributed string and does not include the layouting or drawing.</p>
<p><strong>Demo HTML Snippet </strong></p>
<p>NSScanner: 50 ms</p>
<p>libxml2: 43 ms</p>
<p><strong>War&amp;Peace ePub HTML </strong></p>
<p>NSScanner: 10.968 sec</p>
<p>libxml2: 8.796 sec</p>
<p>This is an overall parsing and string building speed increase of between 14% and  22%.</p>
<p>You might now ask what happened to the 60% increase we saw from just comparing the parsers. The string building itself is still all happening on the same thread as the parsing and by itself has many opportunities for optimization.</p>
<p>For one thing the next thing I&#8217;d like to do is to put the string building operations onto its own GCD background queue. This way the events coming in from libxml would hand off to a queue running on a different thread and would immediately return to parsing. This could easily double the overall scanning performance because you can now make use of the two CPU cores present in the more modern iOS devices.</p>
<p>And there are obviously many more optimizations that now are feasible to do because you no longer face a daunting monster spaghetti but instead stand a chance of understanding what is happing in DTHTMLAttributedStringBuilder.</p>
<h3>Conclusion</h3>
<p>The main three advantages of libxml2 over NSScanner are: Performance, HTML non-wellformedness-resilience, simpler code through event-based handling of HTML.</p>
<p>This merge now makes it possible again for interested developers to contribute optimizations and new features because the code has become so much simpler to read and understand.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5844&amp;md5=d6b5362e768acd24bbeb0015ef65e2ac" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/01/dtcoretext-new-formula/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5844&amp;md5=d6b5362e768acd24bbeb0015ef65e2ac" type="text/html" />"
	</item>
		<item>
		<title>Earnings Call</title>
		<link>http://www.cocoanetics.com/2012/01/earnings-call/</link>
		<comments>http://www.cocoanetics.com/2012/01/earnings-call/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 23:03:39 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Apple]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5842</guid>
		<description><![CDATA[Here are my mental notes for today&#8217;s earnings call&#8230; Label Buy an ad here Peter Oppenheimer, CFO &#8220;Highest Quarter Earnings and Revenue&#8221;, &#8221;All Time Highs&#8221; 3-4 Weeks Mac channel inventory MAS: 100 Mio Downloads in less than a year 128% YOY grown in iPhone, &#8220;tremendous popularity of iPhone 4S&#8221;. Target range 4-6 weeks of iPhone channel inventory available in over 90 country iPads increase 111%, accessories grew 99%. Within 4-6 weeks of iPad channel inventory. With iBook Author anyone can create &#8220;iBook Textbooks, Cookbooks, picture books and more&#8221; &#62; 85 Million customers on iCloud Half of Macs sold in stores are to New Mac users &#8220;Easy Pay&#8221; checkout process key in handling the amount of buyers in store They are actively discussing on what do do with their cash balance, but nothing to announce yet. Extremely enthusiastic about their product pipeline. Tim Cook, CEO &#8211; Q&#38;A iPhone grows at 3 times of the mobile phone market Sold more iPhones than they expected, so called &#8220;short in channel inventory&#8221;. Caught up in some countries, but not all. Component environment is and will stay favorable, except for hard disks (Thailand). Did get better prices for displays, NANDs, DRAM last quarter. iPad: hugh opportunity for Apple, tablet market will be larger than PC market. &#8220;Limited function and eReaders&#8221; are a different category and thus not a thread. Who wants an iPads gets one. They&#8217;ll &#8220;continue to innovate like crazy in this area.&#8221; Team at Apple &#8220;so incredible&#8221;. &#8220;We feel very good about where we are&#8221; 5 Reasons why this quarter will be earning less than last Dec quarter had a 14th week = 1/14th of the Revenue, DOH A week missing in March Quarter that is usually going well Last year they produced more iPhones &#8220;significant pent up demand for 4S&#8221; Strengthening of Dollar against the Euro About acquisitions: Apple generally believes in totally integrating acquired companies into the mothership. &#8220;You will be assimilated, resistance is futile&#8221; (well at least that&#8217;s what I thought to myself) &#8220;There was not an obvious aspect on the numbers&#8221; regarding if the Kindle Fire had any positive or negative effect on iPad sales. iPad cannibalizes the Mac, but much more cannibalizes Windows PCs. Mac has outgrown market for 20 quarters in a row. Seems like all of the data make it a very close race against Android, iPad is way ahead. Though it&#8217;s hard to get any &#8220;crisp numbers&#8221; on Android handset shipments. &#8220;iOS is doing extremely well&#8221;. Prefers to ignore the &#8220;other horses&#8221; and focus on innovating. And when asked about larger screens and LTE we got usual response.]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/01/earnings-call/"></g:plusone></div><p>Here are my mental notes for today&#8217;s earnings call&#8230;</p>
<p><span id="more-5842"></span></p>
<div class="inner_ad_block">
<div id="advman-7" class="widget Advman_Widget">
<h3 class="widgettitle"></h3>
<p><!-- BuySellAds.com Zone Code --></p>
<div id="bsap_1260346" class="bsarocks bsap_fc3166ea4a479e0fdb4251fbe92a1219"></div>
<p><!-- End BuySellAds.com Zone Code --></div>
<div id="text-21" class="widget widget_text">
<h3 class="widgettitle">Label</h3>
<div class="textwidget">
<div class="advert-notice"><a href="http://buysellads.com/buy/detail/56639/zone/1260346">Buy an ad here</a></div>
</div></div>
</div>
<p><strong>Peter Oppenheimer, CFO</strong></p>
<p>&#8220;Highest Quarter Earnings and Revenue&#8221;, &#8221;All Time Highs&#8221;</p>
<p>3-4 Weeks Mac channel inventory</p>
<p>MAS: 100 Mio Downloads in less than a year</p>
<p>128% YOY grown in iPhone, &#8220;tremendous popularity of iPhone 4S&#8221;. Target range 4-6 weeks of iPhone channel inventory</p>
<p>available in over 90 country</p>
<p>iPads increase 111%, accessories grew 99%. Within 4-6 weeks of iPad channel inventory.</p>
<p>With iBook Author anyone can create &#8220;iBook Textbooks, Cookbooks, picture books and more&#8221;</p>
<p>&gt; 85 Million customers on iCloud</p>
<p>Half of Macs sold in stores are to New Mac users</p>
<p>&#8220;Easy Pay&#8221; checkout process key in handling the amount of buyers in store</p>
<p>They are actively discussing on what do do with their cash balance, but nothing to announce yet.</p>
<p>Extremely enthusiastic about their product pipeline.</p>
<p><strong>Tim Cook, CEO &#8211; Q&amp;A</strong></p>
<p>iPhone grows at 3 times of the mobile phone market</p>
<p>Sold more iPhones than they expected, so called &#8220;short in channel inventory&#8221;. Caught up in some countries, but not all.</p>
<p>Component environment is and will stay favorable, except for hard disks (Thailand). Did get better prices for displays, NANDs, DRAM last quarter.</p>
<p>iPad: hugh opportunity for Apple, tablet market will be larger than PC market. &#8220;Limited function and eReaders&#8221; are a different category and thus not a thread. Who wants an iPads gets one. They&#8217;ll &#8220;continue to innovate like crazy in this area.&#8221;</p>
<p>Team at Apple &#8220;so incredible&#8221;. &#8220;We feel very good about where we are&#8221;</p>
<p>5 Reasons why this quarter will be earning less than last</p>
<ol>
<li>Dec quarter had a 14th week = 1/14th of the Revenue, DOH</li>
<li>A week missing in March Quarter that is usually going well</li>
<li>Last year they produced more iPhones</li>
<li>&#8220;significant pent up demand for 4S&#8221;</li>
<li>Strengthening of Dollar against the Euro</li>
</ol>
<p>About acquisitions: Apple generally believes in totally integrating acquired companies into the mothership. &#8220;You will be assimilated, resistance is futile&#8221; (well at least that&#8217;s what I thought to myself)</p>
<p>&#8220;There was not an obvious aspect on the numbers&#8221; regarding if the Kindle Fire had any positive or negative effect on iPad sales. iPad cannibalizes the Mac, but much more cannibalizes Windows PCs.</p>
<p>Mac has outgrown market for 20 quarters in a row. Seems like all of the data make it a very close race against Android, iPad is way ahead. Though it&#8217;s hard to get any &#8220;crisp numbers&#8221; on Android handset shipments.</p>
<p>&#8220;iOS is doing <em>extremely</em> well&#8221;. Prefers to ignore the &#8220;other horses&#8221; and focus on innovating.</p>
<p>And when asked about larger screens and LTE we got usual response.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5842&amp;md5=78950e116e6cfb89ccbc40bd5fb37e6e" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/01/earnings-call/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5842&amp;md5=78950e116e6cfb89ccbc40bd5fb37e6e" type="text/html" />"
	</item>
		<item>
		<title>Taming HTML Parsing with libxml (2)</title>
		<link>http://www.cocoanetics.com/2012/01/taming-html-parsing-with-libxml-2/</link>
		<comments>http://www.cocoanetics.com/2012/01/taming-html-parsing-with-libxml-2/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 08:54:06 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Recipes]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5834</guid>
		<description><![CDATA[The parsing of HTML necessary for my DTCoreText open source project is done entirely with the sophisticated use of NSScanner. But it has been long on my list to rewrite all of this parsing with a the industry standard libxml2 which comes preinstalled on all iOS devices. Not only is this potentially much faster in dealing with large chunks of HTML. It probably is also more intelligent in correcting structural errors of the HTML code you throw at it. In part 1 of this series I showed you how to add the libxml2 library to your project and explained the basic concepts of using libxml2 for parsing any odd HTML snippet into a DOM. In this here part 2 we will create an Objective-C based wrapper around libml2 so that we can use it just like NSXMLParser, only for HTML. Label Buy an ad here There are basically two methods &#8211; approaches &#8211; to handling XML/HTML: DOM or SAX. DOM (short for Document Object Model) refers to building a tree of nodes and leaves which you then can query for information based on their path (with XPath). SAX (short for Simple API for XML) basically walks through the the document and sends you events as it discovers things. For example the begin of an element, the end of it, when a comment was found, etc. NSXMLParser is a SAX parser for well-formed XML. That means you can use it only on XML, it cannot deal with the nature of HTML where some elements might not require that you close them. But if you look at the delegate protocol and compare it to the SAX interface of libxml2 you find an eerie resemblance. It might as well be that NSXMLParser is just a wrapper around the XML SAX interface of libxml2. As we have previously learned we know that libxml2 also possesses a HTML parser which reuses most of the same internal data structures as its XML cousin. So we shall endeavor to create DTHTMLParser as a SAX parser for HTML. Don&#8217;t worry about piecing together all the source code from this article, I will put that online in my DTFoundation project. Instead I want you to follow my lead and understand the pieces. The libxml2 SAX Interface The SAX interface works such that you register a handler function &#8211; in C &#8211; for each SAX event that you are interested in. This is done via a C-structure of type htmlSAXHandler which is nothing more than an aggregate of multiple C-function pointers. In the libxml headers you often see some &#8220;html&#8230;&#8221; data structure typedef&#8217;d into one with &#8220;xml&#8221; as prefix. The reason for this is that it reuses whatever it can from the XML parser. But this also adds confusion &#8211; as I found through my experimenting &#8211; because some of the events that make sense for parsing XML don&#8217;t fire for HTML, like for example the one that reports CDATA elements. HTML does not have those, but the function pointer is still present in the htmlSAXHandler struct. By CMD+Clicking on a type we can swim upstream to find the original definition of htmlSAXHandler: htmlSAXHandler = xmlSAXHandler = _xmlSAXHandler = struct _xmlSAXHandler &#123; internalSubsetSAXFunc internalSubset; isStandaloneSAXFunc isStandalone; hasInternalSubsetSAXFunc hasInternalSubset; hasExternalSubsetSAXFunc hasExternalSubset; resolveEntitySAXFunc resolveEntity; getEntitySAXFunc getEntity; entityDeclSAXFunc entityDecl; notationDeclSAXFunc notationDecl; attributeDeclSAXFunc attributeDecl; elementDeclSAXFunc elementDecl; unparsedEntityDeclSAXFunc unparsedEntityDecl; setDocumentLocatorSAXFunc setDocumentLocator; startDocumentSAXFunc startDocument; endDocumentSAXFunc endDocument; startElementSAXFunc startElement; endElementSAXFunc endElement; referenceSAXFunc reference; charactersSAXFunc characters; ignorableWhitespaceSAXFunc ignorableWhitespace; processingInstructionSAXFunc processingInstruction; commentSAXFunc comment; warningSAXFunc warning; errorSAXFunc error; fatalErrorSAXFunc fatalError; /* unused error() get all the errors */ getParameterEntitySAXFunc getParameterEntity; cdataBlockSAXFunc cdataBlock; externalSubsetSAXFunc externalSubset; unsigned int initialized; /* The following fields are extensions available only on version 2 */ void *_private; startElementNsSAX2Func startElementNs; endElementNsSAX2Func endElementNs; xmlStructuredErrorFunc serror; &#125;; All these function pointer types are aptly named SomethingFunc and we&#8217;ll get to how these need to look like in a minute. The problem for us to solve how to bridge from our Objective-C paradigm (using self, properties, IVARs) into the C-function paradigm (no access to our parser object). This problem is compounded by the fact that we are building this with ARC so that we don&#8217;t have to deal with memory management any more. Our resulting class will run on iOS 4 and above. Somehow we need to pass enough information to each event-function so that we can communicate with the parser object. There are two reasonable possibilities: either we pass a reference to the parser instance or we pass a pointer to a struct that contains multiple values that we might need. I decided for the first because it seems cleaner to me. libxml2 provides a concept of a user_data pointer that is passed to the event-functions together with other relevant information. We can use (abuse?) this for passing a reference to self. ARC requires this to be be cast to (__bridge [...]]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/01/taming-html-parsing-with-libxml-2/"></g:plusone></div><p>The parsing of HTML necessary for my <a title="NSAttributedString+HTML Q&amp;A" href="http://www.cocoanetics.com/2011/08/nsattributedstringhtml-qa/">DTCoreText</a> open source project is done entirely with the sophisticated use of NSScanner. But it has been long on my list to rewrite all of this parsing with a the industry standard libxml2 which comes preinstalled on all iOS devices. Not only is this potentially much faster in dealing with large chunks of HTML. It probably is also more intelligent in correcting structural errors of the HTML code you throw at it.</p>
<p>In <a title="Taming HTML Parsing with libxml (1)" href="http://www.cocoanetics.com/2011/09/taming-html-parsing-with-libxml-1/">part 1 of this series</a> I showed you how to add the libxml2 library to your project and explained the basic concepts of using libxml2 for parsing any odd HTML snippet into a DOM. In this here part 2 we will create an Objective-C based wrapper around libml2 so that we can use it just like NSXMLParser, only for HTML.</p>
<p><span id="more-5834"></span></p>
<div class="inner_ad_block">
<div id="advman-7" class="widget Advman_Widget">
<h3 class="widgettitle"></h3>
<p><!-- BuySellAds.com Zone Code --></p>
<div id="bsap_1260346" class="bsarocks bsap_fc3166ea4a479e0fdb4251fbe92a1219"></div>
<p><!-- End BuySellAds.com Zone Code --></div>
<div id="text-21" class="widget widget_text">
<h3 class="widgettitle">Label</h3>
<div class="textwidget">
<div class="advert-notice"><a href="http://buysellads.com/buy/detail/56639/zone/1260346">Buy an ad here</a></div>
</div></div>
</div>
<p>There are basically two methods &#8211; approaches &#8211; to handling XML/HTML: DOM or SAX. DOM (short for Document Object Model) refers to building a tree of nodes and leaves which you then can query for information based on their path (with XPath). SAX (short for Simple API for XML) basically walks through the the document and sends you events as it discovers things. For example the begin of an element, the end of it, when a comment was found, etc.</p>
<p>NSXMLParser is a SAX parser for well-formed XML. That means you can use it only on XML, it cannot deal with the nature of HTML where some elements might not require that you close them. But if you look at the delegate protocol and compare it to the SAX interface of libxml2 you find an eerie resemblance. It might as well be that NSXMLParser is just a wrapper around the XML SAX interface of libxml2.</p>
<p>As we have previously learned we know that libxml2 also possesses a HTML parser which reuses most of the same internal data structures as its XML cousin. So we shall endeavor to create DTHTMLParser as a SAX parser for HTML.</p>
<p>Don&#8217;t worry about piecing together all the source code from this article, I will put that online in my <a href="https://github.com/Cocoanetics/DTFoundation">DTFoundation</a> project. Instead I want you to follow my lead and understand the pieces.</p>
<h3>The libxml2 SAX Interface</h3>
<p>The SAX interface works such that you register a handler function &#8211; in C &#8211; for each SAX event that you are interested in. This is done via a C-structure of type htmlSAXHandler which is nothing more than an aggregate of multiple <a title="Functions as Parameters – Old &amp; New" href="http://www.cocoanetics.com/2011/05/functions-as-parameters-old-new/">C-function pointers</a>.</p>
<p>In the libxml headers you often see some &#8220;html&#8230;&#8221; data structure typedef&#8217;d into one with &#8220;xml&#8221; as prefix. The reason for this is that it reuses whatever it can from the XML parser. But this also adds confusion &#8211; as I found through my experimenting &#8211; because some of the events that make sense for parsing XML don&#8217;t fire for HTML, like for example the one that reports CDATA elements. HTML does not have those, but the function pointer is still present in the htmlSAXHandler struct.</p>
<p>By CMD+Clicking on a type we can swim upstream to find the original definition of htmlSAXHandler:</p>
<p>htmlSAXHandler = xmlSAXHandler = _xmlSAXHandler =</p>

<div class="wp_codebox"><table><tr id="p583434"><td class="code" id="p5834code34"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">struct</span> _xmlSAXHandler <span style="color: #002200;">&#123;</span>
    internalSubsetSAXFunc internalSubset;
    isStandaloneSAXFunc isStandalone;
    hasInternalSubsetSAXFunc hasInternalSubset;
    hasExternalSubsetSAXFunc hasExternalSubset;
    resolveEntitySAXFunc resolveEntity;
    getEntitySAXFunc getEntity;
    entityDeclSAXFunc entityDecl;
    notationDeclSAXFunc notationDecl;
    attributeDeclSAXFunc attributeDecl;
    elementDeclSAXFunc elementDecl;
    unparsedEntityDeclSAXFunc unparsedEntityDecl;
    setDocumentLocatorSAXFunc setDocumentLocator;
    startDocumentSAXFunc startDocument;
    endDocumentSAXFunc endDocument;
    startElementSAXFunc startElement;
    endElementSAXFunc endElement;
    referenceSAXFunc reference;
    charactersSAXFunc characters;
    ignorableWhitespaceSAXFunc ignorableWhitespace;
    processingInstructionSAXFunc processingInstruction;
    commentSAXFunc comment;
    warningSAXFunc warning;
    errorSAXFunc error;
    fatalErrorSAXFunc fatalError; <span style="color: #11740a; font-style: italic;">/* unused error() get all the errors */</span>
    getParameterEntitySAXFunc getParameterEntity;
    cdataBlockSAXFunc cdataBlock;
    externalSubsetSAXFunc externalSubset;
    <span style="color: #a61390;">unsigned</span> <span style="color: #a61390;">int</span> initialized;
    <span style="color: #11740a; font-style: italic;">/* The following fields are extensions available only on version 2 */</span>
    <span style="color: #a61390;">void</span> <span style="color: #002200;">*</span>_private;
    startElementNsSAX2Func startElementNs;
    endElementNsSAX2Func endElementNs;
    xmlStructuredErrorFunc serror;
<span style="color: #002200;">&#125;</span>;</pre></td></tr></table></div>

<p>All these function pointer types are aptly named SomethingFunc and we&#8217;ll get to how these need to look like in a minute. The problem for us to solve how to bridge from our Objective-C paradigm (using self, properties, IVARs) into the C-function paradigm (no access to our parser object).</p>
<p>This problem is compounded by the fact that we are building this with ARC so that we don&#8217;t have to deal with memory management any more. Our resulting class will run on iOS 4 and above. Somehow we need to pass enough information to each event-function so that we can communicate with the parser object.</p>
<p>There are two reasonable possibilities: either we pass a reference to the parser instance or we pass a pointer to a struct that contains multiple values that we might need. I decided for the first because it seems cleaner to me.</p>
<p>libxml2 provides a concept of a user_data pointer that is passed to the event-functions together with other relevant information. We can use (abuse?) this for passing a reference to self. ARC requires this to be be cast to (__bridge void *) which in plain English means: <em>&#8220;please treat this as just some typeless memory pointer and also don&#8217;t worry about retaining or releasing. I&#8217;ll take care of that, don&#8217;t panic.&#8221;</em></p>
<p>Like any self-respecting class we&#8217;ll start out with a good block of IVAR definitions and and init method.</p>

<div class="wp_codebox"><table><tr id="p583435"><td class="code" id="p5834code35"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@implementation</span> DTHTMLParser
<span style="color: #002200;">&#123;</span>
    htmlSAXHandler _handler;
&nbsp;
    NSStringEncoding _encoding;
    <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/"><span style="color: #400080;">NSData</span></a> <span style="color: #002200;">*</span>_data;
&nbsp;
    __unsafe_unretained <span style="color: #a61390;">id</span> &lt;DTHTMLParserDelegate&gt; _delegate;
    htmlParserCtxtPtr _parserContext;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Notice that I&#8217;m defining the IVARs in the implementation, not the interface (in the header). This is possible as of using the new Apple LLVM compiler and provides for a nice way to hide the IVARs that we don&#8217;t want to be visible.</p>

<div class="wp_codebox"><table><tr id="p583436"><td class="code" id="p5834code36"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>initWithData<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/"><span style="color: #400080;">NSData</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>data encoding<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>NSStringEncoding<span style="color: #002200;">&#41;</span>encoding
<span style="color: #002200;">&#123;</span>
	self <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>super init<span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>self<span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
		_data <span style="color: #002200;">=</span> data;
		_encoding <span style="color: #002200;">=</span> encoding;
&nbsp;
		xmlSAX2InitHtmlDefaultSAXHandler<span style="color: #002200;">&#40;</span><span style="color: #002200;">&amp;</span>_handler<span style="color: #002200;">&#41;</span>;
	<span style="color: #002200;">&#125;</span>
&nbsp;
	<span style="color: #a61390;">return</span> self;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>We save the data and the encoding into our IVARs, _data being a strong reference to it. That means that it retains it during the lifetime of our parser and will only release it when the parser goes away.</p>
<p>We also initialize the _handler structure via the xmlSAX2InitHtmlDefaultSAXHandler function. This sets up some initial internals and also chooses the SAX2 method for our work. There&#8217;s also an older SAX1 method, but we obviously prefer the newer one. This setup has to happen inside the init method because right after such an instance of a DTHTMLParser is create we want to be able to set the delegate which should take care of wiring up the needed functions.</p>
<p>Each event-function should have a corresponding delegate method in our DTHTMLParserDelegate protocol, but to avoid unnecessary function-calling we only add the functions to the handler for which the delegate actually implements the function.</p>

<div class="wp_codebox"><table><tr id="p583437"><td class="code" id="p5834code37"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#pragma mark Properties</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>setDelegate<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>__unsafe_unretained id&lt;DTHTMLParserDelegate&gt;<span style="color: #002200;">&#41;</span>delegate;
<span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>delegate <span style="color: #002200;">!=</span> _delegate<span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
		_delegate <span style="color: #002200;">=</span> delegate;
&nbsp;
		<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>_delegate respondsToSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>parserDidStartDocument<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>
		<span style="color: #002200;">&#123;</span>
			_handler.startDocument <span style="color: #002200;">=</span> _startDocument;
		<span style="color: #002200;">&#125;</span>
		<span style="color: #a61390;">else</span>
		<span style="color: #002200;">&#123;</span>
			_handler.startDocument <span style="color: #002200;">=</span> <span style="color: #a61390;">NULL</span>;
		<span style="color: #002200;">&#125;</span>
&nbsp;
		<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>_delegate respondsToSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>parserDidEndDocument<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>
		<span style="color: #002200;">&#123;</span>
			_handler.endDocument <span style="color: #002200;">=</span> _endDocument;
		<span style="color: #002200;">&#125;</span>
		<span style="color: #a61390;">else</span>
		<span style="color: #002200;">&#123;</span>
			_handler.endDocument <span style="color: #002200;">=</span> <span style="color: #a61390;">NULL</span>;
		<span style="color: #002200;">&#125;</span>
<span style="color: #11740a; font-style: italic;">// ...</span></pre></td></tr></table></div>

<p>This way when you set the delegate it is inspected one by one whether it responds to certain methods of the protocol. And whenever it does the corresponding function pointer is set in the _handler IVAR.</p>
<p>At the top of the file we need to define these functions. If we do just that then the compiler will warn us for all of these implementations that there was &#8220;no previous prototype&#8221;. In C a you call the first line of a C-function it&#8217;s prototype. So we just have an extra block for these.</p>

<div class="wp_codebox"><table><tr id="p583438"><td class="code" id="p5834code38"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#pragma mark Event function prototypes</span>
&nbsp;
<span style="color: #a61390;">void</span> _startDocument<span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span> <span style="color: #002200;">*</span>context<span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">void</span> _endDocument<span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span> <span style="color: #002200;">*</span>context<span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">void</span> _startElement<span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span> <span style="color: #002200;">*</span>context, <span style="color: #a61390;">const</span> xmlChar <span style="color: #002200;">*</span>name,<span style="color: #a61390;">const</span> xmlChar <span style="color: #002200;">**</span>atts<span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">void</span> _endElement<span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span> <span style="color: #002200;">*</span>context, <span style="color: #a61390;">const</span> xmlChar <span style="color: #002200;">*</span>name<span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">void</span> _characters<span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span> <span style="color: #002200;">*</span>context, <span style="color: #a61390;">const</span> xmlChar <span style="color: #002200;">*</span>ch, <span style="color: #a61390;">int</span> len<span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">void</span> _comment<span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span> <span style="color: #002200;">*</span>context, <span style="color: #a61390;">const</span> xmlChar <span style="color: #002200;">*</span>value<span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">void</span> _error<span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span> <span style="color: #002200;">*</span>context, <span style="color: #a61390;">const</span> <span style="color: #a61390;">char</span> <span style="color: #002200;">*</span>msg, ...<span style="color: #002200;">&#41;</span>;</pre></td></tr></table></div>

<p>Wherever you see a context parameter this will be the user_data pointer we will provide. And for example the _startElement function gets a name and an array of attributes as well. The xmlChar type is just a char. This is actually always provided as UTF8-encoded string regardless of what the data is encoded as.</p>
<p>Let&#8217;s look first at an easy event-function and then at a more complex one.</p>

<div class="wp_codebox"><table><tr id="p583439"><td class="code" id="p5834code39"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">void</span> _startDocument<span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span> <span style="color: #002200;">*</span>context<span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#123;</span>
    DTHTMLParser <span style="color: #002200;">*</span>myself <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>__bridge DTHTMLParser <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>context;
&nbsp;
    <span style="color: #002200;">&#91;</span>myself.delegate parserDidStartDocument<span style="color: #002200;">:</span>myself<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>You see how I cast the void pointer back into a pointer of type DTHTMLParser. I have to name the variable different than &#8220;self&#8221; because that is a reserved word. Then I can simply call the delegate method that corresponds to this event function. </p>
<p>By the way, these are the delegate methods we want to implement:</p>

<div class="wp_codebox"><table><tr id="p583440"><td class="code" id="p5834code40"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">@class</span> DTHTMLParser;
&nbsp;
<span style="color: #a61390;">@protocol</span> DTHTMLParserDelegate &lt;NSObject&gt;
&nbsp;
@optional
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>parserDidStartDocument<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>DTHTMLParser <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>parser;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>parserDidEndDocument<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>DTHTMLParser <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>parser;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>parser<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>DTHTMLParser <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>parser didStartElement<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>elementName attributes<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/"><span style="color: #400080;">NSDictionary</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>attributeDict;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>parser<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>DTHTMLParser <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>parser didEndElement<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>elementName;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>parser<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>DTHTMLParser <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>parser foundCharacters<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #a61390;">string</span>;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>parser<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>DTHTMLParser <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>parser foundComment<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>comment;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>parser<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>DTHTMLParser <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>parser parseErrorOccurred<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSError_Class/"><span style="color: #400080;">NSError</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>parseError;
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p>The @class is necessary before the protocol definition because a good delegate protocol also passes a reference to the caller. This also enables the casual reader of your code to know at a glance that this method belongs to a protocol connected to this class.</p>
<p>Now for something more complex, let&#8217;s look at didStartElement. The complexity of this method results from the arts parameter being alternating key, value, key, value etc.</p>

<div class="wp_codebox"><table><tr id="p583441"><td class="code" id="p5834code41"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">void</span> _startElement<span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span> <span style="color: #002200;">*</span>context, <span style="color: #a61390;">const</span> xmlChar <span style="color: #002200;">*</span>name,<span style="color: #a61390;">const</span> xmlChar <span style="color: #002200;">**</span>atts<span style="color: #002200;">&#41;</span>
<span style="color: #002200;">&#123;</span>
	DTHTMLParser <span style="color: #002200;">*</span>myself <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>__bridge DTHTMLParser <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>context;
&nbsp;
	<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>nameStr <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> stringWithUTF8String<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">char</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>name<span style="color: #002200;">&#93;</span>;
&nbsp;
	<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSMutableDictionary_Class/"><span style="color: #400080;">NSMutableDictionary</span></a> <span style="color: #002200;">*</span>attributes <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
&nbsp;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>atts<span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
		<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>key <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
		<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>value <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
&nbsp;
		attributes <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSMutableDictionary_Class/"><span style="color: #400080;">NSMutableDictionary</span></a> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
&nbsp;
		<span style="color: #a61390;">int</span> i<span style="color: #002200;">=</span><span style="color: #2400d9;">0</span>;
		<span style="color: #a61390;">while</span> <span style="color: #002200;">&#40;</span><span style="color: #2400d9;">1</span><span style="color: #002200;">&#41;</span>
		<span style="color: #002200;">&#123;</span>
			<span style="color: #a61390;">char</span> <span style="color: #002200;">*</span>att <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">char</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>atts<span style="color: #002200;">&#91;</span>i<span style="color: #002200;">++</span><span style="color: #002200;">&#93;</span>;
&nbsp;
			<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>key<span style="color: #002200;">&#41;</span>
			<span style="color: #002200;">&#123;</span>
				<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>att<span style="color: #002200;">&#41;</span>
				<span style="color: #002200;">&#123;</span>
					<span style="color: #11740a; font-style: italic;">// we're done</span>
					<span style="color: #a61390;">break</span>;
				<span style="color: #002200;">&#125;</span>
&nbsp;
				key <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> stringWithUTF8String<span style="color: #002200;">:</span>att<span style="color: #002200;">&#93;</span>;
			<span style="color: #002200;">&#125;</span>
			<span style="color: #a61390;">else</span>
			<span style="color: #002200;">&#123;</span>
				<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>att<span style="color: #002200;">&#41;</span>
				<span style="color: #002200;">&#123;</span>
					value <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> stringWithUTF8String<span style="color: #002200;">:</span>att<span style="color: #002200;">&#93;</span>;
				<span style="color: #002200;">&#125;</span>
				<span style="color: #a61390;">else</span>
				<span style="color: #002200;">&#123;</span>
					<span style="color: #11740a; font-style: italic;">// solo attribute</span>
					value <span style="color: #002200;">=</span> key;
				<span style="color: #002200;">&#125;</span>
&nbsp;
				<span style="color: #002200;">&#91;</span>attributes setObject<span style="color: #002200;">:</span>value forKey<span style="color: #002200;">:</span>key<span style="color: #002200;">&#93;</span>;
&nbsp;
				value <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
				key <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
			<span style="color: #002200;">&#125;</span>
		<span style="color: #002200;">&#125;</span>
	<span style="color: #002200;">&#125;</span>
&nbsp;
	<span style="color: #002200;">&#91;</span>myself.delegate parser<span style="color: #002200;">:</span>myself didStartElement<span style="color: #002200;">:</span>nameStr attributes<span style="color: #002200;">:</span>attributes<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>The while loop walks through the attributes and and when a NULL is encountered where a key would be then it breaks out of the loop. It is also necessary to deal with a situation where there is only an attribute name, but no value because HTML also allows that. Theoretically one attribute could also be occurring multiple times, but we ignore this. For later convenience we want the key/values for the attributes in an NSDictionary.</p>
<p>The final piece is how the parsing actually is started. For this we have a parse method, just like NSXMLParser.</p>

<div class="wp_codebox"><table><tr id="p583442"><td class="code" id="p5834code42"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>parse
<span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">void</span> <span style="color: #002200;">*</span>dataBytes <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">char</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span>_data bytes<span style="color: #002200;">&#93;</span>;
	<span style="color: #a61390;">int</span> dataSize <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>_data length<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">// detect encoding if necessary</span>
	xmlCharEncoding charEnc <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>;
&nbsp;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>_encoding<span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
		charEnc <span style="color: #002200;">=</span> xmlDetectCharEncoding<span style="color: #002200;">&#40;</span>dataBytes, dataSize<span style="color: #002200;">&#41;</span>;
	<span style="color: #002200;">&#125;</span>
	<span style="color: #a61390;">else</span>
	<span style="color: #002200;">&#123;</span>
		<span style="color: #11740a; font-style: italic;">// convert the encoding</span>
		<span style="color: #11740a; font-style: italic;">// TODO: proper mapping from _encoding to xmlCharEncoding</span>
		CFStringEncoding cfenc <span style="color: #002200;">=</span> CFStringConvertNSStringEncodingToEncoding<span style="color: #002200;">&#40;</span>_encoding<span style="color: #002200;">&#41;</span>;
		CFStringRef cfencstr <span style="color: #002200;">=</span> CFStringConvertEncodingToIANACharSetName<span style="color: #002200;">&#40;</span>cfenc<span style="color: #002200;">&#41;</span>;
		<span style="color: #a61390;">const</span> <span style="color: #a61390;">char</span> <span style="color: #002200;">*</span>enc <span style="color: #002200;">=</span> CFStringGetCStringPtr<span style="color: #002200;">&#40;</span>cfencstr, <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>;
&nbsp;
		charEnc <span style="color: #002200;">=</span> xmlParseCharEncoding<span style="color: #002200;">&#40;</span>enc<span style="color: #002200;">&#41;</span>;
	<span style="color: #002200;">&#125;</span>
&nbsp;
	<span style="color: #11740a; font-style: italic;">// create a parse context</span>
	_parserContext <span style="color: #002200;">=</span> htmlCreatePushParserCtxt<span style="color: #002200;">&#40;</span><span style="color: #002200;">&amp;</span>_handler, <span style="color: #002200;">&#40;</span>__bridge <span style="color: #a61390;">void</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>self, 
		dataBytes, dataSize, <span style="color: #a61390;">NULL</span>, charEnc<span style="color: #002200;">&#41;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">// set some options</span>
	htmlCtxtUseOptions<span style="color: #002200;">&#40;</span>_parserContext, HTML_PARSE_RECOVER | HTML_PARSE_NONET |
		HTML_PARSE_COMPACT<span style="color: #002200;">&#41;</span>;
&nbsp;
	<span style="color: #11740a; font-style: italic;">// parse!</span>
	<span style="color: #a61390;">int</span> result <span style="color: #002200;">=</span> htmlParseDocument<span style="color: #002200;">&#40;</span>_parserContext<span style="color: #002200;">&#41;</span>;
&nbsp;
	<span style="color: #a61390;">return</span> <span style="color: #002200;">&#40;</span>result<span style="color: #002200;">==</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>There is a xmlDetectCharEncoding function in libxml to try and detect the encoding of the data which we invoke if the passed encoding is 0. The way to convert the NSStringEncoding into the xmlCharEncoding is only work shift, that needs some improving, possibly by simply having a big switch statement. Maybe later.</p>
<p>There are multiple ways how you can parse a document, some of which take individual parameters, some take a html parsing context. I settled on using the one for the push interface because there the htmlParseDocument function does not return a pointer to an html document tree (DOM), but instead a result that is 0 for success or -1 for error.</p>
<p>It is my understanding that this variant does not actually build the entire tree but keeps just enough state information to track the current hierarchy level inside the HTML tree. The push parser variant also has the ability to parse chunks of HTML data as they become available, e.g. while downloading. But exploring that is outside our scope for now.</p>
<h3>Conclusion</h3>
<p>Once your eyes have gotten used to the coding style of libxml2 you can start to appreciate the plethora of functions that it provides. You can also peruse the <a href="http://xmlsoft.org/html/index.html">official reference manual online</a>.</p>
<p>Finally I invite your collaboration on using and helping to polish DTHTMLParser if you have any need for parsing HTML text from within your iOS apps. Look for it on the GitHub DTFoundation project as soon as I can add a bit of AppleDoc-style documentation to it.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5834&amp;md5=71505f45c772506d51675dd3c0636f33" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/01/taming-html-parsing-with-libxml-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5834&amp;md5=71505f45c772506d51675dd3c0636f33" type="text/html" />"
	</item>
		<item>
		<title>Helping Xcode Find Library Headers</title>
		<link>http://www.cocoanetics.com/2012/01/helping-xcode-find-library-headers/</link>
		<comments>http://www.cocoanetics.com/2012/01/helping-xcode-find-library-headers/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 15:26:46 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Recipes]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5825</guid>
		<description><![CDATA[In my previous article about Sub-Projects in Xcode I showed you how you can have an Xcode project as a dependency. The advantage of this is that you can update your library from within the same project and debug into the sub-project&#8217;s code. One thing that was not immediately obvious was how you deal with the problem that Xcode cannot find your sub-project&#8217;s library headers. Hence this writeup. Label Buy an ad here A header file generally informs the compiler what c-functions, global variables, Object-C methods and classes exist in an object file. All these are generally called &#8220;symbols&#8221;. Build Process Review The build process consists of these three steps: Preprocessor &#8211; this takes care of including/importing header files into your source code, essentially pasting the content of the specified file right into your source code for building. This step also replaces all instances of #defined values with what you defined them to be. Compiler &#8211; this goes through all the .m files and builds an object file with .o extension for each. Each item that is not coming from the same .m file is marked as an external symbol. Linker &#8211; this merges all the object files into one big binary while at the same time linking the symbols with the actual implementations. Header files do not actually contain executable code, but instead they tell the compiler which names and functions it should accept. It is the linker then that resolves these references. In short: If you want to use something which is implemented outside the current .m file than you need the appropriate import for that. There are two kinds of imports: &#60;path/header.h&#62; with angle brackets &#8211; these are meant for system or &#8220;global&#8221; includes. &#8220;path/header.h&#8221; with double quotes &#8211; these are meant for items that are limited in scope to your current project You have probably used both already, the one with the angle brackets for including headers that Apple provided. The one with the double quotes for accessing your own classes. Paths are usually relative paths because everybody has a different folder structure on his hard disk. Get the Headers into Your App The easiest way to get the headers into your project is to just add them. But you should generally refrain from duplicating your code for convenience, because then you have to perform an update on every copy of the file. A variation of this theme would be to not add the file itself, but just a reference. But this approach would also make your project dependent on your folder structure. Don&#8217;t do it, just don&#8217;t. If you have followed the Sub-Projects guide you are already perfectly set up to get to the header while still keeping the project self-contained and independent from the file system layout. You only need to tell the outer Xcode project &#8211; probably your app that includes sub-projects for some static libraries &#8211; where it can find the necessary headers from the sub-project. Again you have multiple options: you can point it to the source code folder where the .h files are located. Or you can point it to the build output folder. Both are equally viable but if you work with static universal frameworks &#8211; as I do &#8211; then you can only use option two without losing your mind. On my projects that contain reusable code I usually have multiple targets. One for a universal static framework &#8211; which is very convenient to add to a project because it automatically sets up the library and header paths for you when you drag it into your project. I have a second target for a static library because this allows for using the project as a sub-project and have the outer project link to the static library product. Because the framework conveniently bundles together multiple .h files you usually have the general name of the framework as path, i.e. you find &#60;MobFox/MobFox.h&#62; as the import of choice. For for example an Apple framework &#60;Foundation/Foundation.h&#62;. Contrasting the MobFox/ path the actual location of the header file is PROJECT_ROOT/Core, so no MobFox path component there. This is the reason why we cannot point the containing app to the source folder because there is no header file MobFox.h inside a folder named MobFox. So via approach number 1 we would never find the header, we want to take door number two which is to point Xcode to the static library build output folder. But for this to work some setup is necessary. Specifying Public Header Output Location After building the static library Xcode will also copy certain headers to the output folder. A header can be public, project or private. Public means that it will be distributed together with the library. Project and Private won&#8217;t. You can set this for every header file individually. [...]]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/01/helping-xcode-find-library-headers/"></g:plusone></div><p>In my previous article about <a title="Sub-Projects in Xcode" href="http://www.cocoanetics.com/2011/12/sub-projects-in-xcode/">Sub-Projects in Xcode</a> I showed you how you can have an Xcode project as a dependency. The advantage of this is that you can update your library from within the same project and debug into the sub-project&#8217;s code.</p>
<p>One thing that was not immediately obvious was how you deal with the problem that Xcode cannot find your sub-project&#8217;s library headers. Hence this writeup.</p>
<p><span id="more-5825"></span></p>
<div class="inner_ad_block">
<div id="advman-7" class="widget Advman_Widget">
<h3 class="widgettitle"></h3>
<p><!-- BuySellAds.com Zone Code --></p>
<div id="bsap_1260346" class="bsarocks bsap_fc3166ea4a479e0fdb4251fbe92a1219"></div>
<p><!-- End BuySellAds.com Zone Code --></div>
<div id="text-21" class="widget widget_text">
<h3 class="widgettitle">Label</h3>
<div class="textwidget">
<div class="advert-notice"><a href="http://buysellads.com/buy/detail/56639/zone/1260346">Buy an ad here</a></div>
</div></div>
</div>
<p>A header file generally informs the compiler what c-functions, global variables, Object-C methods and classes exist in an object file. All these are generally called &#8220;symbols&#8221;.</p>
<h3>Build Process Review</h3>
<p>The build process consists of these three steps:</p>
<ol>
<li><strong>Preprocessor</strong> &#8211; this takes care of including/importing header files into your source code, essentially pasting the content of the specified file right into your source code for building. This step also replaces all instances of #defined values with what you defined them to be.</li>
<li><strong>Compiler</strong> &#8211; this goes through all the .m files and builds an object file with .o extension for each. Each item that is not coming from the same .m file is marked as an external symbol.</li>
<li><strong>Linker</strong> &#8211; this merges all the object files into one big binary while at the same time linking the symbols with the actual implementations.</li>
</ol>
<p>Header files do not actually contain executable code, but instead they tell the compiler which names and functions it should accept. It is the linker then that resolves these references. In short: If you want to use something which is implemented outside the current .m file than you need the appropriate import for that.</p>
<p>There are two kinds of imports:</p>
<ul>
<li>&lt;path/header.h&gt; with angle brackets &#8211; these are meant for system or &#8220;global&#8221; includes.</li>
<li>&#8220;path/header.h&#8221; with double quotes &#8211; these are meant for items that are limited in scope to your current project</li>
</ul>
<p>You have probably used both already, the one with the angle brackets for including headers that Apple provided. The one with the double quotes for accessing your own classes. Paths are usually relative paths because everybody has a different folder structure on his hard disk.</p>
<h3>Get the Headers into Your App</h3>
<p>The easiest way to get the headers into your project is to just add them. But you should generally refrain from duplicating your code for convenience, because then you have to perform an update on every copy of the file. A variation of this theme would be to not add the file itself, but just a reference. But this approach would also make your project dependent on your folder structure. Don&#8217;t do it, just don&#8217;t.</p>
<p>If you have followed the Sub-Projects guide you are already perfectly set up to get to the header while still keeping the project self-contained and independent from the file system layout. You only need to tell the outer Xcode project &#8211; probably your app that includes sub-projects for some static libraries &#8211; where it can find the necessary headers from the sub-project. Again you have multiple options: you can point it to the source code folder where the .h files are located. Or you can point it to the build output folder. Both are equally viable but if you work with static universal frameworks &#8211; as I do &#8211; then you can only use option two without losing your mind.</p>
<p>On my projects that contain reusable code I usually have multiple targets. One for a universal static framework &#8211; which is very convenient to add to a project because it automatically sets up the library and header paths for you when you drag it into your project. I have a second target for a static library because this allows for using the project as a sub-project and have the outer project link to the static library product. Because the framework conveniently bundles together multiple .h files you usually have the general name of the framework as path, i.e. you find &lt;MobFox/MobFox.h&gt; as the import of choice. For for example an Apple framework &lt;Foundation/Foundation.h&gt;.</p>
<p>Contrasting the MobFox/ path the actual location of the header file is PROJECT_ROOT/Core, so no MobFox path component there. This is the reason why we cannot point the containing app to the source folder because there is no header file MobFox.h inside a folder named MobFox. So via approach number 1 we would never find the header, we want to take door number two which is to point Xcode to the static library build output folder. But for this to work some setup is necessary.</p>
<h3>Specifying Public Header Output Location</h3>
<p>After building the static library Xcode will also copy certain headers to the output folder. A header can be public, project or private. Public means that it will be distributed together with the library. Project and Private won&#8217;t. You can set this for every header file individually. Headers for objects that you want to be able to see from your app should be Public.</p>
<p><a href="http://www.cocoanetics.com/files/Screen-Shot-2012-01-19-at-3.48.06-PM.png"><img class="alignnone  wp-image-5826" title="Public, Project, Private" src="http://www.cocoanetics.com/files/Screen-Shot-2012-01-19-at-3.48.06-PM.png" alt="" width="640" height="92" /></a></p>
<p>If you now build the static library and look at the build log you will see that at the very end the public headers are copied somewhere:</p>
<p><a href="http://www.cocoanetics.com/files/Screen-Shot-2012-01-19-at-3.52.39-PM.png"><img class="alignnone  wp-image-5827" title="Library output after build" src="http://www.cocoanetics.com/files/Screen-Shot-2012-01-19-at-3.52.39-PM.png" alt="" width="713" height="182" /></a></p>
<p>We are astonished to find a path ending in Build/Products/Debug-iphoneos/usr/local/include for the two public header files. The reason for this being the default setting is that traditionally people would build binary files for the system they are working on. But that&#8217;s not what we want. So we go into the build settings for the static library target and adjust this. Don&#8217;t put this entry into either the Debug or Release lines, but into the line above these so that it may override both.</p>
<p><a href="http://www.cocoanetics.com/files/Screen-Shot-2012-01-19-at-4.00.42-PM.png"><img class="alignnone  wp-image-5828" title="changing the public header output path" src="http://www.cocoanetics.com/files/Screen-Shot-2012-01-19-at-4.00.42-PM.png" alt="" width="608" height="467" /></a></p>
<p>When we now build we see the output go to Build/Products/Debug-iphoneos/MobFox &#8211; as we want it. It is this extra MobFox path component that enables us to use the &lt;MobFox/MobFox.h&gt; style of including later on.</p>
<p>Now back to our app that is including this sub-project&#8217;s static library. There we now need to tell the compiler where it can find the above folder. It so happens that when building Xcode usually uses the same output folder for all products it needs to build, namely whatever is in the $(CONFIGURATION_BUILD_DIR) variable at the time. This in turn is set by default to $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME).</p>
<p>The final piece of the puzzle to know is where to put that. This depends on the include style that I explained above. Double quoted includes need the path in &#8220;User Header Search Paths&#8221;. Angle-bracketed includes need the regular &#8220;Header Search Paths&#8221;. We are forced to use the latter due to the framework. We don&#8217;t need to check the Recursive box because at the given location there is a MobFox folder.</p>
<p><a href="http://www.cocoanetics.com/files/Screen-Shot-2012-01-19-at-4.12.28-PM.png"><img class="alignnone size-full wp-image-5829" title="Screen Shot 2012-01-19 at 4.12.28 PM" src="http://www.cocoanetics.com/files/Screen-Shot-2012-01-19-at-4.12.28-PM.png" alt="" width="887" height="513" /></a></p>
<p>The &lt;Multiple values&gt; might cause you to pause for a second, but remember what I told you above. The configuration (Debug/Release) is part of this path and so even though you put the same variable in there, the actual result is a different one. Note that these values are bold because the target settings override the settings specified by the project. You can revert to the project settings by selecting the line and hitting CMD+Backspace.</p>
<p>There is an alternate option to put this path in the &#8220;User Header Search Paths&#8221; instead, but then you need to set &#8220;Always Search User Paths&#8221; to Yes. This will cause the compiler to also search the user header paths for angle bracket includes. Though personally I prefer the other option that needs less settings.</p>
<p>The other steps for building are explained in the Sub-Projects posts. If you carry them out (link with target), you will find that now your app finds the headers and successfully builds.</p>
<h3>Conclusion</h3>
<p>If Xcode complains that it cannot find a header then you should make sure that it is indeed in a place where it can find it. There is an abundance of default settings that may seem daunting, but if you know what to look for you can quickly find why your header cannot be found.</p>
<p>I wrote this article because I myself was stumped by not being able to explain why a project couldn&#8217;t find the MobFox header. So another learning of this episode is that you should not assume that the owner of your sub-project has set everything up correctly. In my case I too was missing the custom header output path setting. Errare humanum est.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5825&amp;md5=2d7dee18cea6ddcc2a930d578c490b8e" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/01/helping-xcode-find-library-headers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5825&amp;md5=2d7dee18cea6ddcc2a930d578c490b8e" type="text/html" />"
	</item>
		<item>
		<title>Linguan 1.0.3</title>
		<link>http://www.cocoanetics.com/2012/01/linguan-1-0-3/</link>
		<comments>http://www.cocoanetics.com/2012/01/linguan-1-0-3/#comments</comments>
		<pubDate>Mon, 16 Jan 2012 18:32:27 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Updates]]></category>
		<category><![CDATA[Linguan]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5823</guid>
		<description><![CDATA[Besides fixing several bugs reported by users this release focusses on implementing a new custom-built super-charged strings scanner. Changes FIXED: missing strings file no longer aborts import FIXED: added &#8211; Button for deleting tokens FIXED: deletion of wrong row FIXED: over-escaping of \ on writing strings files FIXED: wrong token name updated on enter key FIXED: search filter not reset on adding a new token FIXED: Previous/Next buttons in wizard cease to function NEW: replaced genstrings with high-speed custom implementation (&#62;20x speed improvement) NEW: support custom localization macro prefix This new version does no longer support 32-bit because the new strings scanner was implemented using ARC. We hope that this does not inconvenience any of our existing uses. But then again, serious developers are on a 64 bit machine anyway since Snow Leopard&#8230; The new version has been submitted to Apple today.]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/01/linguan-1-0-3/"></g:plusone></div><p>Besides fixing several bugs reported by users this release focusses on implementing a new <a title="genstrings2" href="http://www.cocoanetics.com/2012/01/genstrings2/">custom-built super-charged strings scanner</a>.</p>
<p><strong>Changes</strong></p>
<ul>
<li>FIXED: missing strings file no longer aborts import</li>
<li>FIXED: added &#8211; Button for deleting tokens</li>
<li>FIXED: deletion of wrong row</li>
<li>FIXED: over-escaping of \ on writing strings files</li>
<li>FIXED: wrong token name updated on enter key</li>
<li>FIXED: search filter not reset on adding a new token</li>
<li>FIXED: Previous/Next buttons in wizard cease to function</li>
<li>NEW: replaced genstrings with high-speed custom implementation (&gt;20x speed improvement)</li>
<li>NEW: support custom localization macro prefix</li>
</ul>
<p>This new version does no longer support 32-bit because the new strings scanner was implemented using ARC. We hope that this does not inconvenience any of our existing uses. But then again, serious developers are on a 64 bit machine anyway since Snow Leopard&#8230;</p>
<p>The new version has been submitted to Apple today.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5823&amp;md5=97da7c954c1ebe8f2634920018c31cdc" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/01/linguan-1-0-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5823&amp;md5=97da7c954c1ebe8f2634920018c31cdc" type="text/html" />"
	</item>
		<item>
		<title>C-Code outperforms NSScanner</title>
		<link>http://www.cocoanetics.com/2012/01/c-code-outperforms-nsscanner/</link>
		<comments>http://www.cocoanetics.com/2012/01/c-code-outperforms-nsscanner/#comments</comments>
		<pubDate>Sun, 15 Jan 2012 11:02:26 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5813</guid>
		<description><![CDATA[Over the past week I&#8217;ve been working on DTLocalizableStringScanner or in short genstrings2. The original genstrings dates back to the NeXtStep days. You know how it is &#8220;never change a winning team&#8221; BUT &#8220;the good is the enemy of the great&#8221;, because if something kind of works, why change it? Besides of the other problems I&#8217;ve alluded to in my previous article genstrings is very slow. Internally it is written in Objective-C as you can tell from the occasional stack trace when it crashes again. But it was created in a time when Macs did only have single CPU cores and when we did not have the awesome LLVM with ARC, GCD and multi-threading. Label Buy an ad here At the time of this writing we implemented genstrings2 twice: once based extensively on NSScanner which I became intimately acquainted with when working on DTCoreText. The other is a rewrite of the rewrite totally ditching NSScanner and doing all scanning directly on the individual characters. My feeling is that the lower-level scanning will be orders of magnitude faster and at the same time it is way more robust because for non-literal macro parameters it knows how to deal with pairs of parenthesis and commas contained in strings. But this just begs to be benchmarked. In order to have a sufficient amount of code to scan through I downloaded the latest source bundle for Adium. Getting a time for the individual versions is easy with the time command: time genstrings -q -s AILocalizedString ~/Desktop/adium-1.4.4/Source/*.m &#160; real 0m7.872s user 0m6.848s sys 0m0.053s When benchmarking you also need to mention the type of bench you are marking. These numbers come from my 2010 MacBook Air which is somewhat skewed because the disk IO times are possibly faster than usual. But we are mostly interested in the parsing efficiency. Here the benchmark machine has 2 CPU cores (1.6 GHz Intel Core 2 Duo). You can see in activity monitor that original genstrings is single-threaded. It uses up to 100% of a single core and shows to have only 1 thread. The version of genstrings2 using NSScanner clocked in much better. 1.7 seconds down from 7.9 seconds, 5 times as fast. real 0m1.663s user 0m2.950s sys 0m0.070s Now for the turbo version that does all the scanning without NSScanner. Instead it is working with the individual unichar characters that make up the strings. On iOS these are 16 bit because internally all NSStrings are using UTF16. real 0m2.167s user 0m3.973s sys 0m0.074s Whoa! Hold your horses, why is that slower than my version? My first thought was that maybe NSScanner really is very efficient. But once I fired up Instruments I found this, lots of CFRelease calls were bogging down the turbo scanner. Looking at the sample distribution in _scanMacro revealed the culprit. From this it was quite obvious that the creation of the mutable array to hold the scanned macro parameters was taking most of the CPU time in this area of the code. Turns out this was allocating and releasing this parameter array way more than necessary. We only need to created that once we are sure that this is actually one of the macros we are looking for, not some random word that happens to be made up of macro name characters. So moving the array creation a few lines down and changing it to an alloc/initWithCapacity (we know that we probably will have less than 10 parameters) yielded this result in the benchmark: real 0m1.385s user 0m2.045s sys 0m0.081s Looking at Instruments again we see even more potential for optimization. If a line takes a quarter of the CPU time spent in a method then you have to ask yourself if there is a way to get rid of this work. Now this validMacroCharacters is already supposed to be a lazy initialization, so how to optimize this? While it is lazy there is still quite some overhead to do the method call. On the first time around the character set is initialized and on subsequent calls the method returns the initialized IVAR. We can easily get around this by moving the initialization of the IVAR to the class init and reference it directly. Normally this method call plus if plus returning the IVAR would not be a problem, but _scanMacro is called thousands of times and so &#8211; as proven by Instruments &#8211; this is an easy optimization. The benchmark improvement is very impressive: real 0m1.065s user 0m1.839s sys 0m0.059s At this stage the turbo scanner (with two changes) is already almost twice as fast as the NSScanner-version and 7 times as fast as original genstrings. BUT three is a charm and it so happens that I had a stroke of genius. My train of thought went: if I can defer CPU-intensive work to the [...]]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/01/c-code-outperforms-nsscanner/"></g:plusone></div><p>Over the past week I&#8217;ve been working on <a href="https://github.com/Cocoanetics/DTLocalizableStringScanner">DTLocalizableStringScanner</a> or in short <strong>genstrings2</strong>. The original genstrings dates back to the NeXtStep days. You know how it is<em> &#8220;never change a winning team&#8221;</em> BUT &#8220;the good is the enemy of the great&#8221;, because if something kind of works, why change it?</p>
<p>Besides of the other problems I&#8217;ve <a title="genstrings2" href="http://www.cocoanetics.com/2012/01/genstrings2/">alluded to</a> in my previous article genstrings is very slow. Internally it is written in Objective-C as you can tell from the occasional stack trace when it crashes again. But it was created in a time when Macs did only have single CPU cores and when we did not have the awesome LLVM with ARC, GCD and multi-threading.</p>
<p><span id="more-5813"></span></p>
<div class="inner_ad_block">
<div id="advman-7" class="widget Advman_Widget">
<h3 class="widgettitle"></h3>
<p><!-- BuySellAds.com Zone Code --></p>
<div id="bsap_1260346" class="bsarocks bsap_fc3166ea4a479e0fdb4251fbe92a1219"></div>
<p><!-- End BuySellAds.com Zone Code --></div>
<div id="text-21" class="widget widget_text">
<h3 class="widgettitle">Label</h3>
<div class="textwidget">
<div class="advert-notice"><a href="http://buysellads.com/buy/detail/56639/zone/1260346">Buy an ad here</a></div>
</div></div>
</div>
<p>At the time of this writing we implemented genstrings2 twice: once based extensively on NSScanner which I became intimately acquainted with when working on <a href="https://github.com/Cocoanetics/DTCoreText">DTCoreText</a>. The other is a rewrite of the rewrite totally ditching NSScanner and doing all scanning directly on the individual characters.</p>
<p>My feeling is that the lower-level scanning will be orders of magnitude faster and at the same time it is way more robust because for non-literal macro parameters it knows how to deal with pairs of parenthesis and commas contained in strings. But this just <em>begs to be benchmarked</em>.</p>
<p>In order to have a sufficient amount of code to scan through I downloaded the <a href="http://trac.adium.im/wiki/PreviousReleases">latest source bundle for Adium</a>. Getting a time for the individual versions is easy with the time command:</p>

<div class="wp_codebox"><table><tr id="p581349"><td class="code" id="p5813code49"><pre class="sh" style="font-family:monospace;">time genstrings -q -s AILocalizedString ~/Desktop/adium-1.4.4/Source/*.m
&nbsp;
real     0m7.872s
user     0m6.848s
sys      0m0.053s</pre></td></tr></table></div>

<p>When benchmarking you also need to mention the type of bench you are marking. These numbers come from my 2010 MacBook Air which is somewhat skewed because the disk IO times are possibly faster than usual. But we are mostly interested in the parsing efficiency. Here the benchmark machine has 2 CPU cores (1.6 GHz Intel Core 2 Duo).</p>
<p>You can see in activity monitor that original genstrings is single-threaded. It uses up to 100% of a single core and shows to have only 1 thread.</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-15-um-10.50.59.png"><img class="alignnone size-full wp-image-5814" title="genstrings single threaded" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-15-um-10.50.59.png" alt="" width="639" height="140" /></a></p>
<p>The version of genstrings2 using NSScanner clocked in much better. 1.7 seconds down from 7.9 seconds, 5 times as fast.</p>

<div class="wp_codebox"><table><tr id="p581350"><td class="code" id="p5813code50"><pre class="sh" style="font-family:monospace;">real     0m1.663s
user     0m2.950s
sys      0m0.070s</pre></td></tr></table></div>

<p>Now for the turbo version that does all the scanning without NSScanner. Instead it is working with the individual unichar characters that make up the strings. On iOS these are 16 bit because internally all NSStrings are using UTF16.</p>

<div class="wp_codebox"><table><tr id="p581351"><td class="code" id="p5813code51"><pre class="sh" style="font-family:monospace;">real     0m2.167s
user     0m3.973s
sys      0m0.074s</pre></td></tr></table></div>

<p>Whoa! Hold your horses, why is that <em>slower</em> than my version? My first thought was that maybe NSScanner really is very efficient. But once I fired up Instruments I found this, lots of CFRelease calls were bogging down the turbo scanner.</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-15-um-11.06.11.png"><img class="alignnone size-full wp-image-5815" title="Too many CFRelease" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-15-um-11.06.11.png" alt="" width="571" height="253" /></a></p>
<p>Looking at the sample distribution in _scanMacro revealed the culprit.</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-15-um-11.09.30.png"><img class="alignnone size-full wp-image-5816" title="Misplaced autoreleased array creation" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-15-um-11.09.30.png" alt="" width="686" height="311" /></a></p>
<p>From this it was quite obvious that the creation of the mutable array to hold the scanned macro parameters was taking most of the CPU time in this area of the code. Turns out this was allocating and releasing this parameter array way more than necessary. We only need to created that once we are sure that this is actually one of the macros we are looking for, not some random word that happens to be made up of macro name characters.</p>
<p>So moving the array creation a few lines down and changing it to an alloc/initWithCapacity (we know that we probably will have less than 10 parameters) yielded this result in the benchmark:</p>

<div class="wp_codebox"><table><tr id="p581352"><td class="code" id="p5813code52"><pre class="sh" style="font-family:monospace;">real     0m1.385s
user     0m2.045s
sys      0m0.081s</pre></td></tr></table></div>

<p>Looking at Instruments again we see even more potential for optimization. If a line takes a quarter of the CPU time spent in a method then you have to ask yourself if there is a way to get rid of this work. Now this validMacroCharacters is already supposed to be a lazy initialization, so how to optimize this?</p>
<p>While it is lazy there is still quite some overhead to do the method call. On the first time around the character set is initialized and on subsequent calls the method returns the initialized IVAR. We can easily get around this by moving the initialization of the IVAR to the class init and reference it directly.</p>
<p>Normally this method call plus if plus returning the IVAR would not be a problem, but _scanMacro is called thousands of times and so &#8211; as proven by Instruments &#8211; this is an easy optimization. The benchmark improvement is very impressive:</p>

<div class="wp_codebox"><table><tr id="p581353"><td class="code" id="p5813code53"><pre class="sh" style="font-family:monospace;">real	0m1.065s
user	0m1.839s
sys	0m0.059s</pre></td></tr></table></div>

<p>At this stage the turbo scanner (with two changes) is already almost twice as fast as the NSScanner-version and 7 times as fast as original genstrings. BUT three is a charm and it so happens that I had a stroke of genius.</p>
<p>My train of thought went: if I can defer CPU-intensive work to the latest moment possible and if I can reduce the amount of times when it is necessary, what other method could I come up with to skip out of _scanMacro early? After the previous optimizations most CPU time was distributed between creating an NSString object and the containsObject of the macro dictionary. Two items that cannot be easily optimized further.</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-15-um-11.40.59.png"><img class="alignnone size-full wp-image-5817" title="No more optimization" src="http://www.cocoanetics.com/files/Bildschirmfoto-2012-01-15-um-11.40.59.png" alt="" width="712" height="128" /></a></p>
<p>Upon closer inspection I found that far too many times words were found that were made up of characters in the macro words. This resulted in these two statements being called way more often than necessary, even for words that are not plausible macro names because they are too short. On the NSScanner version I had had the optimization to ignore short commands like &#8220;if&#8221; and &#8220;do&#8221; because these would look like macro characters but are in reality reserved words. But this did not yield and advantage.</p>
<p>The stroke of genius was to find the lengths of the shortest and longest macro names (also in the init) and then have a simple if comparison to return from _scanMacro if we character sequence is far too short for one of our macro names. The results blew me away.</p>

<div class="wp_codebox"><table><tr id="p581354"><td class="code" id="p5813code54"><pre class="sh" style="font-family:monospace;">real	0m0.442s
user	0m0.691s
sys	0m0.044s</pre></td></tr></table></div>

<p>Now we have truly reached the point of impossible further optimization. Looking in Instruments the CPU times are now much wider spread, only characterIsMember cumulates more CPU times then the other lines, but this method cannot be optimized further since that would mean writing a replacement for NSCharacterSet.</p>
<h3>Conclusion</h3>
<p>Let&#8217;s summarize the lessons learned:</p>
<ul>
<li>Good C-code easily outperforms NSScanner</li>
<li>Defer creating objects to the latest possible moment</li>
<li>Avoid lazy instantiations if they are called in tight loops that cause them to be called too often</li>
<li>Try to find simple mathematical or logical abort conditions (quickly processed) to avoid CPU-intense work where possible</li>
</ul>
<p>Granted I could spend more effort on working out the performance problems the NSScanner version has, but I doubt that I could get anywhere near the double turbo version. The final results thus are:</p>
<ul>
<li>genstrings: 7.9 sec</li>
<li>genstrings (NSScanner): 1.7 sec</li>
<li>genstrings (optimized turbo): 0.4 sec</li>
</ul>
<p>The optimized turbo version is 20 times as fast as the original, let&#8217;s be content with that. <img src='http://www.cocoanetics.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' /> </p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5813&amp;md5=5477fc29d4ad144f4315adc84be9fc36" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/01/c-code-outperforms-nsscanner/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5813&amp;md5=5477fc29d4ad144f4315adc84be9fc36" type="text/html" />"
	</item>
		<item>
		<title>LEGO: Life of George</title>
		<link>http://www.cocoanetics.com/2012/01/lego-life-of-george/</link>
		<comments>http://www.cocoanetics.com/2012/01/lego-life-of-george/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 15:30:32 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Fun]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5800</guid>
		<description><![CDATA[LEGO&#8217;s Life of George game brings together 5 worlds like nothing else before: 8-Bit Design iPhone LEGO bricks manual interaction, a &#8220;touch interface&#8221; if you will computer vision for gamification Let&#8217;s have a quick look at this fun pastime that is all the rage. Label Buy an ad here The LEGO Life of George app is a free download on the app store. To play you need the box which contains some additional ingredients you need to play. You get 6&#215;1, 8&#215;2, 4&#215;3, 4&#215;4 and 2&#215;6 pieces in red, green, blue, black, yellow, white. Any self-respecting LEGOist probably has these at home. Then there is a piece of cardboard that has a grid of dots which aide in recognizing the shapes you put together. Plus there is a very brief Getting Started guide and a sticker showing George in all his 8-bit glory. The product is smartly priced at a level where you probably prefer the convenience of having it all in a box over pirating the pieces from your kids and using a scan of the mat. Also this level of innovativeness needs to be rewarded, so I purchased the original product at my Apple Store. And so should you: if not for yourself then for all the LEGO+iPhone fans around you. You select a model from initially 130 models and your goal is to complete these in as little time as possible. So you select a model, build that from the included pieces, drop it onto the grid, tap the cam button on the iPhone app which displays the model and countdown. Then you position the iPhone such that it sees the entire grid. It does not matter where on the grid you place the finished model. When playing you should make sure that you have sufficient space to lay out the pieces for faster access. Also the bricks have a tendency to fall to the floor if permitted. The models are rated in 12 difficulty levels. The most fun, but also the biggest weakness of this game is Multiplayer. There is no support for Game Center and Online competition. Instead you have to make due with pass&#8217;n'play mode. Players alternate building different models, because it would be useless to be building exactly the same model if the person before you has already found all the pieces. Though there seems to be a balancing glitch: On one of my multi-player games I was getting a very difficult model while my opponent got something extremely simple. Unfair! The other problem is that on several occasions the model was not recognized properly causing no points to be awarded. Instead you just get a display with tips to improve recognition, like tilting to avoid shine or making sure that the entire mat is visible. But no option to retake the picture. Annoying! LEGO plans to sell us additional models for certain holidays, the first one being the Christmas pack for $2 which contains &#8220;3 new levels of Christmas content with 30 new Challenges and 45 models&#8221;. Don&#8217;t ask me how this works out mathematically and what the difference between challenge and model is. That the price is still $2 even after the turn of the year reminds us that Apple still does not permit In-App-Purchases for free. Finally &#8211; what might be even be the coolest feature of all &#8211; you also get to make your own models. I tried making my Cocoanetics logo here: The image recognition software tries to match the contained pieces with what it &#8220;sees&#8221; on the mat. But the pieces need to be upright. We build a ciqua logo, but with the pips pointing to the side and that was not properly recognized.  The software cannot differentiate between two adjacent pieces of the same color. If you please a 2 and a 1 next to each other, it is recognized as a 3. So far the models the app tries out all the variations that are possible and seems to always try to take the longest bricks possible. Life of George uses image recognition technology from Eye Cue Vision Technologies which they describe themselves as &#8220;&#8230;the first and only low-cost vision recognition platform in the world for toys&#8221;. I image that the innovative guys at LEGO &#8211; which is extremely active in terms of product development for bricks as well as apps &#8211; found Eye Cue to be an affordable and simple to implement technology and so they hammered out this deal. Their low-cost technology circumvents the problem you have with normal computer vision of having to adjust for a wide variety of image quality by simplifying the shapes it has to recognize, little squares in primary colors, and by using this grid mat for calibration. It&#8217;s is orders of magnitude more simple to recognize and align a grid of [...]]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/01/lego-life-of-george/"></g:plusone></div><p>LEGO&#8217;s Life of George game brings together 5 worlds like nothing else before:</p>
<ul>
<li>8-Bit Design</li>
<li>iPhone</li>
<li>LEGO bricks</li>
<li>manual interaction, a &#8220;touch interface&#8221; if you will</li>
<li>computer vision for gamification</li>
</ul>
<p>Let&#8217;s have a quick look at this fun pastime that is all the rage.</p>
<p><span id="more-5800"></span></p>
<div class="inner_ad_block">
<div id="advman-7" class="widget Advman_Widget">
<h3 class="widgettitle"></h3>
<p><!-- BuySellAds.com Zone Code --></p>
<div id="bsap_1260346" class="bsarocks bsap_fc3166ea4a479e0fdb4251fbe92a1219"></div>
<p><!-- End BuySellAds.com Zone Code --></div>
<div id="text-21" class="widget widget_text">
<h3 class="widgettitle">Label</h3>
<div class="textwidget">
<div class="advert-notice"><a href="http://buysellads.com/buy/detail/56639/zone/1260346">Buy an ad here</a></div>
</div></div>
</div>
<p>The <a href="http://itunes.apple.com/at/app/life-of-george/id463288121?mt=8">LEGO Life of George app</a> is a free download on the app store. To play you need the box which contains some additional ingredients you need to play. You get 6&#215;1, 8&#215;2, 4&#215;3, 4&#215;4 and 2&#215;6 pieces in red, green, blue, black, yellow, white. Any self-respecting LEGOist probably has these at home. Then there is a piece of cardboard that has a grid of dots which aide in recognizing the shapes you put together. Plus there is a very brief Getting Started guide and a sticker showing George in all his 8-bit glory.</p>
<p>The product is smartly priced at a level where you probably prefer the convenience of having it all in a box over pirating the pieces from your kids and using a scan of the mat. Also this level of innovativeness needs to be rewarded, so I purchased the original product at my Apple Store. And so should you: if not for yourself then for all the LEGO+iPhone fans around you.</p>
<p><a href="http://www.cocoanetics.com/files/IMG_0380.jpg"><img class="alignnone size-medium wp-image-5801" title="LEGO Ingredients" src="http://www.cocoanetics.com/files/IMG_0380-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>You select a model from initially 130 models and your goal is to complete these in as little time as possible. So you select a model, build that from the included pieces, drop it onto the grid, tap the cam button on the iPhone app which displays the model and countdown. Then you position the iPhone such that it sees the entire grid. It does not matter where on the grid you place the finished model.</p>
<p><a href="http://www.cocoanetics.com/files/IMG_0382.jpg"><img class="alignnone size-medium wp-image-5803" title="Select and Play" src="http://www.cocoanetics.com/files/IMG_0382-300x200.jpg" alt="" width="300" height="200" /></a></p>
<p>When playing you should make sure that you have sufficient space to lay out the pieces for faster access. Also the bricks have a tendency to fall to the floor if permitted. The models are rated in 12 difficulty levels.</p>
<p>The most fun, but also the biggest weakness of this game is Multiplayer. There is no support for Game Center and Online competition. Instead you have to make due with pass&#8217;n'play mode. Players alternate building different models, because it would be useless to be building exactly the same model if the person before you has already found all the pieces. Though there seems to be a balancing glitch: On one of my multi-player games I was getting a very difficult model while my opponent got something extremely simple. Unfair!</p>
<p>The other problem is that on several occasions the model was not recognized properly causing no points to be awarded. Instead you just get a display with tips to improve recognition, like tilting to avoid shine or making sure that the entire mat is visible. But no option to retake the picture. Annoying!</p>
<p><a href="http://www.cocoanetics.com/files/IMG_0384.jpg"><img class="alignnone size-medium wp-image-5807" title="Multiplayer Failure" src="http://www.cocoanetics.com/files/IMG_0384-300x200.jpg" alt="" width="300" height="200" /></a></p>
<p>LEGO plans to sell us additional models for certain holidays, the first one being the Christmas pack for $2 which contains &#8220;3 new levels of Christmas content with 30 new Challenges and 45 models&#8221;. Don&#8217;t ask me how this works out mathematically and what the difference between challenge and model is. That the price is still $2 even after the turn of the year reminds us that Apple still does not permit In-App-Purchases for free.</p>
<p>Finally &#8211; what might be even be the coolest feature of all &#8211; you also get to make your own models. I tried making my Cocoanetics logo here:</p>
<p><a href="http://www.cocoanetics.com/files/IMG_0383.jpg"><img class="alignnone size-medium wp-image-5806" title="Cocoanetics LEGO Logo" src="http://www.cocoanetics.com/files/IMG_0383-300x200.jpg" alt="" width="300" height="200" /></a></p>
<p>The image recognition software tries to match the contained pieces with what it &#8220;sees&#8221; on the mat. But the pieces need to be upright. We build a ciqua logo, but with the pips pointing to the side and that was not properly recognized.  The software cannot differentiate between two adjacent pieces of the same color. If you please a 2 and a 1 next to each other, it is recognized as a 3. So far the models the app tries out all the variations that are possible and seems to always try to take the longest bricks possible.</p>
<div>Life of George uses image recognition technology from <a href="http://www.eyecue-tech.com/ProductsOverview.aspx">Eye Cue</a> Vision Technologies which they describe themselves as <em>&#8220;&#8230;the first and only low-cost vision recognition platform in the world for toys&#8221;</em>. I image that the innovative guys at LEGO &#8211; which is extremely active in terms of product development for bricks as well as apps &#8211; found Eye Cue to be an affordable and simple to implement technology and so they hammered out this deal.</div>
<p>Their low-cost technology circumvents the problem you have with normal computer vision of having to adjust for a wide variety of image quality by simplifying the shapes it has to recognize, little squares in primary colors, and by using this grid mat for calibration. It&#8217;s is orders of magnitude more simple to recognize and align a grid of primary color blocks versus having to do edge and shape detection. This is an smart approach makes the technology robust enough for use by everybody. If you are used to buying LEGO bricks then you also have no issue with using this cardboard thing. So this partnership turns out to be a very nice fit between LEGO and Eye Cue.</p>
<p>LEGO is smart to exploring this unknown territory between digital and physical, between virtual and real. Normal apps which are digital offer much less satisfying value to the player than LEGO can.</p>
<p>If what I am hearing is any indication then LEGO has a hit. What&#8217;s next? Maybe an app to remote control LEGO robots?</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5800&amp;md5=5936e8360d6132a21689cdc3bb22108f" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/01/lego-life-of-george/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5800&amp;md5=5936e8360d6132a21689cdc3bb22108f" type="text/html" />"
	</item>
		<item>
		<title>genstrings2</title>
		<link>http://www.cocoanetics.com/2012/01/genstrings2/</link>
		<comments>http://www.cocoanetics.com/2012/01/genstrings2/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 16:05:07 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5797</guid>
		<description><![CDATA[Actually I am on vacation, but I couldn&#8217;t help myself using the breather to work on a little hobby project. This I shall reveal to you today! If you localize your apps (iOS or Mac regardless) you are probably used to working with genstrings. Probably painfully working, which is why we built the Mac app Linguan which remote-controls genstrings and merges the results with your previously existing tokens. But genstrings has several big problems. Label Buy an ad here The most pressing problem of using genstrings from Linguan is that it is very picky about the syntax of the string macros. If you have a parameter for the macro that is not a literal @&#8221;string&#8221; then it will crash. Several Linguan users have been stumped by this behavior because this makes it impossible for Linguan to scan their source code. The second problem is that we don&#8217;t have access to genstrings source code, and so we neither cannot know what this tool really does, nor can we modernize it to make use of modern multi-processor systems. genstrings is single-threaded. The third problem is that before now the only way how we could call genstrings from within Linguan is basically open an invisible shell and then read the output files from some hidden temporary output folder. You get genstrings with Xcode, but what if you don&#8217;t want to install Xcode on the machine you want to use with Linguan? Having to spawn a process for each source file individually has also proven to be impracticable because instead of a 0.3 seconds this would take 12 seconds for scanning just the Linguan source files. If that is any indication then the genstrings man page has not been updated since May 7, 2007. Any substantial improvements to the tool are probably even older than this, somebody from Apple told me that this goes back as long as the NeXt days. My goal was to reverse-engineer the functionality of genstrings, put that into a static library and thus be able to bring native high-performance string scanning to Linguan without the need for genstrings to be present any more. My latest Open Source project DTLocalizableStringScanner (on GitHub) contains two targets: one for a static library which we can use for scanning the source files. The other is a re-implementation of a command line tool which can take the place of genstrings. genstrings2 is built around NSScanner for the scanning and GCD queues for multi-threading. There might be faster ways to scan for the macros but there is no reason to do that at the expense of the code being easy to read. I&#8217;d rather fill up a Grand Central Dispatch queue with one block per source file and thus make full use of multiple CPU cores. It works on as many files in parallel as GCD permits. You can help hone this into a worthy successor for genstrings by testing it on your own source code and telling me about edge cases that it does not handle properly. For one thing it should ignore invalid macros instead of crashing like the original, that&#8217;s one immediate advantage that you get from symbolic-linking genstrings2 to be used instead of genstrings. There is one (undocumented) behavior that is not implemented yet. genstrings apparently expands tokens containing lists in the format [one, two, three] into three lines with [one], [two] and [three]. People would use this to localizes NSPredicateEditor. But that&#8217;s an easy exercise that I will do in the next few days. If there are no show stoppers then DTLocalizableStringScanner will replace genstrings already in Linguan 1.0.3.]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2012/01/genstrings2/"></g:plusone></div><p>Actually I am on vacation, but I couldn&#8217;t help myself using the breather to work on a little hobby project. This I shall reveal to you today!</p>
<p>If you localize your apps (iOS or Mac regardless) you are probably used to working with genstrings. Probably painfully working, which is why we built the Mac app <a href="http://www.cocoanetics.com/apps/Linguan/">Linguan</a> which remote-controls genstrings and merges the results with your previously existing tokens.</p>
<p>But genstrings has several big problems.</p>
<p><span id="more-5797"></span></p>
<div class="inner_ad_block">
<div id="advman-7" class="widget Advman_Widget">
<h3 class="widgettitle"></h3>
<p><!-- BuySellAds.com Zone Code --></p>
<div id="bsap_1260346" class="bsarocks bsap_fc3166ea4a479e0fdb4251fbe92a1219"></div>
<p><!-- End BuySellAds.com Zone Code --></div>
<div id="text-21" class="widget widget_text">
<h3 class="widgettitle">Label</h3>
<div class="textwidget">
<div class="advert-notice"><a href="http://buysellads.com/buy/detail/56639/zone/1260346">Buy an ad here</a></div>
</div></div>
</div>
<p>The most pressing problem of using genstrings from Linguan is that it is very <strong>picky about the syntax of the string macros</strong>. If you have a parameter for the macro that is not a literal @&#8221;string&#8221; then it will crash. Several Linguan users have been stumped by this behavior because this makes it impossible for Linguan to scan their source code.</p>
<p>The second problem is that we <strong>don&#8217;t have access to genstrings source code</strong>, and so we neither cannot know what this tool really does, nor can we modernize it to make use of modern multi-processor systems. genstrings is single-threaded.</p>
<p>The third problem is that before now the only way how we could call genstrings from within Linguan is basically open an invisible shell and then read the output files from some hidden temporary output folder. You get genstrings with Xcode, but what if you don&#8217;t want to install Xcode on the machine you want to use with Linguan? <strong>Having to spawn a process</strong> for each source file individually has also proven to be impracticable because instead of a 0.3 seconds this would take 12 seconds for scanning just the Linguan source files.</p>
<p>If that is any indication then the genstrings man page has not been updated since May 7, 2007. Any substantial improvements to the tool are probably even older than this, somebody from Apple told me that this goes back as long as the NeXt days.</p>
<p>My goal was to reverse-engineer the functionality of genstrings, put that into a static library and thus be able to bring native high-performance string scanning to Linguan without the need for genstrings to be present any more.</p>
<p>My latest Open Source project <a href="https://github.com/Cocoanetics/DTLocalizableStringScanner">DTLocalizableStringScanner</a> (on GitHub) contains two targets: one for a static library which we can use for scanning the source files. The other is a re-implementation of a command line tool which can take the place of genstrings.</p>
<p><strong>genstrings2</strong> is built around NSScanner for the scanning and GCD queues for multi-threading. There might be faster ways to scan for the macros but there is no reason to do that at the expense of the code being easy to read. I&#8217;d rather fill up a Grand Central Dispatch queue with one block per source file and thus make full use of multiple CPU cores. It works on as many files in parallel as GCD permits.</p>
<p>You can help hone this into a worthy successor for genstrings by testing it on your own source code and telling me about edge cases that it does not handle properly. For one thing it should ignore invalid macros instead of crashing like the original, that&#8217;s one immediate advantage that you get from symbolic-linking genstrings2 to be used instead of genstrings.</p>
<p>There is one (undocumented) behavior that is not implemented yet. genstrings apparently expands tokens containing lists in the format [one, two, three] into three lines with [one], [two] and [three]. People would use this to localizes NSPredicateEditor. But that&#8217;s an easy exercise that I will do in the next few days.</p>
<p>If there are no show stoppers then DTLocalizableStringScanner will replace genstrings already in Linguan 1.0.3.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5797&amp;md5=9a8ea7fa548cbfd14f910a9383a9deda" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2012/01/genstrings2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5797&amp;md5=9a8ea7fa548cbfd14f910a9383a9deda" type="text/html" />"
	</item>
		<item>
		<title>Myth Busted: iPhones Won&#8217;t Work With Gloves</title>
		<link>http://www.cocoanetics.com/2011/12/myth-busted-iphones-wont-work-with-gloves/</link>
		<comments>http://www.cocoanetics.com/2011/12/myth-busted-iphones-wont-work-with-gloves/#comments</comments>
		<pubDate>Fri, 30 Dec 2011 08:38:32 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Apple]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5785</guid>
		<description><![CDATA[Imagine me getting a mani-pedi during the Christmas holidays. No, really! We have a lady come to our house regularly and doing all willing feet. Somehow our casual conversion came to the iPhone. Now imagine this healthcare professional telling me: &#8220;For me the iPhone is no option because it does not work with the gloves we use&#8221;. One does not have to say THAT to me twice. This myth was begging to be busted. Label Buy an ad here First thing I tried out was one of the original Latex gloves. There was almost no difference in the ability of my iPhone and iPad detecting touches. Can you imagine how belief-shattering this was when I showed it off to my witnesses? &#8221;Oh my, then I had been told a lie!&#8221; When I mentioned this finding on Twitter one of the responses was: They&#8217;re probably thin enough. Regular gloves don&#8217;t work, unless they&#8217;re specially prepared. Thicker. Hm, where do I get thicker gloves? Ah, my wife got these cleaning gloves made from rubber. Those only worked like 80%, you had to push slightly more than usual and also their rubbery surface made sliding over the display a bit awkward. But it still worked well enough for emergencies. So thickness does not play a role either as this step 2 in our experiment showed. John Blanchard told me: &#8220;I recently noticed I can use my iPhone through my motorcycle gloves. Didn&#8217;t expect that!&#8221; And here is picture proof of him using his iPhone with his real leather Stryker Gloves. They don&#8217;t even mention &#8220;iPhone-compatible&#8221; in the product description. Maybe they should! I asked for other people to contribute photos of them using their iPhones with gloves. Hermano Queiroz was the second person to present photo proof of his gloves working with his iPhone: Haha, very funny Hermano! We all know that you&#8217;re cheating on this photo. Clearly these are your wife&#8217;s fingers, not yours. But Hermano also had this picture proof. He need 3 tries for that. On the first you could only see the screen showing my original tweet, but not the material of the gloves. The second only showed a blurry screen. The HDR setting finally got the best of both worlds. Finally the coolest entry in the &#8220;show your gloves contest&#8221; did not involve gloves at all. Timothee Boucher mentioned: I&#8217;m sure it would work with a Ziplock™ bag. I used that to still listen to and control Pandora while painting. It just so happens that I hav such a bag at home, who doesn&#8217;t? I have been using it to waterproof my iPhone while walking the dog while it rains. In Europe these are sold by Toppits. Here you see me aceing the final test: If we learned anything from this exercise then it is that our iOS devices are even more amazing than we previously realized. It is true that most material that are used for gloves won&#8217;t work. I tested wool and rough leather to no avail. But smooth leather has been proven to work on John&#8217;s gloves. Apparently there are a couple of elusive factors at work that are more complex than simply material or thickness. This post would not be complete if I didn&#8217;t mention that &#8211; of course! &#8211; there are winter gloves with specially coated finger tips. These guys in Michigan have compiled an extensive list: Best iPhone, iPad &#38; Android Touchscreen Gloves. People just love to use their iDevices with gloves.]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2011/12/myth-busted-iphones-wont-work-with-gloves/"></g:plusone></div><p>Imagine me getting a mani-pedi during the Christmas holidays. No, really! We have a lady come to our house regularly and doing all willing feet.</p>
<p>Somehow our casual conversion came to the iPhone. Now imagine this healthcare professional telling me:</p>
<blockquote><p><em>&#8220;For me the iPhone is no option because it does not work with the gloves we use&#8221;</em>.</p></blockquote>
<p>One does not have to say THAT to me twice. This myth was begging to be busted.</p>
<p><span id="more-5785"></span></p>
<div class="inner_ad_block">
<div id="advman-7" class="widget Advman_Widget">
<h3 class="widgettitle"></h3>
<p><!-- BuySellAds.com Zone Code --></p>
<div id="bsap_1260346" class="bsarocks bsap_fc3166ea4a479e0fdb4251fbe92a1219"></div>
<p><!-- End BuySellAds.com Zone Code --></div>
<div id="text-21" class="widget widget_text">
<h3 class="widgettitle">Label</h3>
<div class="textwidget">
<div class="advert-notice"><a href="http://buysellads.com/buy/detail/56639/zone/1260346">Buy an ad here</a></div>
</div></div>
</div>
<p>First thing I tried out was one of the original Latex gloves. There was almost no difference in the ability of my iPhone and iPad detecting touches.</p>
<p><a href="http://www.cocoanetics.com/files/IMG_0184.jpg"><img class="alignnone size-medium wp-image-5786" title="iPad with Latex" src="http://www.cocoanetics.com/files/IMG_0184-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>Can you imagine how belief-shattering this was when I showed it off to my witnesses? &#8221;Oh my, then I had been told a lie!&#8221;</p>
<p>When I mentioned this finding on Twitter one of the responses was:</p>
<blockquote><p>They&#8217;re probably thin enough. Regular gloves don&#8217;t work, unless they&#8217;re specially prepared.</p></blockquote>
<p>Thicker. Hm, where do I get thicker gloves? Ah, my wife got these cleaning gloves made from rubber. Those only worked like 80%, you had to push slightly more than usual and also their rubbery surface made sliding over the display a bit awkward. But it still worked well enough for emergencies.</p>
<p><a href="http://www.cocoanetics.com/files/IMG_0186.jpg"><img class="alignnone size-medium wp-image-5787" title="iPad and Rubber" src="http://www.cocoanetics.com/files/IMG_0186-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>So thickness does not play a role either as this step 2 in our experiment showed.</p>
<p>John Blanchard told me:</p>
<blockquote><p>&#8220;I recently noticed I can use my iPhone through my motorcycle gloves. Didn&#8217;t expect that!&#8221;</p></blockquote>
<p>And here is picture proof of him using his iPhone with his real leather <a href="http://www.motorcycle-superstore.com/mobile/ItemPage.aspx?DivisionGroupId=1&amp;DivisionId=1&amp;DepartmentId=37&amp;ItemStyleId=13152">Stryker Gloves</a>. They don&#8217;t even mention &#8220;iPhone-compatible&#8221; in the product description. Maybe they should!</p>
<p><a href="http://www.cocoanetics.com/files/x2_a1dd457.jpg"><img class="alignnone size-medium wp-image-5788" title="iPhone and Shift Racing Stryker Gloves" src="http://www.cocoanetics.com/files/x2_a1dd457-225x300.jpg" alt="" width="225" height="300" /></a></p>
<p>I asked for other people to contribute photos of them using their iPhones with gloves. Hermano Queiroz was the second person to present photo proof of his gloves working with his iPhone:</p>
<p><a href="http://www.cocoanetics.com/files/Ah2FGchCMAAijW-1.jpg"><img class="alignnone size-medium wp-image-5790" title="iPhone and Wool" src="http://www.cocoanetics.com/files/Ah2FGchCMAAijW-1-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p>Haha, very funny Hermano! We all know that you&#8217;re cheating on this photo. Clearly these are your wife&#8217;s fingers, not yours. <img src='http://www.cocoanetics.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' /> </p>
<p>But Hermano also had this picture proof. He need 3 tries for that. On the first you could only see the screen showing my original tweet, but not the material of the gloves. The second only showed a blurry screen. The HDR setting finally got the best of both worlds.</p>
<p><a href="http://www.cocoanetics.com/files/Bildschirmfoto-2011-12-30-um-09.10.15.png"><img class="alignnone size-medium wp-image-5791" title="iPhone and Gloves" src="http://www.cocoanetics.com/files/Bildschirmfoto-2011-12-30-um-09.10.15-224x300.png" alt="" width="224" height="300" /></a></p>
<p>Finally the coolest entry in the &#8220;show your gloves contest&#8221; did not involve gloves at all. Timothee Boucher mentioned:</p>
<blockquote><p>I&#8217;m sure it would work with a Ziplock™ bag. <img src='http://www.cocoanetics.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  I used that to still listen to and control Pandora while painting.</p></blockquote>
<p>It just so happens that I hav such a bag at home, who doesn&#8217;t? I have been using it to waterproof my iPhone while walking the dog while it rains. In Europe these are sold by <a href="http://www.toppits.de">Toppits</a>.</p>
<p>Here you see me aceing the final test:</p>
<p><a href="http://www.cocoanetics.com/files/iPhoneZipLock.jpg"><img class="alignnone size-medium wp-image-5792" title="iPhone and ZipLock" src="http://www.cocoanetics.com/files/iPhoneZipLock-300x247.jpg" alt="" width="300" height="247" /></a></p>
<p>If we learned anything from this exercise then it is that our iOS devices are even more amazing than we previously realized.</p>
<p>It is true that most material that are used for gloves won&#8217;t work. I tested wool and rough leather to no avail. But smooth leather has been proven to work on John&#8217;s gloves. Apparently there are a couple of elusive factors at work that are more complex than simply material or thickness.</p>
<p>This post would not be complete if I didn&#8217;t mention that &#8211; of course! &#8211; there are winter gloves with specially coated finger tips. These guys in Michigan have compiled an extensive list: <a href="http://topiphoneresource.info/best-iphone-gloves/">Best iPhone, iPad &amp; Android Touchscreen Gloves</a>.</p>
<p>People just love to use their iDevices with gloves.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5785&amp;md5=2bfe8906f09df4813099711135c5a326" title="Flattr" target="_blank"><img src="http://www.cocoanetics.com/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cocoanetics.com/2011/12/myth-busted-iphones-wont-work-with-gloves/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5785&amp;md5=2bfe8906f09df4813099711135c5a326" type="text/html" />"
	</item>
	</channel>
</rss>

