<?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; Projects</title>
	<atom:link href="http://www.cocoanetics.com/category/projects/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>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>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="p58443"><td class="code" id="p5844code3"><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="p58444"><td class="code" id="p5844code4"><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>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="p581311"><td class="code" id="p5813code11"><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="p581312"><td class="code" id="p5813code12"><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="p581313"><td class="code" id="p5813code13"><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="p581314"><td class="code" id="p5813code14"><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="p581315"><td class="code" id="p5813code15"><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="p581316"><td class="code" id="p5813code16"><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>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>Decoding Safari&#8217;s Pasteboard Format</title>
		<link>http://www.cocoanetics.com/2011/09/decoding-safaris-pasteboard-format/</link>
		<comments>http://www.cocoanetics.com/2011/09/decoding-safaris-pasteboard-format/#comments</comments>
		<pubDate>Fri, 02 Sep 2011 15:43:39 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5386</guid>
		<description><![CDATA[If you have ever looked at UIPasteboard you might have seen that there are a variety of public types, like colors, images, plain text or URLs. But applications are also free to implement their own types to be put on the pasteboard when the existing types don&#8217;t do justice to your content. One such custom type is being used between Apple&#8217;s iOS apps, like mobile Safari, whenever you copy HTML snippets: &#8220;Apple Web Archive pasteboard type&#8221;. At first glance this looks really secretive because all you can see there is a long string of numbers representing the NSData for it. Today I am unveiling an Open Source solution to consuming this pasteboard type as well: DTWebArchive. Using this you can let your users copy something from Safari or Mail and pasted it into your app while preserving the rich text. I put this code into a new GitHub repository because even if you don&#8217;t dabble with CoreText and NSAttributedStrings+HTML then this project can be very useful to you. Label Buy an ad here When I started implementing cut/copy/paste for my DTRichTextEditor I found that text copied from Safari is both available on the pasteboard as plain text and as the above mentioned type. At that point I thought &#8220;Boy wouldn&#8217;t it be great if we could get at the HTML that was pasted&#8221;. Well, now you can. The reverse-engineering began by inspecting the NSData with a text editor. All I needed was to see the &#8220;BPLIST&#8221; tag at the beginning to know that this is in fact a binary plist. I deserialized it and was astonished to find that this is simply an NSDictionary. There are several elements to this archive, the most important one being the main contents in a WebArchive class which has mime type &#8220;test/html&#8221; and is the pure HTML that we are seeking. In addition to that &#8211; if you have copied images as well &#8211; you see an array of WebRessource elements where each encapsulates a file, typically an image, sometimes a CSS file. Those are basically cached copies. The original HTML still has the web URLs in it, but you could search for the WebResource with the same URL to find the local version. Finally if you have IFRAMEs in the main HTML then each IFRAME will also have a corresponding WebArchive in an separate array. For example a HTML5 YouTube video would be showing in an IFRAME. Because WebKit is Open Source could can see for yourself why my cleanroom re-implementation is way more portable. Heres the source for WebArchive.mm and here for WebResource.mm which relies heavily on LegacyWebArchive.cpp. Here&#8217;s an example where I copied text with one image. I decoded this pasteboard item with DTWebArchive output the HTML. DTWebArchive *archive = &#91;&#91;DTWebArchive alloc&#93; initWithData:data&#93;; &#160; DTWebResource *resource = archive.mainResource; NSString *string = &#91;&#91;NSString alloc&#93; initWithData:resource.data encoding:NSUTF8StringEncoding&#93;; &#160; NSLog&#40;@&#34;%@&#34;, string&#41;; &#160; &#91;archive release&#93;; This is not entirely correct, because it hard-codes NSUTF8StringEncoding but should take the actual encoding of the WebArchive contents. But you get the idea. I copied this into a snippet to look at it with the NSAttributedString+HTML demo project and this is what you see: (Actually I had to cheat a bit because I found that I first had to fix something in NSAS+HTML that would cause the image to shift upwards.) The next step for me is now to add this project as a submodule to NSAS+HTML and implement convenience methods to convert between attributed strings and web archives. Also maybe some convenience methods might be nice to get the UIImage for a specific URL. For you this means that you should add copy and pasting of rich HTML to your applications as well.]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2011/09/decoding-safaris-pasteboard-format/"></g:plusone></div><p>If you have ever looked at UIPasteboard you might have seen that there are a variety of public types, like colors, images, plain text or URLs. But applications are also free to implement their own types to be put on the pasteboard when the existing types don&#8217;t do justice to your content.</p>
<p>One such custom type is being used between Apple&#8217;s iOS apps, like mobile Safari, whenever you copy HTML snippets: &#8220;Apple Web Archive pasteboard type&#8221;. At first glance this looks really secretive because all you can see there is a long string of numbers representing the NSData for it.</p>
<p>Today I am unveiling an Open Source solution to consuming this pasteboard type as well: <a href="https://github.com/Cocoanetics/DTWebArchive">DTWebArchive</a>. Using this you can let your users copy something from Safari or Mail and pasted it into your app while preserving the rich text. I put this code into a new GitHub repository because even if you don&#8217;t dabble with CoreText and NSAttributedStrings+HTML then this project can be very useful to you.</p>
<p><span id="more-5386"></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>When I started implementing cut/copy/paste for my <a href="http://www.cocoanetics.com/parts/dtrichtexteditor/">DTRichTextEditor</a> I found that text copied from Safari is both available on the pasteboard as plain text and as the above mentioned type. At that point I thought <em>&#8220;Boy wouldn&#8217;t it be great if we could get at the HTML that was pasted&#8221;</em>. Well, now you can.</p>
<p>The reverse-engineering began by inspecting the NSData with a text editor. All I needed was to see the &#8220;BPLIST&#8221; tag at the beginning to know that this is in fact a binary plist. I deserialized it and was astonished to find that this is simply an NSDictionary.</p>
<p><a href="http://www.cocoanetics.com/files/Screen-Shot-2011-09-02-at-5.41.50-PM.png"><img class="alignnone size-medium wp-image-5395" title="Deserialized Dictionary" src="http://www.cocoanetics.com/files/Screen-Shot-2011-09-02-at-5.41.50-PM-300x98.png" alt="" width="300" height="98" /></a></p>
<p>There are several elements to this archive, the most important one being the main contents in a WebArchive class which has mime type &#8220;test/html&#8221; and is the pure HTML that we are seeking. In addition to that &#8211; if you have copied images as well &#8211; you see an array of WebRessource elements where each encapsulates a file, typically an image, sometimes a CSS file. Those are basically cached copies. The original HTML still has the web URLs in it, but you could search for the WebResource with the same URL to find the local version.</p>
<p>Finally if you have IFRAMEs in the main HTML then each IFRAME will also have a corresponding WebArchive in an separate array. For example a HTML5 YouTube video would be showing in an IFRAME.</p>
<p>Because WebKit is Open Source could can see for yourself why my cleanroom re-implementation is way more portable. Heres the source for <a href="http://trac.webkit.org/browser/trunk/Source/WebKit/mac/WebView/WebArchive.mm">WebArchive.mm</a> and here for <a href="http://trac.webkit.org/browser/trunk/Source/WebKit/mac/WebView/WebResource.mm">WebResource.mm</a> which relies heavily on <a href="http://trac.webkit.org/browser/trunk/Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp">LegacyWebArchive.cpp</a>.</p>
<p>Here&#8217;s an example where I copied text with one image.</p>
<p><a href="http://www.cocoanetics.com/files/Screen-Shot-2011-09-02-at-5.01.49-PM.png"><img class="alignnone size-medium wp-image-5387" title="Copying Rich Text from Safari" src="http://www.cocoanetics.com/files/Screen-Shot-2011-09-02-at-5.01.49-PM-159x300.png" alt="" width="159" height="300" /></a></p>
<p>I decoded this pasteboard item with DTWebArchive output the HTML.</p>

<div class="wp_codebox"><table><tr id="p538618"><td class="code" id="p5386code18"><pre class="objc" style="font-family:monospace;">DTWebArchive <span style="color: #002200;">*</span>archive <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>DTWebArchive alloc<span style="color: #002200;">&#93;</span> initWithData<span style="color: #002200;">:</span>data<span style="color: #002200;">&#93;</span>;
&nbsp;
DTWebResource <span style="color: #002200;">*</span>resource <span style="color: #002200;">=</span> archive.mainResource;
<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: #a61390;">string</span> <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>resource.data encoding<span style="color: #002200;">:</span>NSUTF8StringEncoding<span style="color: #002200;">&#93;</span>;
&nbsp;
NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%@&quot;</span>, <span style="color: #a61390;">string</span><span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #002200;">&#91;</span>archive release<span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>

<p>This is not entirely correct, because it hard-codes NSUTF8StringEncoding but should take the actual encoding of the WebArchive contents. But you get the idea.</p>
<p>I copied this into a snippet to look at it with the NSAttributedString+HTML demo project and this is what you see:</p>
<p><a href="http://www.cocoanetics.com/files/Screen-Shot-2011-09-02-at-5.30.30-PM.png"><img class="alignnone size-medium wp-image-5388" title="Pasted into NSAttributedString+HTML" src="http://www.cocoanetics.com/files/Screen-Shot-2011-09-02-at-5.30.30-PM-159x300.png" alt="" width="159" height="300" /></a></p>
<p>(Actually I had to cheat a bit because I found that I first had to fix something in NSAS+HTML that would cause the image to shift upwards.)</p>
<p>The next step for me is now to add this project as a submodule to NSAS+HTML and implement convenience methods to convert between attributed strings and web archives. Also maybe some convenience methods might be nice to get the UIImage for a specific URL.</p>
<p>For you this means that you should add copy and pasting of rich HTML to your applications as well.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5386&amp;md5=54ebe269ffe3c7cf61c7738b2a87ac06" 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/09/decoding-safaris-pasteboard-format/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5386&amp;md5=54ebe269ffe3c7cf61c7738b2a87ac06" type="text/html" />
	</item>
		<item>
		<title>Start Floating</title>
		<link>http://www.cocoanetics.com/2011/07/start-floating/</link>
		<comments>http://www.cocoanetics.com/2011/07/start-floating/#comments</comments>
		<pubDate>Thu, 28 Jul 2011 16:23:48 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=5261</guid>
		<description><![CDATA[You might have noticed that I blogged much less during the past 3 months, that was for the most part because almost all of my programming time went into a secret project for Scribd. Something that is finally revealed to the public on July 19th 2011. Preempting the next question I am usually asked at this point: &#8220;What is Scribd?&#8221; Scribd is often described as &#8220;the  YouTube of Documents&#8221;. You can upload and share any kind of document on their network and they have an HTML5 reader that you can embed on your blog. At the time the official statement was that Scribd is working on a mobile reader for iOS and they needed much more control over the rendering and interactivity of HTML-based content than UIWebView would afford them. Let me tell you how Scribd has completely ditched UIWebView and is revolutionizing the way you read on your iPhone. Introducing Float. Label Buy an ad here What is Float? Think of it like this: everything digital that you are reading today (blogs, tweeted articles, articles you have on a reading list, eBooks, documents, etc.) in one amazing mobile native app that displays the content in the most perfect way possible on your device. What follows here is a look at Float from a technical point of view, which I can provide because I was put in charge of the rich text display. If you are interested in reading more about the user experience itself then have a look at the reviews on all the other major blogs. I especially liked the review on Wired.com, which mentions me by name. Only The Best Ingredients My story with Float started 3 months ago. Sam Soffes &#8211; whom I greatly admire &#8211; discovered my work on CoreText and got me in contact with Scribd&#8217;s CTO Jared Friedman. We both were excited by the prospect of doing something on iOS that had never been done before, both technically as well as for the user experience. The basic approach that almost everybody in our industry takes when it comes to displaying rich text is to use UIWebViews. Which leads to several problems because Apple does not let us at the inner workings of WebKit which ticks inside of these web views. Instead you have to resort to complicated hacks to find out things like the content size of a web page or inject JavaScript commands to implement any sort of non-standard communication. Oh and it is slow to load, takes enormous amounts of memory and is almost impossible to customize visually if you don&#8217;t want to swizzle methods or hack the view hierarchy. Long story short: UIWebView sucks. Ok, you get the picture, now let me tell you how the grown-ups do it. With iOS 3.2 Apple brought over CoreText to the mobile platform. CoreText brings you NSAttributedString which is basically an NSString where certain areas of text can have different attributes. These attributes &#8211; like a certain font or text color &#8211; are contained in NSDictionaries that have a certain range for which they are valid. Problem is, Apple forgot to include the initWithHTML method that exists on OSX. So on Macs you can easily create an attributed string from an HTML file and render this in a CATextLayer. Not so on iOS, where you have to painstakingly construct the attributed strings yourself and not just that, CATextLayer exists, but it ignores certain attributes altogether to make it practically unusable. Enter NSAttributedStrings+HTML, my Open Source project to make it all much easier. It contains three major parts: A category for NSAttributedString that gives you an initWithHTML Objective-C wrapper classes to wrap CoreText objects UI Classes to render this rich text The main reason why I chose to make it FOSS is because as a single person I can never hope to implement all of HTML. If I had chosen to make this a for pay software people might have felt entitled to get certain things implemented. Instead, on GitHub, they can make they additions they need and can send me a pull request to merge their changes into the master to benefit all. Scribd is a big believer in Open Source and so you can thank them for sponsoring the project for the past 3 months. Almost all the commits I made during this time came out of that. A few of the most recent ones came from John Engelhart who famously created the fastest JSON parser of the world: JSONKit. BTW, John recently signed up full-time to work on Scribd&#8217;s iOS Team. And so can you, they are now hiring more than ever, especially since Sam Soffes moved on to new horizons. Personally I am too old and too married here in Austria to move to San Francisco, so I&#8217;ve been working under [...]]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2011/07/start-floating/"></g:plusone></div><p>You might have noticed that I blogged much less during the past 3 months, that was for the most part because almost all of my programming time went into a secret project for <a href="http://www.scribd.com">Scribd</a>. Something that is finally revealed to the public on July 19th 2011.</p>
<p>Preempting the next question I am usually asked at this point: &#8220;What is Scribd?&#8221; Scribd is often described as &#8220;the  YouTube of Documents&#8221;. You can upload and share any kind of document on their network and they have an HTML5 reader that you can embed on your blog.</p>
<p>At the time the official statement was that Scribd is working on a mobile reader for iOS and they needed much more control over the rendering and interactivity of HTML-based content than UIWebView would afford them.</p>
<p>Let me tell you how Scribd has completely ditched UIWebView and is revolutionizing the way you read on your iPhone. Introducing <a href="http://www.float.com">Float</a>.</p>
<p><span id="more-5261"></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>What is Float? Think of it like this: everything digital that you are reading today (blogs, tweeted articles, articles you have on a reading list, eBooks, documents, etc.) in one amazing mobile native app that displays the content in the most perfect way possible on your device.</p>
<p>What follows here is a look at Float from a technical point of view, which I can provide because I was put in charge of the rich text display. If you are interested in reading more about the user experience itself then have a look at the reviews on all the other major blogs. I especially liked the <a href="http://www.wired.com/epicenter/2011/07/float-netflix-reading/">review on Wired.com</a>, which mentions me by name. <img src='http://www.cocoanetics.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h3>Only The Best Ingredients</h3>
<p>My story with Float started 3 months ago. Sam Soffes &#8211; whom I greatly admire &#8211; discovered <a title="UIWebView must die" href="http://www.cocoanetics.com/2011/01/uiwebview-must-die/">my work on CoreText</a> and got me in contact with Scribd&#8217;s CTO Jared Friedman. We both were excited by the prospect of doing something on iOS that had never been done before, both technically as well as for the user experience.</p>
<p>The basic approach that almost everybody in our industry takes when it comes to displaying rich text is to use UIWebViews. Which leads to several problems because Apple does not let us at the inner workings of WebKit which ticks inside of these web views. Instead you have to resort to complicated hacks to find out things like the content size of a web page or inject JavaScript commands to implement any sort of non-standard communication.</p>
<p>Oh and it is slow to load, takes enormous amounts of memory and is almost impossible to customize visually if you don&#8217;t want to swizzle methods or hack the view hierarchy. Long story short: UIWebView sucks. Ok, you get the picture, now let me tell you how the grown-ups do it.</p>
<p>With iOS 3.2 Apple brought over CoreText to the mobile platform. CoreText brings you NSAttributedString which is basically an NSString where certain areas of text can have different attributes. These attributes &#8211; like a certain font or text color &#8211; are contained in NSDictionaries that have a certain range for which they are valid. Problem is, Apple forgot to include the initWithHTML method that exists on OSX. So on Macs you can easily create an attributed string from an HTML file and render this in a CATextLayer. Not so on iOS, where you have to painstakingly construct the attributed strings yourself and not just that, CATextLayer exists, but it ignores certain attributes altogether to make it practically unusable.</p>
<p>Enter <a href="https://github.com/Cocoanetics/NSAttributedString-Additions-for-HTML">NSAttributedStrings+HTML</a>, my Open Source project to make it all much easier. It contains three major parts:</p>
<ol>
<li>A category for NSAttributedString that gives you an initWithHTML</li>
<li>Objective-C wrapper classes to wrap CoreText objects</li>
<li>UI Classes to render this rich text</li>
</ol>
<p>The main reason why I chose to make it FOSS is because as a single person I can never hope to implement all of HTML. If I had chosen to make this a for pay software people might have felt entitled to get certain things implemented. Instead, on GitHub, they can make they additions they need and can send me a pull request to merge their changes into the master to benefit all.</p>
<p>Scribd is a big believer in Open Source and so you can thank them for sponsoring the project for the past 3 months. Almost all the commits I made during this time came out of that. A few of the most recent ones came from John Engelhart who famously created the <a title="JSON versus PLIST, the Ultimate Showdown" href="http://www.cocoanetics.com/2011/03/json-versus-plist-the-ultimate-showdown/">fastest JSON parser of the world</a>: JSONKit. BTW, John recently signed up full-time to work on Scribd&#8217;s iOS Team. And so can you, they are now hiring more than ever, especially since <a href="http://samsoff.es/posts/moving-on">Sam Soffes moved</a> on to new horizons.</p>
<p>Personally I am too old and too married here in Austria to move to San Francisco, so I&#8217;ve been working under contract with Scribd. Because of this our contract contains three levels of licensing in to cover the various levels of ownership and rights of the source code involved:</p>
<ul>
<li><strong>Open Source</strong> &#8211; code is owned by me, licensed publicly, Scribd would pay for the continued development necessary to provide the foundation for the other levels</li>
<li><strong>Proprietary</strong> &#8211; there is a great deal of proprietary code I developed on top of the open source. This code is owned by Scribd.</li>
<li><strong>Cross-Licensed</strong> &#8211; a few bits of code are owned by me and developed for use in my <a title="Rich Text Editing on iOS" href="http://www.cocoanetics.com/2011/01/rich-text-editing-on-ios/">rich text editor</a>. These I need to own so that I can sell it in other components, but Scribd has an automatic license.</li>
</ul>
<p>At this point I probably should give you a demo of the app so that you see what I am talking about.</p>
<p><a href="http://www.youtube.com/watch?v=OmIIxXFhBvs&#038;fmt=18">http://www.youtube.com/watch?v=OmIIxXFhBvs</a></p>
<p>All the rendering you see is in the Open Source project. Everything related to user interaction is the proprietary part. To give some examples for Scribd proprietary tech: dynamic switching between paging and scrolling mode, fast font resizing and style changing and multi-threaded layouting. Imagine me tinkering, programming, experimenting for the better part of two months to get the performance and responsiveness to where it is today.</p>
<h3>How Float Got It&#8217;s Name</h3>
<p>Let me also tell you the story of how Float got it&#8217;s name because this is closely related to this topic. Scribd&#8217;s CEO Trip Adler had a certain vision of how the ideal reading experience would look like. He felt that the user/reader should be able to decide for himself whether he preferred scrolling or paging through text. This is what he called &#8220;the Floating Reading Experience&#8221;. The user should be able to float around without such artificial bounds.</p>
<p>I have to admit &#8211; at that time &#8211; I was unsure how I would pull that off, secretly I thought Trip was crazy, pardon the pun: tripping. But I kept experimenting, tinkering, threw away a couple of failed approaches until I ended up with what you see today. Lo and behold, it is amazingly close to the original vision which is why Scribd rebranded the app as Float.</p>
<p>I learned one thing from this experience: as an engineer you might consider some ideas that your leaders come up with as crazy and impossible. But if you put enough work into it, even the impossible becomes possible after a while. The &#8220;Impossible&#8221; takes around 2 months.</p>
<p>There is <strong>one other ingredient</strong> in Float&#8217;s secret sauce that makes this possible. Scribd has developed amazing server-side technology to break apart fixed-structure documents of any kind and make then reflowable. For example they can dissolve a PDF and provide output where you can change the font size and pagination based on the device you are reading on. If there is something that is too complex to be put as pure text (like tables or a signature) then they render an image of that.</p>
<p>This is actually the much greater feat because at my end CoreText only has to worry about displaying this custom &#8220;clean room&#8221; HTML as opposed to having to worry about malformed tags and what not. I keep telling people that NSAS+HTML is great if they control the HTML and this is the perfect example. I know exactly which tags can come out of this reflow process and this predictability is key in having the display of text work all of the time.</p>
<p>So these are the two main ingredients that make Float unique and miles ahead of any kind of competition. And of course it gives me as a contributor a good feeling to be associated with a company that is in this position.</p>
<h3>Try It Out Now!</h3>
<p>Only time can tell if users will understand and accept how revolutionary Float actually is. But from a technical perspective I can honestly say that we did all that is humanly possible to make the greatest app (and service) we can. Please try it out now, it&#8217;s free. And once you have sufficiently marveled at it, let us know &#8211; preferably publicly &#8211; how you like it.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5261&amp;md5=fecf6f5089e6e96d935a5be5587abe9f" 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/07/start-floating/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=5261&amp;md5=fecf6f5089e6e96d935a5be5587abe9f" type="text/html" />
	</item>
		<item>
		<title>Translating NSTimeZone Geopolitical IDs</title>
		<link>http://www.cocoanetics.com/2011/03/translating-nstimezone-geopolitical-ids/</link>
		<comments>http://www.cocoanetics.com/2011/03/translating-nstimezone-geopolitical-ids/#comments</comments>
		<pubDate>Wed, 02 Mar 2011 18:01:59 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=4723</guid>
		<description><![CDATA[For my new version of Summertime I am building a time zone picker. You can get the known time zone names from the NSTimeZone class, but unfortunately Apple does not give us any localization of these. The localizedName:local: method gives you localized names of the time zones itself (e.g. &#8220;Pacific Standard Time&#8221;) in various formats. But what I found to be missing is a way to have the geo names localizable as well. If I have my iPhone set to German I want to find my timezone by entering &#8220;Wien&#8221;, not &#8220;Vienna&#8221;. My initial thought was to keep this to myself, but since I only speak German and English I can never hope to have the translations be perfect unless I would pay several translators to comb through them. And you know, Google Translate is great, but not 100%. So I started a new Open Source project on GitHub: NSTimeZone+Localization which aims to remedy this. Label Buy an ad here I wrote a quick command line tool which passes the knownTimeZoneNames through Google Translate for German, Spanish, French and Dutch as these are the languages that Summertime is currently localized in. More languages can be easily added the same way, but in general I would want to ask you a favor: if you speak any of these languages please have a quick look if you see any spelling or translation mistakes. I had a modified version of LKGoogleTranslator handy which I had to modify again to include my API key. This still uses version 1.0 of the API while 2.0 is a newer one, but since it worked I did not bother. #import &#34;LKGoogleTranslator.h&#34; int main &#40;int argc, const char * argv&#91;&#93;&#41; &#123; NSAutoreleasePool * pool = &#91;&#91;NSAutoreleasePool alloc&#93; init&#93;; &#160; LKGoogleTranslator *translator = &#91;&#91;LKGoogleTranslator alloc&#93; init&#93;; &#160; NSMutableString *string = &#91;NSMutableString string&#93;; &#160; for &#40;NSString *timezoneName in &#91;NSTimeZone knownTimeZoneNames&#93;&#41; &#123; // replace slashes with commas, works better in Google Translate NSString *searchName = &#91;timezoneName stringByReplacingOccurrencesOfString:@&#34;/&#34; withString:@&#34;,&#34;&#93;; searchName = &#91;searchName stringByReplacingOccurrencesOfString:@&#34;_&#34; withString:@&#34; &#34;&#93;; &#160; NSString *translation = &#91;translator translateText:searchName fromLanguage:@&#34;en&#34; toLanguage:@&#34;nl&#34;&#93;; translation = &#91;translation stringByReplacingOccurrencesOfString:@&#34;,&#34; withString:@&#34;/&#34;&#93;; translation = &#91;translation stringByReplacingOccurrencesOfString:@&#34;/ &#34; withString:@&#34;/&#34;&#93;; translation = &#91;translation stringByReplacingOccurrencesOfString:@&#34; &#34; withString:@&#34;_&#34;&#93;; &#160; &#91;string appendFormat:@&#34;\&#34;%@\&#34; = \&#34;%@\&#34;;\n&#34;, timezoneName, translation&#93;; &#160; NSLog&#40;@&#34;%@ = %@&#34;, timezoneName, translation&#41;; &#125; &#160; NSLog&#40;@&#34;%@&#34;, string&#41;; &#160; &#91;translator release&#93;; &#160; &#91;pool drain&#93;; return 0; &#125; The resulting string blog I just pasted into strings files. With the help of a small category extension on NSTimeZone you can now get the localized geopolitical name. #import &#34;NSTimeZone+Translation.h&#34; &#160; @implementation NSTimeZone &#40;Translation&#41; &#160; - &#40;NSString *&#41;localizedGeoName &#123; return NSLocalizedStringFromTable&#40;self.name, @&#34;LocalizableTimezones&#34;, @&#34;NSTimeZone+Translation&#34;&#41;; &#125; &#160; @end This works because the localizable strings files for this are called LocalizableTimezones.strings. Instead of the regular NSLocalizedString macro I&#8217;m using NSLocalizedStringFromTable with the middle parameter being the name of the strings file minus extension. You can use this functionality in your apps if in turn you feed back errors to me so that I can correct them. If you want additional languages to be added, let me know. I&#8217;ll make the same starting list via Google Translate for any newly requested languages and then you can manually polish them.]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2011/03/translating-nstimezone-geopolitical-ids/"></g:plusone></div><p><img class="alignright size-full wp-image-4724" title="Time Zone Selector" src="http://www.cocoanetics.com/files/Screen-shot-2011-03-02-at-8.52.09-AM.png" alt="" width="143" height="268" /></p>
<p>For my new version of <a href="http://www.cocoanetics.com/apps/summertime/">Summertime</a> I am building a time zone picker. You can get the known time zone names from the NSTimeZone class, but unfortunately Apple does not give us any localization of these. The localizedName:local: method gives you localized names of the time zones itself (e.g. &#8220;Pacific Standard Time&#8221;) in various formats. But what I found to be missing is a way to have the geo names localizable as well.</p>
<p>If I have my iPhone set to German I want to find my timezone by entering &#8220;Wien&#8221;, not &#8220;Vienna&#8221;.</p>
<p>My initial thought was to keep this to myself, but since I only speak German and English I can never hope to have the translations be perfect unless I would pay several translators to comb through them. And you know, Google Translate is great, but not 100%. So I started a new Open Source project on GitHub: <a href="https://github.com/Cocoanetics/NSTimeZone-Localization">NSTimeZone+Localization</a> which aims to remedy this.</p>
<p><span id="more-4723"></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>I wrote a quick command line tool which passes the knownTimeZoneNames through Google Translate for German, Spanish, French and Dutch as these are the languages that Summertime is currently localized in. More languages can be easily added the same way, but in general I would want to ask you a favor: if you speak any of these languages please have a quick look if you see any spelling or translation mistakes.</p>
<p>I had a modified version of <a href="http://code.google.com/p/objc-google-translate-api">LKGoogleTranslator</a> handy which I had to modify again to include my API key. This still uses version 1.0 of the API while 2.0 is a newer one, but since it worked I did not bother.</p>

<div class="wp_codebox"><table><tr id="p472321"><td class="code" id="p4723code21"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &quot;LKGoogleTranslator.h&quot;</span>
<span style="color: #a61390;">int</span> main <span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> argc, <span style="color: #a61390;">const</span> <span style="color: #a61390;">char</span> <span style="color: #002200;">*</span> argv<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSAutoreleasePool_Class/"><span style="color: #400080;">NSAutoreleasePool</span></a> <span style="color: #002200;">*</span> pool <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/NSAutoreleasePool_Class/"><span style="color: #400080;">NSAutoreleasePool</span></a> alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
&nbsp;
	LKGoogleTranslator <span style="color: #002200;">*</span>translator <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>LKGoogleTranslator alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
&nbsp;
	<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSMutableString_Class/"><span style="color: #400080;">NSMutableString</span></a> <span style="color: #002200;">*</span><span style="color: #a61390;">string</span> <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSMutableString_Class/"><span style="color: #400080;">NSMutableString</span></a> <span style="color: #a61390;">string</span><span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #a61390;">for</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>timezoneName <span style="color: #a61390;">in</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSTimeZone_Class/"><span style="color: #400080;">NSTimeZone</span></a> knownTimeZoneNames<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>
	<span style="color: #002200;">&#123;</span>
		<span style="color: #11740a; font-style: italic;">// replace slashes with commas, works better in Google Translate</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>searchName <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>timezoneName stringByReplacingOccurrencesOfString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;/&quot;</span> withString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;,&quot;</span><span style="color: #002200;">&#93;</span>;
		searchName <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>searchName stringByReplacingOccurrencesOfString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;_&quot;</span> withString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot; &quot;</span><span style="color: #002200;">&#93;</span>;
&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>translation <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>translator translateText<span style="color: #002200;">:</span>searchName fromLanguage<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;en&quot;</span> toLanguage<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;nl&quot;</span><span style="color: #002200;">&#93;</span>;
		translation <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>translation stringByReplacingOccurrencesOfString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;,&quot;</span> withString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;/&quot;</span><span style="color: #002200;">&#93;</span>;
		translation <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>translation stringByReplacingOccurrencesOfString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;/ &quot;</span> withString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;/&quot;</span><span style="color: #002200;">&#93;</span>;
		translation <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>translation stringByReplacingOccurrencesOfString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot; &quot;</span> withString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;_&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
		<span style="color: #002200;">&#91;</span><span style="color: #a61390;">string</span> appendFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;<span style="color: #2400d9;">\&quot;</span>%@<span style="color: #2400d9;">\&quot;</span> = <span style="color: #2400d9;">\&quot;</span>%@<span style="color: #2400d9;">\&quot;</span>;<span style="color: #2400d9;">\n</span>&quot;</span>, timezoneName, translation<span style="color: #002200;">&#93;</span>;
&nbsp;
		NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%@ = %@&quot;</span>, timezoneName, translation<span style="color: #002200;">&#41;</span>;
	<span style="color: #002200;">&#125;</span>
&nbsp;
	NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%@&quot;</span>, <span style="color: #a61390;">string</span><span style="color: #002200;">&#41;</span>;
&nbsp;
	<span style="color: #002200;">&#91;</span>translator release<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #002200;">&#91;</span>pool drain<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>The resulting string blog I just pasted into strings files. With the help of a small category extension on NSTimeZone you can now get the localized geopolitical name.</p>

<div class="wp_codebox"><table><tr id="p472322"><td class="code" id="p4723code22"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &quot;NSTimeZone+Translation.h&quot;</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSTimeZone_Class/"><span style="color: #400080;">NSTimeZone</span></a> <span style="color: #002200;">&#40;</span>Translation<span style="color: #002200;">&#41;</span>
&nbsp;
<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>localizedGeoName
<span style="color: #002200;">&#123;</span>
	<span style="color: #a61390;">return</span> NSLocalizedStringFromTable<span style="color: #002200;">&#40;</span>self.name, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;LocalizableTimezones&quot;</span>, <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;NSTimeZone+Translation&quot;</span><span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p>This works because the localizable strings files for this are called LocalizableTimezones.strings. Instead of the regular NSLocalizedString macro I&#8217;m using NSLocalizedStringFromTable with the middle parameter being the name of the strings file minus extension.</p>
<p>You can use this functionality in your apps if in turn you feed back errors to me so that I can correct them. If you want additional languages to be added, let me know. I&#8217;ll make the same starting list via Google Translate for any newly requested languages and then you can manually polish them.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=4723&amp;md5=13619272b731f5d25e2db98d1257b00e" 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/03/translating-nstimezone-geopolitical-ids/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=4723&amp;md5=13619272b731f5d25e2db98d1257b00e" type="text/html" />
	</item>
		<item>
		<title>OpenSource&#8217;ing MyAppSales</title>
		<link>http://www.cocoanetics.com/2011/01/opensourceing-myappsales/</link>
		<comments>http://www.cocoanetics.com/2011/01/opensourceing-myappsales/#comments</comments>
		<pubDate>Sun, 30 Jan 2011 11:25:25 +0000</pubDate>
		<dc:creator>Drops</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.cocoanetics.com/?p=4678</guid>
		<description><![CDATA[One of the things that people know me for is for continuing to develop on MyAppSales, my favorite tool to download and keep those elusive sales report from iTunes Connect. It&#8217;s always been a hobby and until now I&#8217;ve allowed people to access the source in exchange for a mandatory donation. This went on for almost two years now. Those donations never made sufficient money for me to pay for professional development. But I felt that I had to ask the approx. 500 people on the google group about their opinion as they might see their donation as a purchase and not like the idea of this software now being available for free. Boy was I wrong. Resoundingly people voted &#8220;+1&#8243; for going OpenSource. So here it is. It&#8217;s Open. Read on for how I moved the repo from my SVN server to GitHub, including the entire revision history. Label Buy an ad here I wanted to move the entire history so far onto GitHub so that it was preserved. Fortunately this capability is already built into git. It will get all revisions and convert them into commits. Create a local folder and init for a git repo: mkdir MyAppSales cd MyAppSales git init Set an SVN URL and fetch the entire history with all revisions. Amazing! This seems to be built into git. On the first go I made the mistake of importing the project root including trunk, tags and branches. So I aborted it, since I only wanted the contents of the trunk. git svn init https://svn.cocoanetics.com/myappsales/trunk git svn fetch Set the remote repo and push all there: The pull was necessary because I had commited and pushed a README before the import. git remote add origin git@github.com:Cocoanetics/MyAppSales.git git pull origin master git push origin master I almost couldn&#8217;t believe how easy it was, but from the upload taking a couple of seconds and not getting an error message I figured that it worked flawlessly. Upon checking the commits section of the online browser I found that amazingly the entire commit history was present. Made me smile to see the first import dated March 29, 2009. One thing to notice is how my user name changed every time I moved to a new server. Commits by &#8220;oliver&#8221; where done to the first repo which my friends at Spielhaus hosted. Then I moved to my new server, changing to &#8220;odrobnik&#8221;. Now on github I&#8217;m &#8220;Cocoanetics&#8221;. Also it turns out that the project is desperately in need of some cleanup work regarding where files are located in the folders. Class files in the root, images all over the place. Two more things I had to do: I copied a license and a .gitignore file so that it would not push some unwanted files. The first is created by OSX, build folders we never want and the last two are user settings which you don&#8217;t need either. .DS_Store build *.mode1v3 *.pbxuser I have several updates to this source still in progress on my Laptop. I&#8217;m working on migrating the entire database to CoreData because at present bearable performance is only achieved by caching to compressed files. So this is what I&#8217;ll bring to this project next. It&#8217;s also my hope that with the source being now open that this will encourage current and future users to contribute. The repo is located at https://github.com/Cocoanetics/MyAppSales. And of course donations are still very welcome, my PayPal address is oliver@drobnik.com.]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2011/01/opensourceing-myappsales/"></g:plusone></div><p>One of the things that people know me for is for continuing to develop on MyAppSales, my favorite tool to download and keep those elusive sales report from iTunes Connect. It&#8217;s always been a hobby and until now I&#8217;ve allowed people to access the source in exchange for a mandatory donation. This went on for almost two years now.</p>
<p>Those donations never made sufficient money for me to pay for professional development. But I felt that I had to ask the approx. 500 people on the <a href="http://groups.google.com/group/myappsales">google group</a> about their opinion as they might see their donation as a purchase and not like the idea of this software now being available for free. Boy was I wrong. Resoundingly people voted &#8220;+1&#8243; for going OpenSource.</p>
<p>So here it is. It&#8217;s Open. Read on for how I moved the repo from my SVN server to GitHub, including the entire revision history.<br />
<span id="more-4678"></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>I wanted to move the entire history so far onto GitHub so that it was preserved. Fortunately this capability is already built into git. It will get all revisions and convert them into commits.</p>
<p>Create a local folder and init for a git repo:</p>

<div class="wp_codebox"><table><tr id="p467826"><td class="code" id="p4678code26"><pre class="sh" style="font-family:monospace;">mkdir MyAppSales
cd MyAppSales
git init</pre></td></tr></table></div>

<p>Set an SVN URL and fetch the entire history with all revisions. Amazing! This seems to be built into git. On the first go I made the mistake of importing the project root including trunk, tags and branches. So I aborted it, since I only wanted the contents of the trunk.</p>

<div class="wp_codebox"><table><tr id="p467827"><td class="code" id="p4678code27"><pre class="sh" style="font-family:monospace;">git svn init https://svn.cocoanetics.com/myappsales/trunk
git svn fetch</pre></td></tr></table></div>

<p>Set the remote repo and push all there: The pull was necessary because I had commited and pushed a README before the import.</p>

<div class="wp_codebox"><table><tr id="p467828"><td class="code" id="p4678code28"><pre class="sh" style="font-family:monospace;">git remote add origin git@github.com:Cocoanetics/MyAppSales.git
git pull origin master
git push origin master</pre></td></tr></table></div>

<p>I almost couldn&#8217;t believe how easy it was, but from the upload taking a couple of seconds and not getting an error message I figured that it worked flawlessly. Upon checking the commits section of the online browser I found that amazingly the entire commit history was present. Made me smile to see the first import dated March 29, 2009.<br />
<a href="http://www.cocoanetics.com/files/Screen-shot-2011-01-30-at-12.04.13-PM.png"><img class="alignnone size-full wp-image-4679" title="All Revisions are there" src="http://www.cocoanetics.com/files/Screen-shot-2011-01-30-at-12.04.13-PM.png" alt="" width="604" height="602" /></a></p>
<p>One thing to notice is how my user name changed every time I moved to a new server. Commits by &#8220;oliver&#8221; where done to the first repo which my friends at Spielhaus hosted. Then I moved to my new server, changing to &#8220;odrobnik&#8221;. Now on github I&#8217;m &#8220;Cocoanetics&#8221;.</p>
<p>Also it turns out that the project is desperately in need of some cleanup work regarding where files are located in the folders. Class files in the root, images all over the place.</p>
<p>Two more things I had to do: I copied a license and a .gitignore file so that it would not push some unwanted files. The first is created by OSX, build folders we never want and the last two are user settings which you don&#8217;t need either.</p>
<pre>
.DS_Store
build
*.mode1v3
*.pbxuser
</pre>
<p>I have several updates to this source still in progress on my Laptop. I&#8217;m working on migrating the entire database to CoreData because at present bearable performance is only achieved by caching to compressed files. So this is what I&#8217;ll bring to this project next.</p>
<p>It&#8217;s also my hope that with the source being now open that this will encourage current and future users to contribute. The repo is located at <a href="https://github.com/Cocoanetics/MyAppSales">https://github.com/Cocoanetics/MyAppSales</a>. And of course donations are still very welcome, my PayPal address is oliver@drobnik.com.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=4678&amp;md5=2266adc0222df8ebd7434775c0f142ed" 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/01/opensourceing-myappsales/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=4678&amp;md5=2266adc0222df8ebd7434775c0f142ed" type="text/html" />
	</item>
		<item>
		<title>iPhone Landscape Stands &#8211; Cheap or DIY</title>
		<link>http://www.cocoanetics.com/2010/03/iphone-landscape-stands/</link>
		<comments>http://www.cocoanetics.com/2010/03/iphone-landscape-stands/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 08:07:44 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.drobnik.com/touch/?p=2210</guid>
		<description><![CDATA[After having released SpeakerClock, a speech countdown clock, I got a couple of suggestions, one was not about the app itself, but about how you could stand the iphone on it&#8217;s side. Kevin Jamison: &#8220;Now we just need to come up with a simple little stand similar to the iPod Touch uses to hold it in a tilted landscape mode. Maybe rubber coated feet so it won&#8217;t slide if you are using a podium.&#8221; I remembered that every once in a while the blogosphere brought to light yet another clever way of solving such problems. A quick search on Google and YouTube yielded a couple of great solutions. Some that you can purchase , same that you can make yourself at little to no cost. First let&#8217;s look at the professional solutions which typically cost between $5 and $10. After we&#8217;ve set the benchmark we&#8217;ll explore how we can achieve landscape stability ourselves. Building something useful out of physical things might be a welcome distraction from hours of coding Cocoa. Label Buy an ad here Professional Stands MovieWedge from MovieWedge.com Crabble from Seskimo: The Crabble is the only wallet-sized stand to offer an easily and continuously adjustable landscape viewing angle, ranging from 45 to 90 degrees, and, with its rubber claws, it is the only wallet-sized stand to give you that grip. GoGoStand from GoGoStand: The GoGoStand is a plastic folding stand that you can tuck away in your wallet for quick access whenever you need to prop up your phone or gadget. This stand was designed for all generations of iPhones and iPod Touches, but also works with many other phones including the Android G1, Droid, Palm Pre and more. Travel Stand from Griffin Technology: Travel Stand flips open to safely hold your iPhone or iPod touch in landscape mode for comfortable, hands-free viewing of your movies, videos, music, photos and more. When the show&#8217;s over, wind your earphones around the included cord wrap and flip the Travel Stand closed. Compact enough to slip into your pocket, Travel Stand is the perfect blend of stand and storage. Do it Yourself Paperclip Mini-DV Tape Box LEGOs The maker made the building instructions available at my request. Paper $100 Bill Same folding technique as the paper version, by Enrique Pardo. Laser-Cut Acrylic Make Magazine has the guide, all you need is access to a laser cutter&#8230; Credit Card All you need are a pair of scissors, some tape and an expired credit card. By Rod Porterfield. Cardboard Sleeve A cup sleeve that you would get free with coffee at &#8211; say &#8211; a Starbucks. Paper Cup A dixie cup with optional cancer society rubber wristband for additional grip. Business Card By far the easiest, most spontaneous possibility, no tools required. Conclusion Having reviewed quite a few ideas that other people had for either sellable products or DIY options I think that I would go for a solution that I could carry amongst my credit cards. There the GoGoStand looks to me the best professional solution even though the media is hyping the MovieWedge. But I don&#8217;t see that fitting into my wallet. Amongst the DIY it depends if you have time and tools at hand. The variant that has the most likelyhood of being portable is one using nothing but a business card. You don&#8217;t need any tools for it and the folding necessary is easier to remember than for the bill or paper versions. Please comment below what you&#8217;re using or if you found a version that I have not covered.]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2010/03/iphone-landscape-stands/"></g:plusone></div><p>After having released <a href="http://www.cocoanetics.com/2010/03/speakerclock-1-0/">SpeakerClock</a>, a speech countdown clock, I got a couple of suggestions, one was not about the app itself, but about how you could stand the iphone on it&#8217;s side.</p>
<blockquote><p>Kevin Jamison: &#8220;Now we just need to come up with a simple little stand similar to the iPod Touch uses to hold it in a tilted landscape mode. Maybe rubber coated feet so it won&#8217;t slide if you are using a podium.&#8221;</p></blockquote>
<p>I remembered that every once in a while the blogosphere brought to light yet another clever way of solving such problems. A quick search on Google and YouTube yielded a couple of great solutions. Some that you can purchase , same that you can make yourself at little to no cost.</p>
<p>First let&#8217;s look at the professional solutions which typically cost between $5 and $10. After we&#8217;ve set the benchmark we&#8217;ll explore how we can achieve landscape stability ourselves. Building something useful out of physical things might be a welcome distraction from hours of coding Cocoa. <img src='http://www.cocoanetics.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><span id="more-2210"></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>Professional Stands</h2>
<h3>MovieWedge</h3>
<p>from <a href="http://www.moviewedge.com" target="_blank">MovieWedge.com</a></p>
<h3>Crabble</h3>
<p>from <a href="http://www.seskimo.com" target="_blank">Seskimo</a>:</p>
<blockquote><p>The Crabble is the only wallet-sized stand to offer an easily and continuously adjustable landscape viewing angle, ranging from 45 to 90 degrees, and, with its rubber claws, it is the only wallet-sized stand to give you that grip.</p></blockquote>
<h3>GoGoStand</h3>
<p>from <a href="http://www.gogostand.com/" target="_blank">GoGoStand</a>:</p>
<blockquote><p>The GoGoStand is a plastic folding stand that you can tuck away in your wallet for quick access whenever you need to prop up your phone or gadget. This stand was designed for all generations of iPhones and iPod Touches, but also works with many other phones including the Android G1, Droid, Palm Pre and more.</p></blockquote>
<h3>Travel Stand</h3>
<p>from <a href="http://www.griffintechnology.com/products/travel-stand">Griffin Technology:</a></p>
<blockquote><p>Travel Stand flips open to safely hold your iPhone or iPod touch in landscape mode for comfortable, hands-free viewing of your movies, videos, music, photos and more. When the show&#8217;s over, wind your earphones around the included cord wrap and flip the Travel Stand closed. Compact enough to slip into your pocket, Travel Stand is the perfect blend of stand and storage.</p></blockquote>
<h2>Do it Yourself</h2>
<h3>Paperclip</h3>
<h3>Mini-DV Tape Box</h3>
<h3>LEGOs</h3>
<p>The maker made the <a href="https://docs.google.com/uc?id=0B7EVxRLTqlLgZDM1YWYxN2YtMTkwMC00NmU1LTgwNzktZmIwMzc0MzBlOTYw&amp;export=download&amp;hl=en">building instructions</a> available at my request.</p>
<h3>Paper</h3>
<h3>$100 Bill</h3>
<p>Same folding technique as the paper version, by Enrique Pardo.</p>
<h3>Laser-Cut Acrylic</h3>
<p><a href="http://blog.makezine.com/archive/2007/09/how_to_make_an_iphone_sta.html">Make Magazine</a> has the guide, all you need is access to a laser cutter&#8230;</p>
<h3>Credit Card</h3>
<p>All you need are a pair of scissors, some tape and an expired credit card. By Rod Porterfield.</p>
<h3>Cardboard Sleeve</h3>
<p>A cup sleeve that you would get free with coffee at &#8211; say &#8211; a Starbucks.</p>
<h3>Paper Cup</h3>
<p>A dixie cup with optional cancer society rubber wristband for additional grip.</p>
<h3>Business Card</h3>
<p>By far the easiest, most spontaneous possibility, no tools required.</p>
<h2>Conclusion</h2>
<p>Having reviewed quite a few ideas that other people had for either sellable products or DIY options I think that I would go for a solution that I could carry amongst my credit cards. There the GoGoStand looks to me the best professional solution even though the media is hyping the MovieWedge. But I don&#8217;t see that fitting into my wallet.</p>
<p>Amongst the DIY it depends if you have time and tools at hand. The variant that has the most likelyhood of being portable is one using nothing but a business card. You don&#8217;t need any tools for it and the folding necessary is easier to remember than for the bill or paper versions.</p>
<p>Please comment below what you&#8217;re using or if you found a version that I have not covered.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=2210&amp;md5=be6eeb96394441f550c20e94f71dd870" 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/2010/03/iphone-landscape-stands/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=2210&amp;md5=be6eeb96394441f550c20e94f71dd870" type="text/html" />
	</item>
		<item>
		<title>Featured by Apple</title>
		<link>http://www.cocoanetics.com/2010/01/featured-by-apple/</link>
		<comments>http://www.cocoanetics.com/2010/01/featured-by-apple/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 18:08:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.drobnik.com/touch/?p=1859</guid>
		<description><![CDATA[It is with a certain pride that I am announcing that truly was involved with the creation of an app that made it to the top. Well, at least in Austria and Germany, and at least in a category. I&#8217;m referring to Infrared Photography which is an app that was contracted out to us by none less than Michael Görmann, professional photographer and in need of a signature app that he could hand out as a sort of business card. Via a short detour he arrived at our virtual doorstep and was promptly served a cute little app. To put the credit where it is due and put it more precisely the programming itself was carried out by my brother-in-law whom I had the pleasure to help out here and there and generally have a mentoring eye over, when it comes to iPhone programming. He was and still is to this date an export for server-side Java, Android and Symbian. But about iPhone development I can proudly say: &#8220;He got that from me.&#8221; His name is Rene Pirringer and his company is ciqua. We are closely working together on iPhone projects. Infrared Photography is unique in a way because it gives you an endless supply of beautiful black&#38;white photos which where made with expensive Infrared Euqipment and by the unmatched eye of Mr. Görmann. So unique in fact that Apple approached him and asked him to put a couple more screenshots online, because they were planning to feature it. And so they did. You could see an immediate jump in downloads, but for the most part in Germany and Austria where it was featured. It seems that those countries are served by the same iTunes team at Apple. Being featured like this glued the app to the first place like you can see here: We are thankful for having had this chance find us and all you out there who keep downloading the app. It&#8217;s an amazing reference for us.]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2010/01/featured-by-apple/"></g:plusone></div><p>It is with a certain pride that I am announcing that  truly was involved with the creation of an app that made it to the top. Well, at least in Austria and Germany, and at least in a category.</p>
<p><a href="http://itunes.apple.com/app/infrared-photography/id348794277"><img class="alignright size-full wp-image-1860" src="http://www.cocoanetics.com/files/348794277.png" alt="" width="100" height="100" /></a>I&#8217;m referring to <a href="http://itunes.apple.com/app/infrared-photography/id348794277">Infrared Photography</a> which is an app that was contracted out to us by none less than <a href="http://www.michaelgoermann.de">Michael Görmann</a>, professional photographer and in need of a signature app that he could hand out as a sort of business card. Via a short detour he arrived at our virtual doorstep and was promptly served a cute little app.</p>
<p>To put the credit where it is due and put it more precisely the programming itself was carried out by my brother-in-law whom I had the pleasure to help out here and there and generally have a mentoring eye over, when it comes to iPhone programming. He was and still is to this date an export for server-side Java, Android and Symbian. But about iPhone development I can proudly say: &#8220;He got that from me.&#8221; His name is Rene Pirringer and his company is <a href="http://www.ciqua.com/">ciqua</a>. We are closely working together on iPhone projects.</p>
<p>Infrared Photography is unique in a way because it gives you an endless supply of beautiful black&amp;white photos which where made with expensive Infrared Euqipment and by the unmatched eye of Mr. Görmann. So unique in fact that Apple approached him and asked him to put a couple more screenshots online, because they were planning to feature it. And so they did.</p>
<p><a href="http://www.cocoanetics.com/files/Screen-shot-2010-01-15-at-19.03.56.png"><img class="size-full wp-image-1861 alignnone" src="http://www.cocoanetics.com/files/Screen-shot-2010-01-15-at-19.03.56.png" alt="" width="464" height="336" /></a></p>
<p>You could see an immediate jump in downloads, but for the most part in Germany and Austria where it was featured. It seems that those countries are served by the same iTunes team at Apple. Being featured like this glued the app to the first place like you can see here:</p>
<p><a href="http://www.cocoanetics.com/files/Screen-shot-2010-01-15-at-19.05.47.png"><img class="size-full wp-image-1862 alignnone" src="http://www.cocoanetics.com/files/Screen-shot-2010-01-15-at-19.05.47.png" alt="" width="384" height="585" /></a></p>
<p>We are thankful for having had this chance find us and all you out there who keep downloading the app. It&#8217;s an amazing reference for us.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=1859&amp;md5=262e71c04c142f008aa3ee83ddccf9d0" 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/2010/01/featured-by-apple/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=1859&amp;md5=262e71c04c142f008aa3ee83ddccf9d0" type="text/html" />
	</item>
		<item>
		<title>Augmenting Reality</title>
		<link>http://www.cocoanetics.com/2010/01/augmenting-reality/</link>
		<comments>http://www.cocoanetics.com/2010/01/augmenting-reality/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 21:46:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.drobnik.com/touch/?p=1835</guid>
		<description><![CDATA[Opinions differ on what constitutes &#8220;Augmented Reality&#8221;. This can generally range from sophisticated 3D graphics overlayed on a stereoscopic view of the word to simply overlaying floating icons related to a location over a live camera view. In between some also count as AR when you have a special marker in your hand which you webcam can track and inserts a small 3D model on top of it. On the iPhone it is currently not possible to do any sophisticated motion tracking or shape recognition was you can only get live images via a backdoor which Apple recently kind of opened just a bit so that useful applications like RedLaser or uStream can make use of it. Still it seems that the consensus is that you can only use images that have no UI elements over them as the workaround does captures of the whole screen. I figured it would be an interesting addition to my Dr. Touch&#8217;s Parts Store and so I set up to create DTAugmentedRealityController. The goal for V1.0 is to provide a view controller which you can feed icons and geo locations and the view controller would overlay said icons over live video from the iPhone&#8217;s camera. Label Buy an ad here I&#8217;ve been working on this for 3 days now and because of popular demand I&#8217;ve documented each evolutionary step in a YouTube video per day. Day 1 This was all about figuring out how to overlay my own views on top of UIImagePickerController. Turns out you have to do a bit of transform-magic to resize the video to be full screen, hide the UI elements and provide your own view for the overlayView property. Then I found that UIImagePickerController does not auto-rotate, so I had to apply my own transform. Maybe there is a way to get this rotation by subclassing it, but I have not tried that. I was thrilled to have a turning compass rose on top of the live video. Day 2 Stuff started to come together. On a static horizontal plan I displayed my first floating icon. I chose Steve Jobs because his location in Cupertino should be every iPhone Developers place of silent thankfulness not to sound overly religious. But Mr. Jobs was the best augmentation I was able to come up with for the reality of my office. Don&#8217;t you think so, too? Day 3+4 For the third episode I improved the engine tremendously.  First change was to pack all sensor-related activities into the DTRealitySensor class to have a central location for all sensing. Then I added rotation to the previously strictly parallel icon plan so the horizon would always stay parallel to the real one. Finally I was facing the challenge of implemented a true attitude independent compass. The built-in compass has a major drawback: it only works properly if the iphone is flat on it&#8217;s back. Which is of little use for a serious component that I am working on. Thankfully I discovered a paper &#8220;A NewSolution Algorithm of Magnetic Azimuth&#8221; which gave me the necessary insight to use both the gravity vector as well as the raw magnetic vector to calculate a compass bearing which works for any iphone attitude. Still to Come I already have several customers lining up to get this component into their hands. Once of them has a deadline of January 12th. He claims &#8220;if I don&#8217;t get it by then, I&#8217;ll code it my self&#8221;. &#8220;Yeah, right!&#8221; would be my appropriate response now that I have seen how much work it is to get the basics lined up. Version 1.0 of the component still has a couple for things to work out: Make a protocol that allows any UIView to be used for geolocated floating. You would add this view with a method to the controller and the controller would continuosly query your UIView via the protocol. This information would then be used to display the view on screen at the correct location. Invent some sort of dampening so that icons don&#8217;t jump around even though you are holding the iPhone still. Maybe have some detection on DTRealitySensor as to wether the iPhone is being moved or not. Still uncertain how to do this properly without loosing the generall responsiveness. Allow the user to set a maximum distance to show and maybe try to show icons smaller and foggier in the distance. There also has been a request to give the icons an altitude. Right now I am positioning in a simplified fashion. Implementing altitude would require that I start to calculate a pitch for looking vector. Then there are already a couple of ideas for future versions, but I need serious support would I go to tackle those: Do some simple geometric recognition if possible and stabilize the view [...]]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2010/01/augmenting-reality/"></g:plusone></div><p>Opinions differ on what constitutes &#8220;Augmented Reality&#8221;. This can generally range from sophisticated 3D graphics overlayed on a stereoscopic view of the word to simply overlaying floating icons related to a location over a live camera view. In between some also count as AR when you have a special marker in your hand which you webcam can track and inserts a small 3D model on top of it.</p>
<p>On the iPhone it is currently not possible to do any sophisticated motion tracking or shape recognition was you can only get live images via a backdoor which Apple recently kind of opened just a bit so that useful applications like RedLaser or uStream can make use of it. Still it seems that the consensus is that you can only use images that have no UI elements over them as the workaround does captures of the whole screen.</p>
<p>I figured it would be an interesting addition to my Dr. Touch&#8217;s Parts Store and so I set up to create DTAugmentedRealityController. The goal for V1.0 is to provide a view controller which you can feed icons and geo locations and the view controller would overlay said icons over live video from the iPhone&#8217;s camera.</p>
<p><span id="more-1835"></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>I&#8217;ve been working on this for 3 days now and because of popular demand I&#8217;ve documented each evolutionary step in a YouTube video per day.</p>
<h3>Day 1</h3>
<p>This was all about figuring out how to overlay my own views on top of UIImagePickerController. Turns out you have to do a bit of transform-magic to resize the video to be full screen, hide the UI elements and provide your own view for the overlayView property. Then I found that UIImagePickerController does not auto-rotate, so I had to apply my own transform. Maybe there is a way to get this rotation by subclassing it, but I have not tried that. I was thrilled to have a turning compass rose on top of the live video.</p>
<h3>Day 2</h3>
<p>Stuff started to come together. On a static horizontal plan I displayed my first floating icon. I chose Steve Jobs because his location in Cupertino should be every iPhone Developers place of silent thankfulness not to sound overly religious. But Mr. Jobs was the best augmentation I was able to come up with for the reality of my office. Don&#8217;t you think so, too?</p>
<h3>Day 3+4</h3>
<p>For the third episode I improved the engine tremendously.  First change was to pack all sensor-related activities into the DTRealitySensor class to have a central location for all sensing. Then I added rotation to the previously strictly parallel icon plan so the horizon would always stay parallel to the real one. Finally I was facing the challenge of implemented a true attitude independent compass.</p>
<p>The built-in compass has a major drawback: it only works properly if the iphone is flat on it&#8217;s back. Which is of little use for a serious component that I am working on. Thankfully I discovered a paper <a href="http://www.iop.org/EJ/article/1742-6596/48/1/020/jpconf6_48_020.pdf?request-id=e8b844c3-d58f-4a0e-8b41-7a1ffd0a1708">&#8220;A NewSolution Algorithm of Magnetic Azimuth&#8221;</a> which gave me the necessary insight to use both the gravity vector as well as the raw magnetic vector to calculate a compass bearing which works for any iphone attitude.</p>
<h3>Still to Come</h3>
<p>I already have several customers lining up to get this component into their hands. Once of them has a deadline of January 12th. He claims &#8220;if I don&#8217;t get it by then, I&#8217;ll code it my self&#8221;. &#8220;Yeah, right!&#8221; would be my appropriate response now that I have seen how much work it is to get the basics lined up.</p>
<p>Version 1.0 of the component still has a couple for things to work out:</p>
<ul>
<li>Make a protocol that allows any UIView to be used for geolocated floating. You would add this view with a method to the controller and the controller would continuosly query your UIView via the protocol. This information would then be used to display the view on screen at the correct location.</li>
<li>Invent some sort of dampening so that icons don&#8217;t jump around even though you are holding the iPhone still. Maybe have some detection on DTRealitySensor as to wether the iPhone is being moved or not. Still uncertain how to do this properly without loosing the generall responsiveness.</li>
<li>Allow the user to set a maximum distance to show and maybe try to show icons smaller and foggier in the distance.</li>
<li>There also has been a request to give the icons an altitude. Right now I am positioning in a simplified fashion. Implementing altitude would require that I start to calculate a pitch for looking vector.</li>
</ul>
<p>Then there are already a couple of ideas for future versions, but I need serious support would I go to tackle those:</p>
<ul>
<li>Do some simple geometric recognition if possible and stabilize the view on detected lines.</li>
<li>It would be great if we could detect shapes in general.</li>
<li>It should be fairly easy to also overlay an OpenGL layer and display 3D models overlaid over the live video.</li>
</ul>
<p>The final question that I&#8217;ve been asked a lot is what I am planning to charge for DTAugmentedRealityController. You have to bear in mind that I have so far invested 4 full working days (1600 Euros) into this project. Also with that much interest I have to make sure that I don&#8217;t make it too cheap and also make it expensive enough so that I can justify investing even more time. Finally AR seems to be a hot topic right now, especially on the iPhone. There are only very few well done AR applications, but I aim to be at the forefront in usability and ease of implementation.</p>
<p>So to get this settled, I chose 300 Euros, with a distinct upward trend. The first 5 customers will get it and keep it for that amount, after that I will reevaluate. Same terms and conditions apply as do for all other components on the <a href="http://www.cocoanetics.com/2010/01/dr-touchs-parts-store/">Dr. Touch&#8217;s Part Store</a>.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=1835&amp;md5=9ae728080cd48a2c2d352fbd3749ab04" 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/2010/01/augmenting-reality/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=1835&amp;md5=9ae728080cd48a2c2d352fbd3749ab04" type="text/html" />
	</item>
		<item>
		<title>Reverse-Engineering the Apple CalendarView</title>
		<link>http://www.cocoanetics.com/2009/12/reverse-engineering-the-apple-calendarview/</link>
		<comments>http://www.cocoanetics.com/2009/12/reverse-engineering-the-apple-calendarview/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 10:18:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.drobnik.com/touch/?p=1752</guid>
		<description><![CDATA[Now that I am able to work on my apps full time I finally get to fulfilling my user&#8217;s wishes. Amongst those, for iWoman, was a Calendar view. I did not want to use another person&#8217;s code and deconstructing something that Apple made proved to be extremely instructive. Here a video demonstration of my result so far. Please disregard the incorrect labelling at the top. At least this proves that this is not fake. The whole thing consists of three classes, a CalendarViewController which takes care of the general management of views, a CalendarDayView which derives it&#8217;s capabilities of responding to target/actions from UIButton and a CalendarHeadView which is everything you see at the top. What makes it look special and professional is that you have multiple gradients at work. Besides of the obvious one at the bottom, there are black and gray gradients shading most of the labels. The regular gray background I custom draw in drawRect, but the blue selected box was too complicated so I opted to use a UIImage for that. For most of the calendar calculations I needed an NSCalendar, so I made a helper class with category extensions to NSCalendar to give me things like first day of next month, first day of current month, number of days and so on. I found that I could quite reduce my memory footprint by reusing things. Like instantiating the NSCalendar just once for the whole view controller. By far the trickiest business was to properly set up the grid of CalendarDayViews on an invisible view where I enabled cropping of children so that stuff could appear smoothly from below the gradient at the bottom. The animation itself is trivial, but it took some time to figure out that I would have to overlay the bottom or top line with alpha 0 with another set of days when going forward or backward and then animate it to 1 so that the selected day would move from being a gray rectangle (if you tap on a day that belongs to another month) to being blue. For quickly switching between months you can tap and hold one of the arrows. For this I did not need any animations, so I pimped the method to set up my sheet with an animated: BOOL parameter. For regular switching this would be YES, for fast-switching it would be NO. Et voila! That all worked nicely until I started to use it on device. I was asked about the performance on device, especially for fast-scrolling. I found that I could tremendously improve this by reusing the UIViews I am creating one for each day. Before my optimization all subviews to my sheet where removed from superview when they left the visible area. Since the sheet was the only view retaining them this also lead to their deallocation. Then I simply introduced an NSMutableSet to hold onto removed Views and also reuse CalendarDayViews from there. This speed things up quite a bit. Reuse if you can as much as you can! Next things to do on the CalendarView control is to add a table view below it, so that I can query a data source for table view sections and rows pertaining to the currently selected date. I plan on using this in version 2 of iWoman, the first major update to my best selling app. I owe this to my customers since I did not get to update this app in over a year. CalendarView will be the first of many things in my &#8220;Dr. Touch Parts Store&#8221; where you can obtain high quality components to use in your own projects for a small donation. The concept is that this small amount of money pays for the time I need to continue to improve it, support it and help you with implementing it.]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2009/12/reverse-engineering-the-apple-calendarview/"></g:plusone></div><p>Now that I am able to work on my apps full time I finally get to fulfilling my user&#8217;s wishes. Amongst those, for iWoman, was a Calendar view. I did not want to use another person&#8217;s code and deconstructing something that Apple made proved to be extremely instructive.</p>
<p>Here a video demonstration of my result so far. Please disregard the incorrect labelling at the top. At least this proves that this is not fake. <img src='http://www.cocoanetics.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>The whole thing consists of three classes, a CalendarViewController which takes care of the general management of views, a CalendarDayView which derives it&#8217;s capabilities of responding to target/actions from UIButton and a CalendarHeadView which is everything you see at the top.</p>
<p>What makes it look special and professional is that you have multiple gradients at work. Besides of the obvious one at the bottom, there are black and gray gradients shading most of the labels. The regular gray background I custom draw in drawRect, but the blue selected box was too complicated so I opted to use a UIImage for that.</p>
<p>For most of the calendar calculations I needed an NSCalendar, so I made a helper class with category extensions to NSCalendar to give me things like first day of next month, first day of current month, number of days and so on. I found that I could quite reduce my memory footprint by reusing things. Like instantiating the NSCalendar just once for the whole view controller.</p>
<p>By far the trickiest business was to properly set up the grid of CalendarDayViews on an invisible view where I enabled cropping of children so that stuff could appear smoothly from below the gradient at the bottom. The animation itself is trivial, but it took some time to figure out that I would have to overlay the bottom or top line with alpha 0 with another set of days when going forward or backward and then animate it to 1 so that the selected day would move from being a gray rectangle (if you tap on a day that belongs to another month) to being blue.</p>
<p>For quickly switching between months you can tap and hold one of the arrows. For this I did not need any animations, so I pimped the method to set up my sheet with an animated: BOOL parameter. For regular switching this would be YES, for fast-switching it would be NO. Et voila!</p>
<p>That all worked nicely until I started to use it on device. I was asked about the performance on device, especially for fast-scrolling. I found that I could tremendously improve this by reusing the UIViews I am creating one for each day. Before my optimization all subviews to my sheet where removed from superview when they left the visible area. Since the sheet was the only view retaining them this also lead to their deallocation. Then I simply introduced an NSMutableSet to hold onto removed Views and also reuse CalendarDayViews from there. This speed things up quite a bit. R<em>euse if you can as much as you can!</em></p>
<p>Next things to do on the CalendarView control is to add a table view below it, so that I can query a data source for table view sections and rows pertaining to the currently selected date. I plan on using this in version 2 of iWoman, the first major update to my best selling app. I owe this to my customers since I did not get to update this app in over a year.</p>
<p>CalendarView will be the first of many things in my <strong><a href="http://www.cocoanetics.com/2010/01/dr-touchs-parts-store/">&#8220;Dr. Touch Parts Store&#8221;</a></strong><strong> </strong>where you can obtain high quality components to use in your own projects for a small donation. The concept is that this small amount of money pays for the time I need to continue to improve it, support it and help you with implementing it.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=1752&amp;md5=1169e513d373372dd1c6e8c82ab4c0da" 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/2009/12/reverse-engineering-the-apple-calendarview/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=1752&amp;md5=1169e513d373372dd1c6e8c82ab4c0da" type="text/html" />
	</item>
		<item>
		<title>Kernseife (SOAP for iPhone)</title>
		<link>http://www.cocoanetics.com/2009/10/kernseife-soap-for-iphone/</link>
		<comments>http://www.cocoanetics.com/2009/10/kernseife-soap-for-iphone/#comments</comments>
		<pubDate>Sat, 17 Oct 2009 19:46:42 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.drobnik.com/touch/?p=1370</guid>
		<description><![CDATA[Applyzer.com has a SOAP-based API, which is also how AppViz is getting the ranking data. I&#8217;ve been putting it off for a while, but finally I tried to find a painless way to generate proxy classes for the webservice. I failed. Well, not entirely, there IS a plethora of frameworks and toolkits that promise to automatically generate proxy classes for you. Only problem, these are either C++ based, or use libxml or use other xml parsers like are present in CoreFoundation on the Mac, but not on the iPhone. Also the code that gets generated by tools like wsdl2objc gives me the creeps. A proxy class is a class that looks like a normal class that you can instantiate and use it&#8217;s methods. But behind the scenes it packages all calls in SOAP or HTTP GET/POST, calls the server, retrieves the answer and unpackages the returning SOAP envelope. Basically you program against the web service as if the functionality offered is part of your local code. Label Buy an ad here So I started the &#8220;Kernseife&#8221; project. Originally I was tempted to call it SOUCH, like SOAP Touch, but I found this term to by synonymous with the pain of being kicked in the family jewels. Second idea was to call it CoreSOAP because it&#8217;s something that I would have expected for Apple to provide. But then I figured, how about the German translation? Core means &#8220;Kern&#8221; and Soap means &#8220;Seife&#8221; and the Soap product called &#8220;Kernseife&#8221; is synonymous with a very healthy and very thorough cleansing. Just what I had in mind for this project. Don&#8217;t tell me now that &#8220;SOAP is dead&#8221; and now everything is JSON, XML+RPC or REST. Most of the web service world around Microsoft, IBM, SUN and Java knows how to speak SOAP and since it&#8217;s the standard transport for the .NET framework based web services I run, there will be no discussion regarding SOAP&#8217;s viability. It&#8217;s there, I am going to talk with it. So far the project is able to generate proxy classes for very simple web methods: A single return value per method No complex types only string, int, double, dateTime Supported transports are SOAP 1.0, 1.2, HTTP POST and HTTP GET No error handling No SOAP exception handling Because there is still lot of work necessary to make it complete I chose to make it Open Source and created a project on Google Code. I will continue to update and improve the code as I need for my ongoing projects and I am happy to share development with anybody who has some ideas on how to do stuff even smarter. Specifically the next improvements I am looking for are: Add SOAP exception handling, possibly using NSError or objC exceptions Add complex data types by autogenerating classes or structs for them Add the conversions for the missing simple datatypes in the XML schema Unit Testing against a variety of WSDL files Documentation and Samples To get the code into your hands you can check out a working copy via Google&#8217;s instructions. If you&#8217;re interested in contributing then contact me so that I can make you a project member. When you have downloaded and built the code you get a Mac binary called Kernseife which has one parameter: a file path or URL. $ ./Kernseife http://www.drobnik.com/services/testservice.asmx?wsdl This analyzes the WSDL file and outputs a the .h/.m files for a proxy class: These ports where found: - TestServiceSoap - TestServiceSoap12 - TestServiceHttpGet - TestServiceHttpPost &#160; Writing class files for first port Done. Have a look at the header to check if all the input and output parameters could be generated: // TestService.h &#160; #import #import &#34;WebService.h&#34; &#160; #import &#34;NSString+Helpers.h&#34; #import &#34;NSDate+xml.h&#34; &#160; @interface TestService : WebService &#123; &#125; &#160; - &#40;NSString *&#41; helloWorld; - &#40;NSDate *&#41; dateInWithInDate:&#40;NSDate *&#41;inDate; - &#40;NSDate *&#41; jetzt; - &#40;double&#41; addWithOne:&#40;double&#41;one two:&#40;NSInteger&#41;two; &#160; @end Add these files to your project and also add all the files in the &#8220;xml&#8221; group of the Kernseife project. Then you should be ready to test the proxy class. // #import &#34;TestService.h&#34; &#160; TestService *service = &#91;&#91;&#91;TestService alloc&#93; init&#93; autorelease&#93;; &#160; NSDate *nun = &#91;service jetzt&#93;; NSLog&#40;@&#34;Time now from service: %@&#34;, nun&#41;; &#160; NSDate *dann = &#91;service dateInWithInDate:nun&#93;; NSLog&#40;@&#34;Pass-Through Time: %@&#34;, dann&#41;; &#160; double ret = &#91;service addWithOne:1.5 two:2&#93;; &#160; NSLog&#40;@&#34;Added double and int: %f&#34;, ret&#41;; From the initial feedback I have gotten for the basic premise of Kernseife I can tell that there is a tremendous need for such a project. So I appreciate your feedback and/or help going forward.]]></description>
			<content:encoded><![CDATA[<div class="plus-one-wrap"><g:plusone href="http://www.cocoanetics.com/2009/10/kernseife-soap-for-iphone/"></g:plusone></div><p>Applyzer.com has a SOAP-based API, which is also how AppViz is getting the ranking data. I&#8217;ve been putting it off for a while, but finally I tried to find a painless way to generate proxy classes for the webservice. I failed.</p>
<p>Well, not entirely, there IS a plethora of frameworks and toolkits that promise to automatically generate proxy classes for you. Only problem, these are either C++ based, or use libxml or use other xml parsers like are present in CoreFoundation on the Mac, but not on the iPhone. Also the code that gets generated by tools like wsdl2objc gives me the creeps.</p>
<p>A proxy class is a class that looks like a normal class that you can instantiate and use it&#8217;s methods. But behind the scenes it packages all calls in SOAP or HTTP GET/POST, calls the server, retrieves the answer and unpackages the returning SOAP envelope. Basically you program against the web service as if the functionality offered is part of your local code.</p>
<p><span id="more-1370"></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="http://www.cocoanetics.com/files/reine_kernseife.png"><img class="alignright size-full wp-image-1378" src="http://www.cocoanetics.com/files/reine_kernseife.png" alt="reine Kernseife" width="192" height="144" /></a>So I started the &#8220;Kernseife&#8221; project. Originally I was tempted to call it SOUCH, like SOAP Touch, but I found this term to by synonymous with the pain of being kicked in the family jewels. Second idea was to call it CoreSOAP because it&#8217;s something that I would have expected for Apple to provide. But then I figured, how about the German translation? Core means &#8220;Kern&#8221; and Soap means &#8220;Seife&#8221; and the Soap product called &#8220;Kernseife&#8221; is synonymous with a very healthy and very thorough cleansing. Just what I had in mind for this project.</p>
<p>Don&#8217;t tell me now that &#8220;SOAP is dead&#8221; and now everything is JSON, XML+RPC or REST. Most of the web service world around Microsoft, IBM, SUN and Java knows how to speak SOAP and since it&#8217;s the standard transport for the .NET framework based web services I run, there will be no discussion regarding SOAP&#8217;s viability. It&#8217;s there, I am going to talk with it.</p>
<p>So far the project is able to generate proxy classes for very simple web methods:</p>
<ul>
<li>A single return value per method</li>
<li>No complex types</li>
<li>only string, int, double, dateTime</li>
<li>Supported transports are SOAP 1.0, 1.2, HTTP POST and HTTP GET</li>
<li>No error handling</li>
<li>No SOAP exception handling</li>
</ul>
<p>Because there is still lot of work necessary to make it complete I chose to make it Open Source and created a <a href="http://code.google.com/p/kernseife/">project on Google Code</a>. I will continue to update and improve the code as I need for my ongoing projects and I am happy to share development with anybody who has some ideas on how to do stuff even smarter. Specifically the next improvements I am looking for are:</p>
<ul>
<li>Add SOAP exception handling, possibly using NSError or objC exceptions</li>
<li>Add complex data types by autogenerating classes or structs for them</li>
<li>Add the conversions for the missing simple datatypes in the XML schema</li>
<li>Unit Testing against a variety of WSDL files</li>
<li>Documentation and Samples</li>
</ul>
<p>To get the code into your hands you can check out a working copy via <a href="http://code.google.com/p/kernseife/source/checkout">Google&#8217;s instructions</a>. If you&#8217;re interested in contributing then contact me so that I can make you a project member.</p>
<p>When you have downloaded and built the code you get a Mac binary called Kernseife which has one parameter: a file path or URL.</p>

<div class="wp_codebox"><table><tr id="p137033"><td class="code" id="p1370code33"><pre class="objc" style="font-family:monospace;">$ .<span style="color: #002200;">/</span>Kernseife http<span style="color: #002200;">:</span><span style="color: #11740a; font-style: italic;">//www.drobnik.com/services/testservice.asmx?wsdl</span></pre></td></tr></table></div>

<p>This analyzes the WSDL file and outputs a the .h/.m files for a proxy class:</p>

<div class="wp_codebox"><table><tr id="p137034"><td class="code" id="p1370code34"><pre class="objc" style="font-family:monospace;">These ports where found<span style="color: #002200;">:</span>
<span style="color: #002200;">-</span> TestServiceSoap
<span style="color: #002200;">-</span> TestServiceSoap12
<span style="color: #002200;">-</span> TestServiceHttpGet
<span style="color: #002200;">-</span> TestServiceHttpPost
&nbsp;
Writing class files <span style="color: #a61390;">for</span> first port
Done.</pre></td></tr></table></div>

<p>Have a look at the header to check if all the input and output parameters could be generated:</p>

<div class="wp_codebox"><table><tr id="p137035"><td class="code" id="p1370code35"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// TestService.h</span>
&nbsp;
<span style="color: #6e371a;">#import</span>
<span style="color: #6e371a;">#import &quot;WebService.h&quot;</span>
&nbsp;
<span style="color: #6e371a;">#import &quot;NSString+Helpers.h&quot;</span>
<span style="color: #6e371a;">#import &quot;NSDate+xml.h&quot;</span>
&nbsp;
<span style="color: #a61390;">@interface</span> TestService <span style="color: #002200;">:</span> WebService
<span style="color: #002200;">&#123;</span>
<span style="color: #002200;">&#125;</span>
&nbsp;
<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> helloWorld;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/"><span style="color: #400080;">NSDate</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> dateInWithInDate<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/"><span style="color: #400080;">NSDate</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>inDate;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/"><span style="color: #400080;">NSDate</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span> jetzt;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">double</span><span style="color: #002200;">&#41;</span> addWithOne<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">double</span><span style="color: #002200;">&#41;</span>one two<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>NSInteger<span style="color: #002200;">&#41;</span>two;
&nbsp;
<span style="color: #a61390;">@end</span></pre></td></tr></table></div>

<p>Add these files to your project and also add all the files in the &#8220;xml&#8221; group of the Kernseife project.</p>
<p><a href="http://www.cocoanetics.com/files/KernseifeFiles.png"><img class="alignnone size-full wp-image-1374" src="http://www.cocoanetics.com/files/KernseifeFiles.png" alt="Kernseife Files" width="205" height="255" /></a></p>
<p>Then you should be ready to test the proxy class.</p>

<div class="wp_codebox"><table><tr id="p137036"><td class="code" id="p1370code36"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// #import &quot;TestService.h&quot;</span>
&nbsp;
TestService <span style="color: #002200;">*</span>service <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>TestService alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span> autorelease<span style="color: #002200;">&#93;</span>;
&nbsp;
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/"><span style="color: #400080;">NSDate</span></a> <span style="color: #002200;">*</span>nun <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>service jetzt<span style="color: #002200;">&#93;</span>;
NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Time now from service: %@&quot;</span>, nun<span style="color: #002200;">&#41;</span>;
&nbsp;
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/"><span style="color: #400080;">NSDate</span></a> <span style="color: #002200;">*</span>dann <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>service dateInWithInDate<span style="color: #002200;">:</span>nun<span style="color: #002200;">&#93;</span>;
NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Pass-Through Time: %@&quot;</span>, dann<span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #a61390;">double</span> ret <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>service addWithOne<span style="color: #002200;">:</span><span style="color: #2400d9;">1.5</span> two<span style="color: #002200;">:</span><span style="color: #2400d9;">2</span><span style="color: #002200;">&#93;</span>;
&nbsp;
NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Added double and int: %f&quot;</span>, ret<span style="color: #002200;">&#41;</span>;</pre></td></tr></table></div>

<p>From the initial feedback I have gotten for the basic premise of Kernseife I can tell that there is a tremendous need for such a project. So I appreciate your feedback and/or help going forward.</p>
 <p><a href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=1370&amp;md5=1dac221bcf80b0f5c4f3046150ef83dd" 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/2009/10/kernseife-soap-for-iphone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<atom:link rel="payment" href="http://www.cocoanetics.com/?flattrss_redirect&amp;id=1370&amp;md5=1dac221bcf80b0f5c4f3046150ef83dd" type="text/html" />
	</item>
	</channel>
</rss>

