<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>iOS Guy</title>
	<atom:link href="http://iosguy.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://iosguy.com</link>
	<description>Feel it! Enjoy it!</description>
	<lastBuildDate>Sat, 12 May 2012 03:04:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='iosguy.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/9ed4dd7659350b30096d1b7a435b02e0?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>iOS Guy</title>
		<link>http://iosguy.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://iosguy.com/osd.xml" title="iOS Guy" />
	<atom:link rel='hub' href='http://iosguy.com/?pushpress=hub'/>
		<item>
		<title>Natural Code Just Works.</title>
		<link>http://iosguy.com/2012/01/13/natural-code-just-works/</link>
		<comments>http://iosguy.com/2012/01/13/natural-code-just-works/#comments</comments>
		<pubDate>Fri, 13 Jan 2012 23:10:36 +0000</pubDate>
		<dc:creator>Cezar Augustus Signori</dc:creator>
				<category><![CDATA[Technical stuff]]></category>
		<category><![CDATA[ARC]]></category>
		<category><![CDATA[Automatic Reference Counting]]></category>
		<category><![CDATA[iOS 5]]></category>
		<category><![CDATA[Memory Handling]]></category>
		<category><![CDATA[Memory Management]]></category>
		<category><![CDATA[properties]]></category>
		<category><![CDATA[strong]]></category>
		<category><![CDATA[weak]]></category>
		<category><![CDATA[__autoreleasing]]></category>
		<category><![CDATA[__strong]]></category>
		<category><![CDATA[__unsafe_unretained]]></category>
		<category><![CDATA[__weak]]></category>

		<guid isPermaLink="false">http://iosguy.com/?p=230</guid>
		<description><![CDATA[As soon as I heard about ARC I thought &#8220;WOW, this is amazing! A compiler-time garbage collector! Why didn&#8217;t anyone think about this before!?&#8221;. But then even after migrating to iOS 5 I got a little scared about changing the compiler and the whole memory management schema that I have been using my entire life. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=230&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">As soon as I heard about ARC I thought &#8220;WOW, this is amazing! A compiler-time garbage collector! Why didn&#8217;t anyone think about this before!?&#8221;.</p>
<p style="text-align:justify;">But then even after migrating to iOS 5 I got a little scared about changing the compiler and the whole memory management schema that I have been using my entire life.   Actually I was waiting to being able to work on a new project so that I could start using these new concepts. It turns out I couldn&#8217;t wait anymore and decided to migrate this huge project I am working on to ARC. Not only for the promise of &#8220;running faster&#8221;, but also for education (in the end I love to explore and learn new ways of writing code).</p>
<p style="text-align:justify;">After migrating the source code by using the automatic migration tool provided by Xcode 4.2.1 (and set the Simulator as deployment target hahahah) I was immediately able to see that <strong>natural code just works</strong>. That is the way Apple wants us to think about using ARC. And my impression tells me this is totally possible.</p>
<p style="text-align:justify;">But I am a man full of questions about the meaning of life and all this crap, so I couldn&#8217;t just believe on that and started to watch some ARC talks Apple has done to comprehend how this magic works behind the scenes. Truth is I can&#8217;t live with something I don&#8217;t understand when it comes to coding.</p>
<p style="text-align:justify;">Although ARC is pretty simple, here are some annotations I have made that really helped me to understand &#8220;da magic&#8221;.</p>
<p style="text-align:justify;">First of all there are 5 things you cannot forget:</p>
<p style="text-align:justify;">1) <strong>Strong references.</strong> Every variable is a strong reference and is implicit released after it&#8217;s scope ends. A strong reference is the same thing as a retained reference that you don&#8217;t manage. For example:</p>
<p style="text-align:justify;">When you declare <em>NSString *name;</em> the compiler understands you actually meant <em>__strong NSString *name;</em>. And this means you don&#8217;t need to retain the reference nor release it afterwards anymore.</p>
<pre><code>- (<span style="color:#993366;">id</span>)<span style="color:#333399;">init</span> { </code></pre>
<pre style="padding-left:30px;"><code><span style="color:#993366;">self</span> = [<span style="color:#993366;">super</span> <span style="color:#333399;">init</span>]; </code></pre>
<pre style="padding-left:30px;"><code><span style="color:#993366;">if</span> (<span style="color:#993366;">self</span>) { </code></pre>
<pre style="padding-left:60px;"><code>name = [<span style="color:#993366;">@"Name"</span> <span style="color:#333399;">retain</span>]; </code></pre>
<pre style="padding-left:30px;"><code>}</code></pre>
<p style="padding-left:30px;"><code><span style="color:#993366;">return</span> <span style="color:#993366;">self</span>;</code></p>
<p><code></code><code>}</code></p>
<pre><code>- (<span style="color:#993366;">void</span>)<span style="color:#333399;">dealloc</span> { </code></pre>
<pre style="padding-left:30px;"><code></code><code>[name <span style="color:#333399;">release</span>]; </code></pre>
<pre style="padding-left:30px;"><code>[<span style="color:#993366;">super</span> <span style="color:#333399;">dealloc</span>];</code></pre>
<p>}</p>
<p>becomes</p>
<pre><code>- (<span style="color:#993366;">id</span>)<span style="color:#333399;">init</span> { </code></pre>
<pre style="padding-left:30px;"><code><span style="color:#993366;">self</span> = [<span style="color:#993366;">super</span> <span style="color:#333399;">init</span>]; </code></pre>
<pre style="padding-left:30px;"><code><span style="color:#993366;">if</span> (<span style="color:#993366;">self</span>) { </code></pre>
<pre style="padding-left:60px;"><code>name = <span style="color:#993366;">@"Name"</span>; </code></pre>
<pre style="padding-left:30px;"><code>} </code></pre>
<pre style="padding-left:30px;"><code><span style="color:#993366;">return self</span>;</code></pre>
<p>}</p>
<p style="text-align:justify;">2) <strong>Autoreleasing References.</strong> Every out-parameter is already retained and autoreleased for you.</p>
<pre><code>- (<span style="color:#993366;">void</span>)<span style="color:#333399;">method</span>: (<span style="color:#333399;">NSObject</span> **)param { *param = …; } </code></pre>
<p>means</p>
<pre><code>- (<span style="color:#993366;">void</span>)method: (<span style="color:#993300;">__autoreleasing</span> <span style="color:#333399;">NSObject</span> **)param { </code></pre>
<p style="padding-left:30px;"><code>*param = … <span style="color:#333399;">retain</span>] <span style="color:#333399;">autorelease</span>];<br />
</code></p>
<p><code>}</code></p>
<p style="text-align:justify;">3) <strong>Unsafe references.</strong> If you see this, keep in mind you are working with a non-initialized, no-extra compiler logic and no restrictions variable. An unsafe reference tells ARC not to touch it and as a result what you get is the same as an <strong>assign property</strong>. The advantage here is: <em>you can use this inside structs</em>. But be warned this can easily dangling references.</p>
<pre><code><span style="color:#993300;"> __unsafe_unretained</span> <span style="color:#333399;">NSString</span> *name = name; </code></pre>
<p style="text-align:justify;">4) <strong>Weak References. </strong>Works like an assign property, <em>but becomes nil as soon as the object starts deallocation</em>.</p>
<pre><code><span style="color:#993300;"> __weak</span> <span style="color:#333399;">NSString</span> *name = name; </code></pre>
<p style="text-align:justify;">If you want to create a reference weak, just add <em>__weak</em> before the variable declaration or <em>weak</em> to the property instead of the old assign parameter.</p>
<p style="text-align:justify;">5) <strong>Return Values.</strong> They never transfer ownership (ARC does a retain and returns a autoreleased object for you) unless the selector starts with alloc, copy, init, mutableCopy or new. In these cases ARC returns a +1 reference (for you), which you also don&#8217;t need to bother with on the caller side due to the rules we discussed above.</p>
<p style="text-align:justify;">Now that you know how ARC works and what it does, you can write natural code in peace =)</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/iosguy.wordpress.com/230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/iosguy.wordpress.com/230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/iosguy.wordpress.com/230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/iosguy.wordpress.com/230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/iosguy.wordpress.com/230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/iosguy.wordpress.com/230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/iosguy.wordpress.com/230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/iosguy.wordpress.com/230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/iosguy.wordpress.com/230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/iosguy.wordpress.com/230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/iosguy.wordpress.com/230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/iosguy.wordpress.com/230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/iosguy.wordpress.com/230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/iosguy.wordpress.com/230/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=230&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://iosguy.com/2012/01/13/natural-code-just-works/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e2caa8fb0f5104c13fcc1dea0bd66d0e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cezarsignori</media:title>
		</media:content>
	</item>
		<item>
		<title>Multiple Video Playback on iOS</title>
		<link>http://iosguy.com/2012/01/11/multiple-video-playback-on-ios/</link>
		<comments>http://iosguy.com/2012/01/11/multiple-video-playback-on-ios/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 19:25:47 +0000</pubDate>
		<dc:creator>Cezar Augustus Signori</dc:creator>
				<category><![CDATA[Technical stuff]]></category>
		<category><![CDATA[AVAsset]]></category>
		<category><![CDATA[AVFoundation]]></category>
		<category><![CDATA[AVPlayer]]></category>
		<category><![CDATA[AVPlayerItem]]></category>
		<category><![CDATA[AVPlayerLayer]]></category>
		<category><![CDATA[MediaPlayer]]></category>
		<category><![CDATA[MPMoviePlayerController]]></category>
		<category><![CDATA[Multiple Video Playback]]></category>
		<category><![CDATA[Video Playback]]></category>

		<guid isPermaLink="false">http://iosguy.com/?p=210</guid>
		<description><![CDATA[As usual let me start by telling you a quick story on how this post came to be&#8230; Once upon a time..NOT. So, I was working on this project for Hyundai at nKey when we got into this screen that requires two videos playing at the same time so the user could see how a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=210&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">As usual let me start by telling you a quick story on how this post came to be&#8230;</p>
<p style="text-align:justify;">Once upon a time..NOT. So, I was working on this project for Hyundai at <a title="nKey's Web Site" href="http://www.nkey.com.br">nKey</a> when we got into this screen that requires two videos playing at the same time so the user could see how a car would behave with and without a feature (like Electronic Stability Control). As an experienced developer I immediately told the customer we should merge both videos so that we could play &#8220;both at the same time&#8221; in iOS. I explained him that in order to play videos on iOS, Apple has released a long time ago the MediaPlayer.framework which <a title="MPMoviePlayerController Class Reference" href="http://developer.apple.com/library/ios/#documentation/mediaplayer/reference/MPMoviePlayerController_Class/Reference/Reference.html">according to the docs</a> (and real life <img src='http://s2.wp.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> ) isn&#8217;t able to handle more than one video playback at a time (although you can have two <em>MPMoviePlayerController</em> instances).</p>
<p style="text-align:justify;">He said OK and that was what we did. However the requirements changed and we had to add a background video that plays on a loop..aaand I started to have problems coordinating all these video playbacks so that only one was playing at a time and the user wouldn&#8217;t notice it.</p>
<p style="text-align:justify;">Fortunately <a title="nKey's Web Site" href="http://www.nkey.com.br">nKey</a> sent me to the <a title="iOS Tech Talk" href="http://developer.apple.com/techtalk/">iOS Tech Talk</a> that was happening on São Paulo/BR this very monday and there I got into a talk where the <a title="Eryk's LinkedIn Profile" href="http://www.linkedin.com/pub/eryk-vershen/0/a54/668">Media Technologies Evangelist, Eryk Vershen</a> was discussing the <a title="About the AV Foundation Framework" href="http://developer.apple.com/library/IOs/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/00_Introduction.html#//apple_ref/doc/uid/TP40010188">AVFoundation.framework</a> and how it is used by the MediaPlayer.framework (aka <em>MPMoviePlayerController</em>) for video playback. After the talk during Wine and Cheese I got to speak to Eryk about my issue and explained him how I was thinking about handling the problem. His answer was something like <em>&#8220;Sure! Go for it! iOS surely is capable of playing multiple videos at the same time!&#8230;Oh&#8230;and I think something around 4 is the limit&#8221;</em>. That answer made me happy and curious so I asked him why is the MediaPlayer.framework incapable of handling multiple video playback if that wasn&#8217;t a library limitation&#8230;he told me the <em>MPMoviePlayerController</em> was created to present cut-scenes on games early on&#8230;that this is why on previous iOS versions only fullscreen playback was allowed and that this limitation is a matter of legacy.</p>
<p style="text-align:justify;">When I got back to my notebook I worked on this very basic version of a video player using the AVFoundation.framework (which obviously I made more robust when I got back to the office so that we could use it on the project).</p>
<p style="text-align:justify;">Okdq, story told. Let&#8217;s get back to work!</p>
<p style="text-align:justify;">The AVFoundation framework provides you the AVPlayer object to implement controllers and user interfaces for single- or multiple-item playback. The visual results generated by the AVPlayer object can be displayed  in a CoreAnimation layer of class AVPlayerLayer. In AVFoundation timed audiovisual media such as videos and sounds are represented by an AVAsset object. According to <a title="Using AVAssets" href="http://developer.apple.com/library/IOs/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/01_UsingAssets.html#//apple_ref/doc/uid/TP40010188-CH7-SW1">the docs</a>, each asset contains a collection of tracks that are intended to be presented or processed together, each of a uniform media type, including but not limited to audio, video, text, closed captions, and subtitles. Due to the nature of timed audiovisual media, upon successful initialization of an asset some or all of the values for its keys may not be immediately available. In order to avoid blocking the main thread, you can register your interest in particular keys and become notified when their values are available.</p>
<p style="text-align:justify;">Having this in mind, subclass UIViewController and name this class VideoPlayerViewController. Just like the MPMoviePlayerController, let&#8217;s add a NSURL property that tells us from where we should grab our video. Like described above, add the following code to load the AVAsset once the URL is set.</p>
<pre><span style="color:#993300;"><code> #pragma mark - Public methods </code></span> 
 - (<span style="color:#800080;">void</span>)setURL:(<span style="color:#0000ff;">NSURL</span>*)URL {
      [<span style="color:#800080;">_URL</span> <span style="color:#0000ff;">release</span>];
      <span style="color:#800080;">_URL</span> = [URL <span style="color:#0000ff;">copy</span>];
      <span style="color:#0000ff;">AVURLAsset</span> *asset = [<span style="color:#0000ff;">AVURLAsset</span> <span style="color:#0000ff;">URLAssetWithURL</span>:_URL <span style="color:#0000ff;">options</span>:<span style="color:#800080;">nil</span>];
      <span style="color:#0000ff;">NSArray</span> *requestedKeys = [<span style="color:#0000ff;">NSArray</span> <span style="color:#0000ff;">arrayWithObjects</span>:kTracksKey,
                <span style="color:#800080;">kPlayableKey</span>, <span style="color:#800080;">nil</span>];
      [asset <span style="color:#0000ff;">loadValuesAsynchronouslyForKeys</span>:requestedKeys
                           <span style="color:#0000ff;">completionHandler</span>: ^{ <span style="color:#800080;">dispatch_async</span>(
                                    <span style="color:#800080;">dispatch_get_main_queue</span>(), ^{
                                 [<span style="color:#800080;">self</span> <span style="color:#0000ff;">prepareToPlayAsset</span>:asset
<span style="color:#0000ff;"> withKeys</span>:requestedKeys];
                           });
      }];
} 
- (<span style="color:#0000ff;">NSURL</span>*)URL {
      return <span style="color:#800080;">_URL</span>;
}</pre>
<p style="text-align:justify;">So, once the URL for the video is set we create an asset to inspect the resource referenced by the given URL and asynchronously load up the values for the asset keys &#8220;tracks&#8221; and &#8220;playable&#8221;. At loading completion we can operate on the AVPlayer on the main queue (the main queue is used to naturally ensure safe access to a player’s nonatomic properties while dynamic changes in playback state may be reported).</p>
<pre><span style="color:#993300;"><code> #pragma mark - Private methods </code></span>
<code>- (<span style="color:#800080;">void</span>)<span style="color:#0000ff;">prepareToPlayAsset</span>: (<span style="color:#0000ff;">AVURLAsset</span> *)asset <span style="color:#0000ff;">withKeys</span>: </code>
<code> (<span style="color:#0000ff;">NSArray</span> *)requestedKeys { </code>
     <span style="color:#800080;">for</span> (<span style="color:#0000ff;">NSString</span> *thisKey in requestedKeys) { 
        <span style="color:#0000ff;">NSError</span> *error = <span style="color:#800080;">nil</span>;  
        <span style="color:#0000ff;">AVKeyValueStatus</span> keyStatus = [asset  
             <span style="color:#0000ff;">statusOfValueForKey:thisKey</span>
                           <span style="color:#0000ff;">error</span>:<span style="color:#800080;">&amp;error</span>];  
        <span style="color:#800080;">if</span> (keyStatus == <span style="color:#800080;">AVKeyValueStatusFailed</span>) {  
           <span style="color:#800080;">return</span>;
        } 
     }
<span style="color:#800080;"> if</span> (!asset.playable) {
           <span style="color:#800080;">return</span>;
      }
      <span style="color:#800080;">if</span> (<span style="color:#800080;">self</span>.playerItem) {
          [<span style="color:#800080;">self.</span>playerItem <span style="color:#0000ff;">removeObserver</span>:<span style="color:#800080;">self</span> <span style="color:#0000ff;">forKeyPath</span>:<span style="color:#800080;">kStatusKey</span>];
          [[<span style="color:#0000ff;">NSNotificationCenter defaultCenter</span>] <span style="color:#0000ff;">removeObserver</span>:<span style="color:#800080;">self</span> 
                   <span style="color:#0000ff;">name</span>:<span style="color:#800080;">AVPlayerItemDidPlayToEndTimeNotification</span>
                 <span style="color:#0000ff;">object</span>:<span style="color:#800080;">self</span>.playerItem];
      }
      <span style="color:#800080;">self</span>.playerItem = [<span style="color:#0000ff;">AVPlayerItem</span> <span style="color:#0000ff;">playerItemWithAsset</span>:asset];
      [<span style="color:#800080;">self</span>.playerItem <span style="color:#0000ff;">addObserver:</span><span style="color:#800080;">self</span> <span style="color:#0000ff;">forKeyPath</span>:<span style="color:#800080;">kStatusKey</span> 
              <span style="color:#0000ff;">options</span>:<span style="color:#800080;">NSKeyValueObservingOptionInitial</span> |
                      <span style="color:#800080;">NSKeyValueObservingOptionNew</span>
              <span style="color:#0000ff;">context</span>:
           <span style="color:#800080;">AVPlayerDemoPlaybackViewControllerStatusObservationContext</span>];
      if (![<span style="color:#800080;">self</span> <span style="color:#0000ff;">player</span>]) {
            [<span style="color:#800080;">self</span> <span style="color:#0000ff;">setPlayer</span>:[<span style="color:#0000ff;">AVPlayer</span> <span style="color:#0000ff;">playerWithPlayerItem</span>:<span style="color:#800080;">self</span>.playerItem]];
            [<span style="color:#800080;">self.</span>player <span style="color:#0000ff;">addObserver</span>:<span style="color:#800080;">self</span> <span style="color:#0000ff;">forKeyPath</span>:<span style="color:#800080;">kCurrentItemKey</span> 
                  <span style="color:#0000ff;">options</span>:<span style="color:#800080;">NSKeyValueObservingOptionInitial</span> |
                          <span style="color:#800080;">NSKeyValueObservingOptionNew</span>
                  <span style="color:#0000ff;">context</span>:
             <span style="color:#800080;">AVPlayerDemoPlaybackViewControllerCurrentItemObservationContext</span>];
      }
      if (<span style="color:#800080;">self</span>.player.currentItem != <span style="color:#800080;">self</span>.playerItem) {
             [[<span style="color:#800080;">self</span> <span style="color:#0000ff;">player</span>] <span style="color:#0000ff;">replaceCurrentItemWithPlayerItem</span>:<span style="color:#800080;">self</span>.playerItem];
      }
}</pre>
<p style="text-align:justify;">At the completion of the loading of the values for all keys on the asset that we require, we check whether loading was successfull and whether the asset is playable. If so, we set up an AVPlayerItem (representation of the presentation state of an asset that’s played by an AVPlayer object) and an AVPlayer to play the asset. Note that I didn&#8217;t add any error handling at this point. Here we should probably create a delegate and let the view controller or whoever is using your player to decide what is the best way to handle the possible errors.</p>
<p style="text-align:justify;">Also we added some key-value observers so that we are notified when our view should be tied to the player and when the the AVPlayerItem is ready to play.<br />
<code></code></p>
<pre><span style="color:#993300;">#pragma mark - Key Valye Observing</span>

- (<span style="color:#800080;">void</span>)<span style="color:#0000ff;">observeValueForKeyPath</span>: (<span style="color:#0000ff;">NSString</span>*) path
                      <span style="color:#0000ff;">ofObject</span>: (<span style="color:#800080;">id</span>)object
                        <span style="color:#0000ff;">change</span>: (<span style="color:#0000ff;">NSDictionary</span>*)change
                       <span style="color:#0000ff;">context</span>: (<span style="color:#800080;">void</span>*)context {
	<span style="color:#800080;">if</span> (context == <span style="color:#800080;">AVPlayerDemoPlaybackViewControllerStatusObservation</span>
             <span style="color:#0000ff;">Context</span>) {
              <span style="color:#0000ff;">AVPlayerStatus</span> status = [[change <span style="color:#0000ff;">objectForKey</span>:
                <span style="color:#800080;">NSKeyValueChangeNewKey</span>] <span style="color:#0000ff;">integerValue</span>];
              <span style="color:#800080;">if</span> (status == <span style="color:#800080;">AVPlayerStatusReadyToPlay</span>) {
                   [<span style="color:#800080;">self</span>.player <span style="color:#0000ff;">play</span>];
              }
	} <span style="color:#800080;">else if</span> (context == <span style="color:#800080;">AVPlayerDemoPlaybackViewControllerCurrentItem</span>
             <span style="color:#800080;">ObservationContext</span>) {
              <span style="color:#0000ff;">AVPlayerItem</span> *newPlayerItem = [change <span style="color:#0000ff;">objectForKey</span>:
                 <span style="color:#800080;">NSKeyValueChangeNewKey</span>];

              if (newPlayerItem) {
                  [<span style="color:#800080;">self</span>.playerView <span style="color:#0000ff;">setPlayer</span>:<span style="color:#800080;">self</span>.player];
                  [<span style="color:#800080;">self</span>.playerView <span style="color:#0000ff;">setVideoFillMode</span>:
                      <span style="color:#800080;">AVLayerVideoGravityResizeAspect</span>];
              }
	} <span style="color:#800080;">else</span> {
		[<span style="color:#800080;">super</span> <span style="color:#0000ff;">observeValueForKeyPath</span>:path <span style="color:#0000ff;">ofObject</span>: object
                    <span style="color:#0000ff;">change</span>:change <span style="color:#0000ff;">context</span>:context];
	}
}</pre>
<p style="text-align:justify;">Once the AVPlayerItem is on place we are free to attach the AVPlayer to the player layer that displays visual output. We also make sure to preserve the video’s aspect ratio and fit the video within the layer’s bounds.</p>
<p style="text-align:justify;">As soon as the AVPlayer is ready, we command it to play! iOS does the hard work <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p style="text-align:justify;">As I mentioned earlier, to play the visual component of an asset, you need a view containing an AVPlayerLayer layer to which the output of an AVPlayer object can be directed. This is how you subclass a UIView to meet the requirements:<br />
<code></code></p>
<pre><span style="color:#800080;">@implementation</span> VideoPlayerView

+ (<span style="color:#0000ff;">Class</span>)<span style="color:#0000ff;">layerClass</span> {
	<span style="color:#800080;">return</span> [<span style="color:#0000ff;">AVPlayerLayer</span> <span style="color:#800080;">class</span>];
}

- (<span style="color:#0000ff;">AVPlayer</span>*)player {
	<span style="color:#800080;">return</span> [(<span style="color:#0000ff;">AVPlayerLayer</span>*)[<span style="color:#800080;">self</span> <span style="color:#0000ff;">layer</span>] <span style="color:#0000ff;">player</span>];
}

- (<span style="color:#800080;">void</span>)<span style="color:#0000ff;">setPlayer</span>: (<span style="color:#0000ff;">AVPlayer</span>*)player {
	[(<span style="color:#0000ff;">AVPlayerLayer</span>*)[<span style="color:#800080;">self</span> <span style="color:#0000ff;">layer</span>] <span style="color:#0000ff;">setPlayer</span>:player];
}

- (<span style="color:#800080;">void</span>)<span style="color:#0000ff;">setVideoFillMode</span>: (<span style="color:#0000ff;">NSString</span> *)fillMode {
	<span style="color:#0000ff;">AVPlayerLayer</span> *playerLayer = (<span style="color:#0000ff;">AVPlayerLayer</span>*)[<span style="color:#800080;">self</span> <span style="color:#0000ff;">layer</span>];
	playerLayer.videoGravity = fillMode;
}

<span style="color:#800080;">@end</span></pre>
<p style="text-align:justify;">And this is it!</p>
<p style="text-align:justify;">Of course I didn&#8217;t add all the necessary code for building and running the project but I wouldn&#8217;t let you down! <a title="MyVideoPlayer" href="https://github.com/cezarsignori/MyVideoPlayer">Go to GitHub and download the full source code!</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/iosguy.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/iosguy.wordpress.com/210/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/iosguy.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/iosguy.wordpress.com/210/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/iosguy.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/iosguy.wordpress.com/210/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/iosguy.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/iosguy.wordpress.com/210/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/iosguy.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/iosguy.wordpress.com/210/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/iosguy.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/iosguy.wordpress.com/210/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/iosguy.wordpress.com/210/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/iosguy.wordpress.com/210/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=210&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://iosguy.com/2012/01/11/multiple-video-playback-on-ios/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e2caa8fb0f5104c13fcc1dea0bd66d0e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cezarsignori</media:title>
		</media:content>
	</item>
		<item>
		<title>3D Tag Cloud available on GitHub!</title>
		<link>http://iosguy.com/2011/11/26/3d-tag-cloud-available-on-github/</link>
		<comments>http://iosguy.com/2011/11/26/3d-tag-cloud-available-on-github/#comments</comments>
		<pubDate>Sun, 27 Nov 2011 01:32:14 +0000</pubDate>
		<dc:creator>Cezar Augustus Signori</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[3D Sphere]]></category>
		<category><![CDATA[3D Tag Cloud]]></category>
		<category><![CDATA[Free Software]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[GNUv3]]></category>
		<category><![CDATA[iOs]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[SphereView]]></category>

		<guid isPermaLink="false">http://iosguy.com/?p=207</guid>
		<description><![CDATA[Hey guys! This time I bring very good news! The 3D Tag Cloud I created almost a year ago is finally a free software available on GitHub. Yes, that is right. A lot of people is asking for some code sample after reading that tutorial so I decided to just make it available on GitHub [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=207&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Hey guys!</p>
<p>This time I bring very good news! The <a title="Creating a 3D Tag Cloud" href="http://iosguy.com/2010/11/17/creating-a-3d-tag-cloud/">3D Tag Cloud</a> I created almost a year ago is finally a free software <a title="SphereView" href="https://github.com/cezarsignori/SphereView/">available on GitHub</a>.</p>
<p>Yes, that is right. A lot of people is asking for some code sample after reading <a title="Creating a 3D Tag Cloud" href="http://iosguy.com/2010/11/17/creating-a-3d-tag-cloud/">that tutorial</a> so I decided to just make it available on GitHub as a free software under the terms of <a href="http://www.gnu.org/licenses/gpl-3.0.html">GNU General Public License version 3</a>, so that you guys can use, redistribute or modify it at will.</p>
<p>Now it is your turn! Contribute!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/iosguy.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/iosguy.wordpress.com/207/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/iosguy.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/iosguy.wordpress.com/207/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/iosguy.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/iosguy.wordpress.com/207/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/iosguy.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/iosguy.wordpress.com/207/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/iosguy.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/iosguy.wordpress.com/207/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/iosguy.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/iosguy.wordpress.com/207/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/iosguy.wordpress.com/207/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/iosguy.wordpress.com/207/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=207&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://iosguy.com/2011/11/26/3d-tag-cloud-available-on-github/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e2caa8fb0f5104c13fcc1dea0bd66d0e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cezarsignori</media:title>
		</media:content>
	</item>
		<item>
		<title>SECCOM 2011: Introduction to iPhone Development</title>
		<link>http://iosguy.com/2011/10/17/seccom-2011-introduction-to-iphone-development/</link>
		<comments>http://iosguy.com/2011/10/17/seccom-2011-introduction-to-iphone-development/#comments</comments>
		<pubDate>Mon, 17 Oct 2011 17:35:01 +0000</pubDate>
		<dc:creator>Cezar Augustus Signori</dc:creator>
				<category><![CDATA[Technical stuff]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[QR code]]></category>
		<category><![CDATA[SECCOM 2011]]></category>
		<category><![CDATA[ZBar]]></category>

		<guid isPermaLink="false">http://iosguy.com/?p=198</guid>
		<description><![CDATA[Hey! So, this year is the second time I am talking about cool stuff at SECCOM. Only this time it is about even cooler stuff: iPhone! SECCOM is a great event that becomes more amazing every year. Actually it is a week where a bunch of people comes to UFSC (Universidade Federal de Santa Catarina) [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=198&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">Hey!</p>
<p style="text-align:justify;">So, this year is the second time I am talking about cool stuff at <a title="SECCOM" href="http://www.pet.inf.ufsc.br/seccom/">SECCOM</a>. Only this time it is about even cooler stuff: iPhone!</p>
<p style="text-align:justify;"><a title="SECCOM" href="http://www.pet.inf.ufsc.br/seccom/">SECCOM</a> is a great event that becomes more amazing every year. Actually it is a week where a bunch of people comes to <a title="UFSC" href="http://www.linkedin.com/company/17959?trk=pro_other_cmpy">UFSC (Universidade Federal de Santa Catarina)</a> to share ideas regarding technology. This year it counts with discussions regarding quality of software, embedded software, databases, arduino, android, windows phone 7, iPhone and much more.</p>
<p style="text-align:justify;">My talk is about iPhone Development, actually it is more like an introduction. The idea is to tell people how they can get started into the iOS world. I am covering very basic topics like what is the cost, which are the tools and what iPhone is all about. Of course it wouldn&#8217;t be a good talk for beginners if it doesn&#8217;t had a cool demo. So the demo I chose shows how to do a very basic use of UITableView and the <a title="Download ZBAR" href="http://sourceforge.net/projects/zbar/files/iPhoneSDK/ZBarSDK-1.2.dmg/download">ZBar library</a> for scanning <a title="QR code generator" href="http://qrcode.kaywa.com/">QR codes</a>.</p>
<p style="text-align:justify;">If you watched the presentation and wants the material or couldn&#8217;t go, but would like it as well, I have good news: <a title="Presentation Material" href="http://dl.dropbox.com/u/11108747/SECCOM.zip">It is all available here</a>. Oh, and one more thing: Since the talk is happing in Brazil the presentation is in Portuguese, but I took the care to translate it to English so that you guys could also enjoy!</p>
<p style="text-align:justify;">Thank you!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/iosguy.wordpress.com/198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/iosguy.wordpress.com/198/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/iosguy.wordpress.com/198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/iosguy.wordpress.com/198/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/iosguy.wordpress.com/198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/iosguy.wordpress.com/198/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/iosguy.wordpress.com/198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/iosguy.wordpress.com/198/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/iosguy.wordpress.com/198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/iosguy.wordpress.com/198/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/iosguy.wordpress.com/198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/iosguy.wordpress.com/198/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/iosguy.wordpress.com/198/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/iosguy.wordpress.com/198/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=198&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://iosguy.com/2011/10/17/seccom-2011-introduction-to-iphone-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e2caa8fb0f5104c13fcc1dea0bd66d0e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cezarsignori</media:title>
		</media:content>
	</item>
		<item>
		<title>Anti-aliasing rotated UIViews</title>
		<link>http://iosguy.com/2011/10/01/anti-aliasing-rotated-uiviews/</link>
		<comments>http://iosguy.com/2011/10/01/anti-aliasing-rotated-uiviews/#comments</comments>
		<pubDate>Sat, 01 Oct 2011 17:21:06 +0000</pubDate>
		<dc:creator>Cezar Augustus Signori</dc:creator>
				<category><![CDATA[Technical stuff]]></category>
		<category><![CDATA[<]]></category>

		<guid isPermaLink="false">http://iosguy.com/?p=190</guid>
		<description><![CDATA[It is being a lot of time I don&#8217;t add a new post here, so here I am with a pretty quick post. This history begins half year ago, when I worked on the Chatter app for iPad with my dear friend Didier Prophete. I worked on an anti-aliasing solution for a rotated image that [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=190&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">It is being a lot of time I don&#8217;t add a new post here, so here I am with a pretty quick post.</p>
<p style="text-align:justify;">This history begins half year ago, when I worked on the <a title="iTunes Store Link" href="http://itunes.apple.com/br/app/salesforce-chatter-for-ipad/id407657655?mt=8">Chatter app for iPad</a> with my dear friend <a title="Didier's Twitter" href="http://twitter.com/#!/dprophete">Didier Prophete</a>. I worked on an anti-aliasing solution for a rotated image that I was pretty eager to publish but I couldn&#8217;t do it at the time.</p>
<p style="text-align:justify;">Yesterday I was working on a Pinch Spread component (yes, just like Chatter does but without the pan part and for a different reason) at <a title="nKey's Web Site" href="http://www.nkey.com.br/">nKey</a> for using on <a title="nKey's Portfolio" href="http://www.nkey.com.br/portfolio/">some of our apps</a>, and I needed to use that old solution but I couldn&#8217;t remember it, so I had to come up with a simpler one since I was on a run due to other matters.</p>
<p style="text-align:justify;">Going (finally) straight to the point, when you rotate an UIView it&#8217;s borders become serrated so that you need to anti-alias them in order to look good.</p>
<p style="text-align:justify;">So my solution was to use a container view 5 pixels wider in order to reduce the serrated effect on the view I wanted to rotate &#8211; of course, you have to center the view on the container and then rotate the container view instead.</p>
<p style="text-align:justify;">The next step is to add a 3 pixel transparent border to the inner view and rasterize it so that the pixels interpolate smoothing the border.</p>
<pre><code>view.<span style="color:#333399;">layer</span>.<span style="color:#333399;">borderWidth</span> = <span style="color:#993300;">3</span>; </code>
<code>view.<span style="color:#333399;">layer</span>.<span style="color:#333399;">borderColor</span> = </code><span class="Apple-style-span" style="font-family:monospace;">[<span style="color:#333399;">UIColor</span> <span style="color:#333399;">clearColor</span>].<span style="color:#333399;">CGColor</span>; </span>
<code>view.<span style="color:#333399;">layer</span>.<span style="color:#333399;">shouldRasterize</span> = <span style="color:#993300;">YES</span>; </code></pre>
<p style="text-align:justify;">Now the final trick is to add some shadow. This will make the border look somehow more solid. In my case I added a lot of shadow because I wanted the shadow to be very visible (the view stack for the Pinch Spread looks sharper and prettier due to the shadow effect).</p>
<pre><code> view.<span style="color:#333399;">layer</span>.<span style="color:#333399;">shadowOffset</span> = <span style="color:#333399;">CGSizeMake</span>(<span style="color:#993300;">0</span>, <span style="color:#993300;">-1</span>); </code>
<code> view.<span style="color:#333399;">layer</span>.<span style="color:#333399;">shadowOpacity</span> = <span style="color:#993300;">1</span>; </code>
<code> view.<span style="color:#333399;">layer</span>.<span style="color:#333399;">shadowColor</span> = [<span style="color:#333399;">UIColor</span> <span style="color:#333399;">blackColor</span>].<span style="color:#333399;">CGColor</span>; </code></pre>
<p>So, by using the solution above this is what you will get:</p>
<p><a href="http://iosguy.files.wordpress.com/2011/10/sharpborders.png"><img class="aligncenter size-full wp-image-191" title="SharpBorders" src="http://iosguy.files.wordpress.com/2011/10/sharpborders.png?w=480" alt="pinch spreading sharp views"   /></a></p>
<p>Although it is a pretty obvious and simple solution, I hope it helps you out (and now I have a reminder for the next time!).</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/iosguy.wordpress.com/190/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/iosguy.wordpress.com/190/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/iosguy.wordpress.com/190/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/iosguy.wordpress.com/190/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/iosguy.wordpress.com/190/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/iosguy.wordpress.com/190/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/iosguy.wordpress.com/190/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/iosguy.wordpress.com/190/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/iosguy.wordpress.com/190/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/iosguy.wordpress.com/190/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/iosguy.wordpress.com/190/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/iosguy.wordpress.com/190/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/iosguy.wordpress.com/190/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/iosguy.wordpress.com/190/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=190&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://iosguy.com/2011/10/01/anti-aliasing-rotated-uiviews/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e2caa8fb0f5104c13fcc1dea0bd66d0e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cezarsignori</media:title>
		</media:content>

		<media:content url="http://iosguy.files.wordpress.com/2011/10/sharpborders.png" medium="image">
			<media:title type="html">SharpBorders</media:title>
		</media:content>
	</item>
		<item>
		<title>Creating a 3D Tag Cloud</title>
		<link>http://iosguy.com/2010/11/17/creating-a-3d-tag-cloud/</link>
		<comments>http://iosguy.com/2010/11/17/creating-a-3d-tag-cloud/#comments</comments>
		<pubDate>Thu, 18 Nov 2010 06:49:37 +0000</pubDate>
		<dc:creator>Cezar Augustus Signori</dc:creator>
				<category><![CDATA[Technical stuff]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[iOs]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Rotation]]></category>
		<category><![CDATA[Sphere]]></category>
		<category><![CDATA[Tag Cloud]]></category>
		<category><![CDATA[Transformation]]></category>

		<guid isPermaLink="false">http://iosguy.com/?p=162</guid>
		<description><![CDATA[I was bored last weekend, so I decided to do something slightly different. The first idea that came to my mind was a 3D sphere on which I could place any kind of view. Truth is that there is nothing better than a clear idea of what you want to do in order to achieve [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=162&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">I was bored last weekend, so I decided to do something slightly different. The first idea that came to my mind was a 3D sphere on which I could place any kind of view. Truth is that there is nothing better than a clear idea of what you want to do in order to achieve your goals. So, why not a Tag Cloud? It is simple, and at a very basic understanding, it is nothing more than a bunch of views distributed on a sphere.</p>
<p style="text-align:justify;">Since I wanted to create it without using OpenGL ES, I took a moment to think about what would be the best way to implement this stuff using just the UIKit.</p>
<p style="text-align:justify;">After not that much of thinking, I decided to evenly distribute points on a sphere and use these points as the center of each view. Obviously UIKit just works with 2 dimentions, so how to achieve the 3D aspect? Simple, let&#8217;s use the Z coordinate as the scale factor. But still, there would be smaller views (views that should be far from the screen) overlaying bigger views (the ones closer to the screen). This can be easily solved via z-index ordering (that is available in the standard SDK).</p>
<p style="text-align:justify;">There will be no fun if we are not able to at least rotate our 3D Tag Cloud around every axis right? ^^</p>
<p style="text-align:justify;">&#8230;</p>
<p style="text-align:justify;">Once our goal is clear, the only remaining question is how to implement all this stuff.</p>
<p style="text-align:justify;">Let&#8217;s revisit our requisites:</p>
<ol style="text-align:justify;">
<li>Evenly distribute points in order to place our views on a sphere;</li>
<li>Use the z coordinate to properly scale and order each view;</li>
<li>Rotate each view around each axis so that we simulate a full sphere rotation;</li>
</ol>
<p style="text-align:justify;">There are a lot of algorithms out there to evenly distribute points on a sphere, but there would be no fun if we don&#8217;t really define and comprehend what is going on here. To begin with, what exactly are evenly distributed points?</p>
<p style="text-align:justify;">Being very precise, we could say that to evenly distribute points on a sphere the resulting polygonal object defined by the points needs to have faces that are equal as well as an equal number of faces leading into every vertex, and this is what defines perfect shapes (or Platonic solids). The problem is that there is no perfect shape with more than 20 vertexes and since each vertex is a the center of a view, this would mean that we could only have 20 views (UILabels) on our cloud.</p>
<p style="text-align:justify;">Therefore we need to think about &#8220;evenly&#8221; on another aspect. Let&#8217;s say that if any two closest points in the whole set are as far apart as possible from each other, all points are equally distant from each other.</p>
<p style="text-align:justify;">Again, there is a bunch of algorithms for this (Golden Section Spiral, Staff and Kuijlaars, Davi&#8217;s Disco Ball and other variations). I tried a lot of them, and the one that fit better to my needs was the Golden Section Spiral, not just because I had better distribution results but also because I could easily define the number of vertexes I wanted.</p>
<p style="text-align:justify;">What the Golden Section Spiral algorithm does is to choose successive longitudes according to the &#8220;most irrational number&#8221; so that no two nodes in nearby bands come too near from each other in longitude.</p>
<p style="text-align:justify;">The implementation I came up with actually run this algorithm creating 3D points (that I called PFPoint and is exactly the same as a CGPoint but with an additional coordinate). These points are then added to an actual array so that we can use them later to properly place our views.</p>
<pre><code><span style="color:#993366;">

@implementation</span> PFGoldenSectionSpiral

+ (<span style="color:#008000;">NSArray</span> *)sphere:(<span style="color:#008000;">NSInteger</span>)n {
    <span style="color:#008000;">NSMutableArray</span>* result = [<span style="color:#008000;">NSMutableArray</span> <span style="color:#0000ff;">arrayWithCapacity</span>:n];

    <span style="color:#993366;">CGFloat</span> N = n;
    <span style="color:#993366;">CGFloat</span> h = <span style="color:#800000;">M_PI</span> * (3 - <span style="color:#800000;">sqrt</span>(5));
    <span style="color:#993366;">CGFloat</span> s = 2 / N;
	<span style="color:#993366;">for</span> (<span style="color:#008000;">NSInteger</span> k=0; k&lt;N; k++) {
        <span style="color:#993366;">CGFloat</span> y = k * s - 1 + (s / 2);
        <span style="color:#993366;">CGFloat</span> r = <span style="color:#800000;">sqrt</span>(1 - y*y);
        <span style="color:#993366;">CGFloat</span> phi = k * h;
	<span style="color:#993366;">PFPoint</span> point = <span style="color:#0000ff;">PFPointMake</span>(<span style="color:#800000;">cos</span>(phi)*r, y, <span style="color:#800000;">sin</span>(phi)*r);
	<span style="color:#008000;">NSValue</span> *v = [<span style="color:#008000;">NSValue</span> <span style="color:#0000ff;">value</span>:&amp;point
              <span style="color:#0000ff;">withObjCType</span>:<span style="color:#993366;">@encode</span>(<span style="color:#0000ff;">PFPoint</span>)];
	[result <span style="color:#0000ff;">addObject</span>:v];
	}
	<span style="color:#993366;">return</span> result;
}
<span style="color:#993366;">@end
</span></code></pre>
<p style="text-align:justify;">This algorithm returns a list of points within [-1, 1] meaning that we will need to properly convert each coordinate to iOS coordinates. In our case, the z-coordinate needs to be converted to [0, 1], while x and y coordinates to [0, frame size].</p>
<p style="text-align:justify;">So basically you can create an UIView subclass &#8211; that I called PFSphereView &#8211; and add a method &#8211; let&#8217;s say &#8211; setItems that receives a set of views to place within the sphere.</p>
<pre><code>
- (<span style="color:#993366;">void</span>)setItems:(<span style="color:#008000;">NSArray</span> *)items {
	<span style="color:#008000;">NSArray</span> *spherePoints =
                [PFGoldenSectionSpiral <span style="color:#0000ff;">sphere</span>:items.count];
	<span style="color:#993366;">for</span> (<span style="color:#993366;">int</span> i=0; i&lt;items.count; i++) {
		<span style="color:#008000;">PFPoint</span> point;
		<span style="color:#008000;">NSValue</span> *pointRep = [spherePoints <span style="color:#0000ff;">objectAtIndex</span>:i];
		[pointRep <span style="color:#0000ff;">getValue</span>:&amp;point];

		<span style="color:#993366;">UIView</span> *view = [items <span style="color:#0000ff;">objectAtIndex</span>:i];
		view.tag = i;
		[<span style="color:#993366;">self</span> <span style="color:#0000ff;">layoutView</span>:view <span style="color:#0000ff;">withPoint</span>:point];
		[<span style="color:#993366;">self</span> <span style="color:#0000ff;">addSubview</span>:view];
	}
}

- (<span style="color:#993366;">void</span>)layoutView:(<span style="color:#008000;">UIView</span> *)view withPoint:(<span style="color:#008000;">PFPoint</span>)point {
	<span style="color:#993366;">CGFloat</span> viewSize = view.frame.size.width;

	<span style="color:#993366;">CGFloat</span> width = <span style="color:#993366;">self</span>.frame.size.width - viewSize*2;
	<span style="color:#993366;">CGFloat</span> x = [<span style="color:#993366;">self</span> <span style="color:#0000ff;">coordinateForNormalizedValue</span>:point.x
             <span style="color:#0000ff;">withinRangeOffset</span>:width];
	<span style="color:#993366;">CGFloat</span> y = [<span style="color:#993366;">self</span> <span style="color:#0000ff;">coordinateForNormalizedValue</span>:point.y
             <span style="color:#0000ff;">withinRangeOffset</span>:width];
	view.<span style="color:#993366;">center</span> = <span style="color:#0000ff;">CGPointMake</span>(x + viewSize, y + viewSize);

	<span style="color:#993366;">CGFloat</span> z = [<span style="color:#993366;">self</span> <span style="color:#0000ff;">coordinateForNormalizedValue</span>:point.z
              <span style="color:#0000ff;">withinRangeOffset</span>:1];

	view.transform = <span style="color:#0000ff;">CGAffineTransformScale</span>(
               <span style="color:#0000ff;">CGAffineTransformIdentity</span>, z, z);
	view.layer.zPosition = z;
}

- (<span style="color:#993366;">CGFloat</span>)coordinateForNormalizedValue:(<span style="color:#993366;">CGFloat</span>)normalizedValue
             withinRangeOffset:(<span style="color:#993366;">CGFloat</span>)rangeOffset {
	<span style="color:#993366;">CGFloat</span> half = rangeOffset / <span style="color:#993366;">2.f</span>;
	<span style="color:#993366;">CGFloat</span> coordinate = <span style="color:#993366;">fabs</span>(normalizedValue) * half;
	<span style="color:#993366;">if</span> (normalizedValue <span style="color:#993366;">&gt; 0</span>) {
		coordinate += half;
	} <span style="color:#993366;">else</span> {
		coordinate = half - coordinate;
	}
	<span style="color:#993366;">return</span> coordinate;
}
</code></pre>
<p style="text-align:justify;">Once the setItems method is called, we can generate a point for each view and layout that view by placing and scaling it according to the converted iOS coordinates. Now you may be able to create a view controller and instantiate the PFSphereView passing a bunch of UILabels to see how our 3D Tag Cloud looks like.</p>
<p style="text-align:justify;">Unfortunately you can&#8217;t animate any kind of rotation yet, since we did not address it. And now is when the cool part comes into play.</p>
<p style="text-align:justify;">We actually can&#8217;t use any 3D transformation available on the SDK since we don&#8217;t want to rotate our labels, but instead the whole sphere. How can we achieve this?</p>
<p style="text-align:justify;">Well, to rotate our sphere all that we need to do is to rotate each point. Once a point is rotated, its coordinates changes on the cartesian plane and therefore each view will rotate around the desired axis in such a way that  only its position and scale will change (not the actual rotation angle).</p>
<p style="text-align:justify;">The achieved behavior is totally different from the result we would get by changing the anchorPoint to be the center of the sphere and use CATransform3DRotate, for example.</p>
<p style="text-align:justify;">If you didn&#8217;t get exactly why, take a moment to draw some points on a 3D cartesian plane in some piece of paper. Imagine each point rotating around the center of the sphere so that we can actually see a sphere rotating. Then imagine every view &#8211; UILabel on our case &#8211; rotating around the very same point. Once you find out what is the difference, continue to read this post.</p>
<p>&#8230;.</p>
<p style="text-align:justify;">Time to rotate our sphere.</p>
<p style="text-align:justify;">The basic idea behind transformations such as rotations on 3D space, is to think of our views as a bunch of points or vectors where we  apply some math and project the results back into the 3 dimensional space. A very efficient way to do so, is to use a homogeneous coordinate representation that maps a point on a n-dimensional space into another on the (n+1)-dimensional space, so that we can represent any point or geometric transformations using only matrixes.</p>
<p style="text-align:justify;">To apply a transformation to a point, we need to multiply two matrixes: the point and the transformation matrix.</p>
<p style="text-align:justify;">Computer Graphics taught us that every transformation can be achieved by multiplying a matrix set. This knowledge allows not only allows us to apply the very basic form of rotation, but also to concatenate transformations in order to achieve a &#8220;real world&#8221; rotation. For example, if we want to rotate an object around its center we need to translate that object to the origin, rotate it and then translate it back to its original position.</p>
<p><a href="http://iosguy.files.wordpress.com/2010/11/rotation.png"><img class="aligncenter size-full wp-image-167" title="Rotation" src="http://iosguy.files.wordpress.com/2010/11/rotation.png?w=480&h=293" alt="" width="480" height="293" /></a></p>
<p>And that is what we are going to do with each of our points.</p>
<blockquote><p>If you don&#8217;t have a basic understanding of geometric transformations you should <a href="http://en.wikipedia.org/wiki/Rotation_(mathematics)">read this topic about rotation</a> to get familiar with terms and matrixes used here.</p></blockquote>
<p style="text-align:justify;">Now that we know the sequence of step we need to take in order to achieve rotation around a given point on a given axis, we just need to get down into math. Let&#8217;s do that using code.</p>
<p style="text-align:justify;">So, there are three kinds of primitive geometric transformations that can be combined to achieve any geometric transformation: rotation, translate and scaling.</p>
<p style="text-align:justify;">We saw that we can combine translations and rotations (and that order matters&#8230;just look at the figure and try achieve D not following the order A-B-C-D) into only one matrix and multiply our point by this matrix to retrieve a new point that is previous point rotated around an arbitrary point. But how do we define which axis we are rotation about or how do we tell what is a translation and what is a rotation?</p>
<p style="text-align:justify;">Actually there is a set of primitive matrixes defined for each primitive geometric transformation. Bellow I provide useful matrixes for our goal: translation and rotation for each axis (x, y and z).</p>
<pre><code><span style="color:#993366;">
static</span> <span style="color:#008000;">PFMatrix</span> PFMatrixTransform3DMakeTranslation(<span style="color:#008000;">PFPoint</span> point) {
	<span style="color:#993366;">CGFloat</span> T<span style="color:#000000;">[4][4]</span> = {
		{1, 0, 0, 0},
		{0, 1, 0, 0},
		{0, 0, 1, 0},
		{point.x, point.y, point.z, 1}
	};

	<span style="color:#008000;">PFMatrix</span> matrix = <span style="color:#0000ff;">PFMatrixMakeFromArray</span>(<span style="color:#993366;">4</span>, <span style="color:#993366;">4</span>, *T);

	<span style="color:#993366;">return</span> matrix;
}

<span style="color:#993366;">static</span> <span style="color:#008000;">PFMatrix</span> PFMatrixTransform3DMakeXRotation(<span style="color:#008000;">PFRadian</span> angle) {
	<span style="color:#993366;">CGFloat</span> c = <span style="color:#993366;">cos</span>(<span style="color:#0000ff;">PFRadianMake</span>(angle));
	<span style="color:#993366;">CGFloat</span> s = <span style="color:#993366;">sin</span>(<span style="color:#0000ff;">PFRadianMake</span>(angle));

	<span style="color:#993366;">CGFloat</span> T<span style="color:#000000;">[4][4]</span> = {
		{1, 0, 0, 0},
		{0, c, s, 0},
		{0, -s, c, 0},
		{0, 0, 0, 1}
	};

	<span style="color:#008000;">PFMatrix</span> matrix = <span style="color:#0000ff;">PFMatrixMakeFromArray</span>(<span style="color:#993366;">4</span>, <span style="color:#993366;">4</span>, *T);

	<span style="color:#993366;">return</span> matrix;
}

<span style="color:#993366;">static</span> <span style="color:#008000;">PFMatrix</span> PFMatrixTransform3DMakeYRotation(<span style="color:#008000;">PFRadian</span> angle) {
	<span style="color:#993366;">CGFloat</span> c = <span style="color:#993366;">cos</span>(<span style="color:#0000ff;">PFRadianMake</span>(angle));
	<span style="color:#993366;">CGFloat</span> s = <span style="color:#993366;">sin</span>(<span style="color:#0000ff;">PFRadianMake</span>(angle));

	<span style="color:#993366;">CGFloat</span> T<span style="color:#000000;">[4][4]</span> = {
		{c, 0, -s, 0},
		{0, 1, 0, 0},
		{s, 0, c, 0},
		{0, 0, 0, 1}
	};

	<span style="color:#008000;">PFMatrix</span> matrix = <span style="color:#0000ff;">PFMatrixMakeFromArray</span>(<span style="color:#993366;">4</span>, <span style="color:#993366;">4</span>, *T);

	<span style="color:#993366;">return</span> matrix;
}

<span style="color:#993366;">static <span style="color:#008000;">PFMatrix</span></span> PFMatrixTransform3DMakeZRotation(<span style="color:#008000;">PFRadian</span> angle) {
	<span style="color:#993366;">CGFloat</span> c = <span style="color:#993366;">cos</span>(<span style="color:#0000ff;">PFRadianMake</span>(angle));
	<span style="color:#993366;">CGFloat</span> s = <span style="color:#993366;">sin</span>(<span style="color:#0000ff;">PFRadianMake</span>(angle));

	<span style="color:#993366;">CGFloat</span> T<span style="color:#000000;">[4][4]</span> = {
		{c, s, 0, 0},
		{-s, c, 0, 0},
		{0, 0, 1, 0},
		{0, 0, 0, 1}
	};

	<span style="color:#008000;">PFMatrix</span> matrix = <span style="color:#0000ff;">PFMatrixMakeFromArray</span>(<span style="color:#993366;">4</span>, <span style="color:#993366;">4</span>, *T);

	<span style="color:#993366;">return</span> matrix;
}
</code></pre>
<p style="text-align:justify;">It would be nice of you to properly research around the math behind these matrixes (This post would be too long if I included a proper explanation about &#8220;where the hell does this matrix set came from??&#8221; and you probably would not read this post until the very end <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  [BTW, I am surprised you got here])</p>
<p style="text-align:justify;">As you may have noticed I created a bunch of representations and helpers to make the code really simple and straightforward. But I don&#8217;t think that you need me to provide that code (matrix representation for example), so I will keep speaking of what really matters. <em>Anyways, you can always reach me via e-mail if you want some sort of code.</em></p>
<p style="text-align:justify;">Ok&#8230;.we already have a specific matrix to rotate a point around any axis and also one to translate it. How are we supposed to use these matrixes to rotate a point around another arbitrary point?</p>
<p style="text-align:justify;">Since the &#8220;the best way to teach is by example&#8221;&#8230;.</p>
<p style="text-align:justify;">Let&#8217;s say that you want to rotate (1,1,1) around (0,1,1) by 45 degrees on the x axis. In this case the code looks like:</p>
<p><code> </code></p>
<pre><code><span style="color:#993366;">
static</span> <span style="color:#008000;">PFMatrix</span> PFMatrixTransform3DMakeXRotationOnPoint(<span style="color:#008000;">PFPoint</span> point,
      <span style="color:#008000;">PFRadian</span> angle) {
	<span style="color:#008000;">PFMatrix</span> T = <span style="color:#0000ff;">PFMatrixTransform3DMakeTranslation</span>(
             <span style="color:#0000ff;">PFPointMake</span>(-point.x, -point.y, -point.z));
	<span style="color:#008000;">PFMatrix</span> R = <span style="color:#0000ff;">PFMatrixTransform3DMakeXRotation</span>(angle);
	<span style="color:#008000;">PFMatrix</span> T1 = <span style="color:#0000ff;">PFMatrixTransform3DMakeTranslation</span>(point);

	<span style="color:#993366;">return</span> <span style="color:#0000ff;">PFMatrixMultiply</span>(<span style="color:#0000ff;">PFMatrixMultiply</span>(T, R), T1);
}

<span style="color:#008000;">PFMatrix</span> coordinate = <span style="color:#0000ff;">PFMatrixMakeFromPFPoint</span>(<span style="color:#0000ff;">PFPointMake</span>(<span style="color:#993366;">1</span>,<span style="color:#993366;">1</span>,<span style="color:#993366;">1</span>));
<span style="color:#008000;">PFMatrix</span> transform = <span style="color:#0000ff;">PFMatrixTransform3DMakeXRotationOnPoint</span>(
         <span style="color:#0000ff;">PFPointMake</span>(<span style="color:#993366;">0</span>,<span style="color:#993366;">1</span>,<span style="color:#993366;">1</span>), <span style="color:#993366;">45</span>);
<span style="color:#008000;">PFMatrix</span> transformedCoordinate = <span style="color:#0000ff;">PFMatrixMultiply</span>(coordinate,
         transform);

<span style="color:#008000;">PFPoint</span> result = <span style="color:#0000ff;">PFPointMakeFromMatrix</span>(transformedCoordinate);
</code></pre>
<p style="text-align:justify;">Ok&#8230;.What the heck is going on!?</p>
<p style="text-align:justify;">First of all we have to create a matrix from our point (UILabel.center) in order to be able to multiply the point by our geometric transformation. This transformation, in turn, consists of 3 primitive transformations.</p>
<p style="text-align:justify;">The first one translates the point to the origin, and that is why we are building the Translate matrix using (-x,-y,-z). Then the second one builds a rotation of 45 degrees around the x axis.</p>
<p style="text-align:justify;">As I explained before, <em>these two transformations are concatenated through multiplication.</em></p>
<p style="text-align:justify;">And since we want to rotate it around the &#8220;point&#8221; and not around &#8220;origin&#8221;, we translate it back to &#8220;point&#8221; by multiplying the resulting matrix by a second Translate matrix using (x, y, z).</p>
<p style="text-align:justify;">That composite transformation is then multiplied by our point (UILabel.center) matrix representation. This gives us as a result a third matrix, from which we extract a point representation.</p>
<p style="text-align:justify;">At this moment you should be thinking that &#8220;result&#8221; point will be our next center and scale representation for one of our labels. <strong>If you thought this you are right!</strong></p>
<p style="text-align:justify;">The basic idea now is to listen for gestures (using UIPanGestureRecognizer or UIRotationGestureRecognizer) to select which rotation matrix will be used and what angle you will pass to <strong>PFMatrixTransform3DMake(Axis)RotationOnPoint</strong>. Once you selected the matrix and found out the proper angle (based on the locationInView method from your gesture recognizer or even using a constant) you just need to iterate through every UILabel and call layoutView:onPoint: just like we did in the setItems method.</p>
<p style="text-align:justify;">To don&#8217;t take from you all the fun, I will let you handle the gestures <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p style="text-align:justify;">By the way, below is how your sphere should look like using this code (of course I added some code to actually handle gestures!).</p>
<p style="text-align:justify;"><span style="text-align:center; display: block;"><a href="http://iosguy.com/2010/11/17/creating-a-3d-tag-cloud/"><img src="http://img.youtube.com/vi/jyBqSNSQDGM/2.jpg" alt="" /></a></span></p>
<blockquote><p>Try to use [0.1, 1] instead of [0,1] for the z coordinate interval and play with view sizes to make it look how you would like to.</p></blockquote>
<p>Hope you enjoy and share your thoughts!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/iosguy.wordpress.com/162/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/iosguy.wordpress.com/162/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/iosguy.wordpress.com/162/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/iosguy.wordpress.com/162/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/iosguy.wordpress.com/162/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/iosguy.wordpress.com/162/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/iosguy.wordpress.com/162/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/iosguy.wordpress.com/162/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/iosguy.wordpress.com/162/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/iosguy.wordpress.com/162/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/iosguy.wordpress.com/162/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/iosguy.wordpress.com/162/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/iosguy.wordpress.com/162/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/iosguy.wordpress.com/162/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=162&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://iosguy.com/2010/11/17/creating-a-3d-tag-cloud/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e2caa8fb0f5104c13fcc1dea0bd66d0e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cezarsignori</media:title>
		</media:content>

		<media:content url="http://iosguy.files.wordpress.com/2010/11/rotation.png" medium="image">
			<media:title type="html">Rotation</media:title>
		</media:content>
	</item>
		<item>
		<title>TThree20: A Brief TTLauncherView tutorial</title>
		<link>http://iosguy.com/2010/10/19/tthree20-a-brief-ttlauncherview-tutorial/</link>
		<comments>http://iosguy.com/2010/10/19/tthree20-a-brief-ttlauncherview-tutorial/#comments</comments>
		<pubDate>Tue, 19 Oct 2010 18:47:51 +0000</pubDate>
		<dc:creator>Cezar Augustus Signori</dc:creator>
				<category><![CDATA[Technical stuff]]></category>
		<category><![CDATA[320]]></category>
		<category><![CDATA[iOs]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[TThree20]]></category>
		<category><![CDATA[TTLauncherView]]></category>

		<guid isPermaLink="false">http://iosguy.com/?p=145</guid>
		<description><![CDATA[The TTLauncherView is a very simple UI component in the sense of use, that basically mimics the iOS home screen. It comes with a scroll view and a page control that enables you to browse through a set of TTLauncherItems. Each of these items can be reordered, deleted or even have a badge number, just like [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=145&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">The TTLauncherView is a very simple UI component in the sense of use, that basically mimics the iOS home screen. It comes with a scroll view and a page control that enables you to browse through a set of TTLauncherItems. Each of these items can be reordered, deleted or even have a badge number, just like application badges on the iOS home screen.</p>
<p style="text-align:justify;">I already worked on a lot of applications that having a &#8220;home screen behavior&#8221; would be great. The Facebook guys found a very neat way to provide this behavior for custom application developers. They just made it a UI component with some delegate methods, just like every other standard component and of course, it works pretty well with their navigation model.</p>
<p style="text-align:justify;">It is so simple, that you just have to create your view controller, append a TTLauncherView to it and attach your TTLauncherItems. If you want to provide a more complete behavior, just implement the TTLauncherViewDelegate and there you go.</p>
<p style="text-align:justify;"><span id="more-145"></span></p>
<p style="text-align:justify;">Let&#8217;s see how to do it.</p>
<p style="text-align:justify;">First of all, let&#8217;s create a UIViewController and name it LauncherViewController. Once you are done with it, modify the AppDelegate so that we map a TTURL to our view controller.</p>
<pre><code>
- (<span style="color:#ff00ff;">void</span>)applicationDidFinishLaunching:(<span style="color:#333399;">UIApplication</span> *)application {
   <span style="color:#333399;">TTNavigator</span>* navigator = [<span style="color:#333399;">TTNavigator</span> <span style="color:#0000ff;">navigator</span>];
   navigator.persistenceMode = <span style="color:#333399;">TTNavigatorPersistenceModeAll</span>;
   <span style="color:#333399;">TTURLMap</span>* map = navigator.<span style="color:#0000ff;">URLMap</span>;
   [map <span style="color:#0000ff;">from</span>:<span style="color:#993366;">@"*"</span> <span style="color:#0000ff;">toViewController</span>:[<span style="color:#333399;">TTWebController</span> <span style="color:#ff00ff;">class</span>]];
   [map <span style="color:#0000ff;">from</span>:<span style="color:#993366;">@"tt://launcher/"</span> <span style="color:#0000ff;">toViewController</span>:
       [LauncherViewController <span style="color:#ff00ff;">class</span>]];

   if (![navigator <span style="color:#0000ff;">restoreViewControllers</span>]) {
      [navigator <span style="color:#0000ff;">openURLAction</span>:
       [<span style="color:#333399;">TTURLAction</span> <span style="color:#0000ff;">actionWithURLPath</span>:<span style="color:#993366;">@"tt://launcher"</span>]];
   }
}
</code></pre>
<p style="text-align:justify;">Now if you run the app you should see a black screen with a navigation controller.</p>
<p style="text-align:justify;">In order to properly display our view controller we need to make it present our Launcher view. The best method to work on this probably is the loadView method since we want to create a UILauncherView and nothing more.</p>
<h4>LauncherViewController.m</h4>
<pre><code>
- (<span style="color:#ff00ff;">void</span>)loadView {
   [<span style="color:#ff00ff;">super</span> loadView];
   <span style="color:#333399;">TTLauncherView</span>* launcherView = [[<span style="color:#333399;">TTLauncherView</span> <span style="color:#0000ff;">alloc</span>]
          <span style="color:#0000ff;">initWithFrame</span>:<span style="color:#ff00ff;">self</span>.<span style="color:#0000ff;">view</span>.<span style="color:#0000ff;">bounds</span>];
   launcherView.<span style="color:#0000ff;">backgroundColor</span> = [<span style="color:#333399;">UIColor</span> <span style="color:#0000ff;">blackColor</span>];
   launcherView.<span style="color:#0000ff;">columnCount</span> = <span style="color:#ff00ff;">4</span>;
   launcherView.<span style="color:#0000ff;">pages</span> = [<span style="color:#333399;">NSArray</span> <span style="color:#0000ff;">arrayWithObjects</span>:
     [<span style="color:#333399;">NSArray</span> <span style="color:#0000ff;">arrayWithObjects</span>:
         [<span style="color:#ff00ff;">self</span> <span style="color:#0000ff;">launcherItemWithTitle</span>:<span style="color:#993366;">@"Google"</span>
              <span style="color:#0000ff;">image</span>:<span style="color:#993366;">@"bundle://safari_logo.png"</span>
                 <span style="color:#0000ff;">URL</span>:<span style="color:#993366;">@"http://google.com"</span>],
        [<span style="color:#ff00ff;">self</span> <span style="color:#0000ff;">launcherItemWithTitle</span>:<span style="color:#993366;">@"Apple"</span>
              <span style="color:#0000ff;">image</span>:<span style="color:#993366;">@"bundle://safari_logo.png"</span>
                 <span style="color:#0000ff;">URL</span>:<span style="color:#993366;">@"http://apple.com"</span>]
        , <span style="color:#ff00ff;">nil</span>]
    , <span style="color:#ff00ff;">nil</span>];

    [<span style="color:#ff00ff;">self</span>.<span style="color:#0000ff;">view addSubview</span>:launcherView];
    [launcherView <span style="color:#0000ff;">release</span>];
}
</code></pre>
<blockquote><p>You could add this code to the viewDidLoad method as well since we need the root view to have it&#8217;s frame properly set.</p></blockquote>
<p style="text-align:justify;">As you can see, when a launcher view is created all you need to do is to provide the proper launcher items that will be displayed and column count. Please note that the column count has nothing to do with the number of pages, which is equal to the number of arrays inside the array provided to the pages property.</p>
<p style="text-align:justify;">Ideally you would read those launcher items from a local stored database (like NSUserDefaults) or even from asynchronously. In the first case, I suggest you to use the viewDidLoad method to set the pages property. In the second one, well it would be when the data is fetched <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>&#8230;.</p>
<p>I know I know, your code is not compiling yet because there is a method missing. It is below, don&#8217;t panic.</p>
<pre><code>
- (<span style="color:#333399;">TTLauncherItem</span> *)launcherItemWithTitle:(<span style="color:#333399;">NSString</span> *)pTitle
       image:(<span style="color:#333399;">NSString</span> *)image URL:(<span style="color:#333399;">NSString</span> *)url {
    <span style="color:#333399;">TTLauncherItem</span> *launcherItem = [[<span style="color:#333399;">TTLauncherItem</span> <span style="color:#0000ff;">alloc</span>]
          <span style="color:#0000ff;">initWithTitle</span>:pTitle
          <span style="color:#0000ff;">image</span>:image
         <span style="color:#0000ff;">URL</span>:url <span style="color:#0000ff;">canDelete</span>:<span style="color:#ff00ff;">YES</span>];
    <span style="color:#ff00ff;">return</span> [launcherItem <span style="color:#0000ff;">autorelease</span>];
}
</code></pre>
<p style="text-align:justify;">Now you can run the app and see a not that nice &#8220;home screen like&#8221; view controller. If you have an image to use in place of safari_logo.png, feel free to try it. Otherwise just <a title="Full Source Code" href="http://dl.dropbox.com/u/11108747/TTLauncherViewTutorial.zip">download the full source code here</a>.</p>
<p style="text-align:justify;">You will notice that if you press and hold a launcher item, all badges will start to wiggle just like the iOS home screen. You can also reorder and delete it. But you can&#8217;t cancel the edit mode, because you will send your app to the background if you tap on the Home Button.</p>
<p style="text-align:justify;">Let&#8217;s fix this issue by using a Edit/Done button on the navigation bar, just like every iOS app does (you can think of a better way once you learn how it works :] ).</p>
<pre><code>
- (<span style="color:#ff00ff;">void</span>)viewDidLoad {
    [<span style="color:#ff00ff;">super</span> <span style="color:#0000ff;">viewDidLoad</span>];
    <span style="color:#ff00ff;">self</span>.<span style="color:#0000ff;">title</span> = <span style="color:#993366;">@"My Launcher View"</span>;
    <span style="color:#333399;">UIBarButtonItem</span> *editButton = [[<span style="color:#333399;">UIBarButtonItem</span> <span style="color:#0000ff;">alloc</span>]
         <span style="color:#0000ff;">initWithBarButtonSystemItem</span>:<span style="color:#333399;">UIBarButtonSystemItemEdit</span>
         <span style="color:#0000ff;">target</span>:launcherView     <span style="color:#0000ff;">action</span>:<span style="color:#ff00ff;">@selector</span>(beginEditing)];
    <span style="color:#ff00ff;">self</span>.<span style="color:#0000ff;">navigationItem.rightBarButtonItem</span> = editButton;
    [editButton <span style="color:#0000ff;">release</span>];
}
</code></pre>
<p style="text-align:justify;">Now we should handle TTLauncherView editing states so that when you tap on Edit, it changes to Done and the TTLauncherView becomes editable. If you tap Done, it stops being editable and the button changes back to Edit. To really be consistent, let&#8217;s change Edit to Done when the TTLauncherView becomes editable but the user did not tap on Edit. So, modify your loadView method to set the TTLauncherView delegate property to self and append the following TTLauncherViewDelegate methods to our controller.</p>
<pre><code>
- (<span style="color:#ff00ff;">void</span>)launcherViewDidBeginEditing:(<span style="color:#333399;">TTLauncherView</span>*)launcher {
    <span style="color:#333399;">UIBarButtonItem</span> *doneButton = [[<span style="color:#333399;">UIBarButtonItem</span> <span style="color:#0000ff;">alloc</span>]
       <span style="color:#0000ff;">initWithBarButtonSystemItem</span>:<span style="color:#333399;">UIBarButtonSystemItemDone</span>
       <span style="color:#0000ff;">target</span>:launcherView <span style="color:#0000ff;">action</span>:<span style="color:#ff00ff;">@selector</span>(endEditing)];
    <span style="color:#ff00ff;">self</span>.<span style="color:#0000ff;">navigationItem.rightBarButtonItem</span> = doneButton;
    [doneButton <span style="color:#0000ff;">release</span>];
}

- (<span style="color:#ff00ff;">void</span>)launcherViewDidEndEditing:(<span style="color:#333399;">TTLauncherView</span>*)launcher {
    <span style="color:#333399;">UIBarButtonItem</span> *editButton = [[<span style="color:#333399;">UIBarButtonItem</span> <span style="color:#0000ff;">alloc</span>]
         <span style="color:#0000ff;">initWithBarButtonSystemItem</span>:<span style="color:#333399;">UIBarButtonSystemItemEdit</span>
         <span style="color:#0000ff;">target</span>:launcherView <span style="color:#0000ff;">action</span>:<span style="color:#ff00ff;">@selector</span>(endEditing)];
    <span style="color:#ff00ff;">self</span>.<span style="color:#0000ff;">navigationItem.rightBarButtonItem</span> = editButton;
    [editButton <span style="color:#0000ff;">release</span>];
}
</code></pre>
<p style="text-align:justify;">Run the app and try out our modifications.</p>
<p style="text-align:justify;">Ok it is working pretty fine&#8230;but our launcher stills not able to launch anything <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  This is a easy fix.</p>
<pre><code>
- (<span style="color:#ff00ff;">void</span>)launcherView:(<span style="color:#333399;">TTLauncherView</span>*)launcher
       didSelectItem:(<span style="color:#333399;">TTLauncherItem</span>*)item {
    [[<span style="color:#333399;">TTNavigator</span> <span style="color:#0000ff;">navigator</span>] <span style="color:#0000ff;">openURLAction</span>:
      [<span style="color:#333399;">TTURLAction</span> <span style="color:#0000ff;">actionWithURLPath</span>:item.<span style="color:#0000ff;">URL</span>]];
}
</code></pre>
<p style="text-align:justify;">Hope you enjoyed this brief tutorial. Now it is time for you to improve this sample code and make a nice app!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/iosguy.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/iosguy.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/iosguy.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/iosguy.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/iosguy.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/iosguy.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/iosguy.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/iosguy.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/iosguy.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/iosguy.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/iosguy.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/iosguy.wordpress.com/145/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/iosguy.wordpress.com/145/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/iosguy.wordpress.com/145/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=145&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://iosguy.com/2010/10/19/tthree20-a-brief-ttlauncherview-tutorial/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e2caa8fb0f5104c13fcc1dea0bd66d0e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cezarsignori</media:title>
		</media:content>
	</item>
		<item>
		<title>A Few Programming Practices: Writing good code</title>
		<link>http://iosguy.com/2010/09/13/a-few-programming-practices-writing-good-code/</link>
		<comments>http://iosguy.com/2010/09/13/a-few-programming-practices-writing-good-code/#comments</comments>
		<pubDate>Tue, 14 Sep 2010 04:30:30 +0000</pubDate>
		<dc:creator>Cezar Augustus Signori</dc:creator>
				<category><![CDATA[Technical stuff]]></category>

		<guid isPermaLink="false">http://iosguy.com/?p=132</guid>
		<description><![CDATA[Obviously that much of what I will speak about here is kind of a convention between Cocoa developers, some may not be, but certainly are details that I believe that makes the code more readable. First of all we write Objective-C code, meaning that our parameters are named. This just happens to be one of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=132&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">Obviously that much of what I will speak about here is kind of a convention between <a href="http://developer.apple.com/cocoa/">Cocoa</a> developers, some may not be, but certainly are details that I believe that makes the code more readable.</p>
<p style="text-align:justify;">First of all we write Objective-C code, meaning that our parameters are named. This just happens to be one of our most valuable tools for writing readable code. <strong>Don&#8217;t be shy to come up with long names</strong> (<a href="http://developer.apple.com/library/ios/#documentation/cocoa/reference/foundation/Classes/NSString_Class/Reference/NSString.html">Apple does that too</a>), that is precisely the reason we have named parameters. <strong>Be clear</strong>.</p>
<p style="text-align:justify;">The second important tip is to <strong>keep your code simple</strong>. You must have heard this phrase a lot, but maybe no one told you what they wanted to tell when using it <img src='http://s2.wp.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p style="text-align:justify;"><span id="more-132"></span></p>
<p style="text-align:justify;">I mean that you should think about using <strong>delegates to handle stuff that you are not sure about how it will work on a different context or even in the future</strong>. Note that I am not saying that you write code without knowing what it is. Instead, let me give you a real example:</p>
<p style="text-align:justify;">Suppose that you are writing a drag&#8217;n drop photo view that can be dropped only on a certain area of the screen. What should happen if you drop that photo outside that area? The first thing that comes to my mind is to animate the photo view to it&#8217;s original position, because the operation failed. But, this photo view could be used inside a popover and maybe it is better to dismiss that popover when the dragging starts&#8230;and if you dismissed it, to where should the photo return to? Nowhere. In this case, I would add a delegate method to ask someone if I should return the photo to it&#8217;s original position or not. Got it?</p>
<p style="text-align:justify;">Of course, you should <strong>write delegate methods when you know that it&#8217;s useful</strong>. Don&#8217;t run around creating lot&#8217;s of unneeded  delegates.</p>
<p style="text-align:justify;">Speaking about delegates and method naming, there are also some delegate conventions that I love to follow. One of them is <strong>to pass self as parameter to every delegate message</strong>. This is very cool because usually prevents you from creating instance variables (as you soon will notice if you start doing this) and gives you <strong>improved readability for free</strong>. You can read the delegate method and know exactly what is going on.</p>
<p style="text-align:justify;">Suppose that draggable photo view we spoke about earlier. What would be a great delegate for it?</p>
<pre style="overflow:auto;"><code>
<span style="color:#993300;">@class</span> DraggablePhotoView;
<span style="color:#993300;">@protoco</span><span style="color:#993300;">l</span> DraggablePhotoViewDelegate&lt;<span style="color:#ff0000;">NSObject</span>&gt;
<span style="color:#993300;">@optional</span>

- (<span style="color:#ff0000;">BOOL</span>)shouldPhotoView:(<span style="color:#ff0000;">DraggablePhotoView</span> *)photoView beDroppedOnto:(<span style="color:#ff0000;">id</span>&lt;<span style="color:#ff0000;">DragablePhotoRecipient</span>&gt;)recipient;
- (<span style="color:#ff0000;">BOOL</span>)photoViewShouldReturnToOriginalPositionOnDropFailure:(<span style="color:#ff0000;">DraggablePhotoView</span> *)photoView;
<span style="color:#993300;">@end</span>
</code></pre>
<p style="text-align:justify;">Big names right? But <strong>you know exactly what is going on</strong> without even reading the implementation code right? And <strong>Xcode auto-completes for you</strong> right? That is what I mean.</p>
<p style="text-align:justify;">These tips can also be applied to variable names. <strong>Don&#8217;t fear writing variables with a clear name, because you spend more time reading code than writing it</strong>.</p>
<p style="text-align:justify;">But just adding long names doesn&#8217;t really improves readability. In order to achieve that, you need to think about what name a method should have (what does it do?). <strong>If it is to complex to find a good name, probably you should split that method into two or more, because it is doing so many things that you can&#8217;t describe it briefly</strong> (and therefore your method may have just a few lines of code). So, <strong>think about the problem itself before you write any code</strong>.</p>
<p style="text-align:justify;">To summarize variable, method and class naming:</p>
<blockquote style="text-align:justify;"><p>A perfect code should be readable enough to need no documentation.</p></blockquote>
<p style="text-align:justify;">But of course, don&#8217;t hesitate to add it when you feel that it is necessary (it is very difficult to achieve perfection <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ).</p>
<p style="text-align:justify;">I am not here to tell you that you should capitalize words and add initials to your classes, you can find this kind of stuff all over the internet (and if you really search for it, you will find people talking about the tips I am posting here, because this is not my invention). But<strong> pay attention to the guides that are available for what you are working with</strong>. Apple for example gives you a lot of &#8220;Best Practices&#8221; stuff in their documentation.</p>
<p style="text-align:justify;">&#8230;.</p>
<p style="text-align:justify;">And what about boolean variables?</p>
<p style="text-align:justify;">For sure you need them, but you probably don&#8217;t like to add a lot (like 3 or 4) to your code. Do you?</p>
<p style="text-align:justify;">I don&#8217;t, and this is why I think it is a good idea to use Enumerations  instead. Just one variable, that tells you everything.</p>
<pre><code>
<span style="color:#800000;">typedef enum</span> {
<span style="color:#333399;">SomethingStatePossible</span>
<span style="color:#333399;">SomethingStateBegan</span>,
<span style="color:#333399;">SomethingStateCancelled</span>,
<span style="color:#333399;">SomethingStateFinished</span>
} <span style="color:#ff0000;">SomethingState</span>;

<span style="color:#ff0000;">SomethingState</span> state;
</code></pre>
<p style="text-align:justify;">Isn&#8217;t it good? It doesn&#8217;t fits to every &#8220;boolean case&#8221;, but usually prevents you from having lots of them.</p>
<p style="text-align:justify;">And finally the BEST PRACTICE EVER</p>
<blockquote style="text-align:justify;">
<p style="text-align:justify;"><strong>Ask someone to review your code and share thoughts with you</strong>.</p>
</blockquote>
<p style="text-align:justify;">This post would be much larger if I added all that I think that makes a good code, so I decided to comment about just the ones that I think is very important and <em>not-everybody-already-follows-it</em>.</p>
<p style="text-align:justify;">So, if you have any tips to share (that you think I should have commented for example), post a comment and let&#8217;s discuss about them!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/iosguy.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/iosguy.wordpress.com/132/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/iosguy.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/iosguy.wordpress.com/132/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/iosguy.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/iosguy.wordpress.com/132/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/iosguy.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/iosguy.wordpress.com/132/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/iosguy.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/iosguy.wordpress.com/132/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/iosguy.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/iosguy.wordpress.com/132/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/iosguy.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/iosguy.wordpress.com/132/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=132&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://iosguy.com/2010/09/13/a-few-programming-practices-writing-good-code/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e2caa8fb0f5104c13fcc1dea0bd66d0e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cezarsignori</media:title>
		</media:content>
	</item>
		<item>
		<title>Provisioning unveiled</title>
		<link>http://iosguy.com/2010/09/08/provisioning-unveiled/</link>
		<comments>http://iosguy.com/2010/09/08/provisioning-unveiled/#comments</comments>
		<pubDate>Thu, 09 Sep 2010 04:47:16 +0000</pubDate>
		<dc:creator>Cezar Augustus Signori</dc:creator>
				<category><![CDATA[Technical stuff]]></category>
		<category><![CDATA[Certificate]]></category>
		<category><![CDATA[Debug]]></category>
		<category><![CDATA[Device]]></category>
		<category><![CDATA[iOs]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Portal]]></category>
		<category><![CDATA[Provisioning]]></category>
		<category><![CDATA[Run on device]]></category>

		<guid isPermaLink="false">http://iosguy.com/?p=104</guid>
		<description><![CDATA[I remember the first time I got to provision a device to run my application (about a year ago). And it was complicated to get the idea behind all the provisioning process. This is precisely why I decided to write about it. Maybe you are lucky enough to read this before your journey. Obviously you [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=104&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">I remember the first time I got to provision a device to run my application (about a year ago). And it was complicated to get the idea behind all the provisioning process.</p>
<p style="text-align:justify;">This is precisely why I decided to write about it. Maybe you are lucky enough to read this before your journey.</p>
<p style="text-align:justify;"><span id="more-104"></span></p>
<p style="text-align:justify;">Obviously you can download and read the <a href="http://adcdownload.apple.com/ios/ios_developer_program_user_guide/ios_developer_program_user_guide__standard_program_v2.7__final_9110.pdf">iOS Developers Program Manual</a> to understand how this process works, but I really think that if you want to get started, this post is very useful.</p>
<p style="text-align:justify;">So let&#8217;s get started!</p>
<p style="text-align:justify;">&#8230;</p>
<p style="text-align:justify;">All iOS applications must be signed by a valid certificate before they can run on a device. This certificate is a file that identifies you as a developer and it is used by Xcode to sign your app.</p>
<p style="text-align:justify;">Each application has it&#8217;s own App ID, that is an unique identifier that enables your app to use Apple Push Notification, In App Purchase, Game Center and Keychain Data sharing with other applications. This identifier consists of an unique 10 character &#8220;Bundle Seed ID&#8221; prefix generated by Apple and a &#8220;Bundle Identifier&#8221; suffix that is specified by you (and should match with the Bundle Identifier property from your application&#8217;s plist file).</p>
<p style="text-align:justify;">In order to debug your app in the device, you need to create a Provisioning Profile and install it on your device (apart from the Certificate). This provisioning profile is a file that ties a set of developers (certificates) and devices, that are able to develop and run (respectively) a given app.</p>
<p style="text-align:justify;">Meaning that each device has a unique identifier too, that is called UDID and consists of  a 40 character string that is similar to a serial number.</p>
<p style="text-align:justify;">So, the basic idea about the provisioning process is to enable a device to run an app that was developed by you, and this is accomplished through the Provisioning Profile and your Certificate.</p>
<p style="text-align:justify;">Now that you know <em>what</em>, let&#8217;s see <em>how</em>.</p>
<p style="text-align:justify;">&#8230;.</p>
<p style="text-align:justify;">First thing is to <a href="https://daw.apple.com/cgi-bin/WebObjects/DSAuthWeb.woa/wa/login?appIdKey=D635F5C417E087A3B9864DAC5D25920C4E9442C9339FA9277951628F0291F620&amp;path=%2F%2Fdevcenter%2Fios%2Findex.action">create an Apple ID if you don&#8217;t already have one</a>. After that, you have to join in the iOS Developer Program (unfortunately you have to pay for that, but this is another story).</p>
<p style="text-align:justify;">If you already joined the program, go to the <a href="http://developer.apple.com/devcenter/ios/index.action">iOS Provisioning Portal</a> on the right side of the screen.</p>
<p style="text-align:justify;"><img class="aligncenter size-full wp-image-106" title="iOS Provisioning Portal" src="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-8-44-59-pm.png?w=480" alt=""   /></p>
<p style="text-align:justify;">Go to the App IDs section, fill the form as requested and tap submit.</p>
<p style="text-align:justify;"><a href="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-8-48-03-pm1.png"><img class="aligncenter size-full wp-image-108" title="App IDs" src="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-8-48-03-pm1.png?w=480&h=159" alt="" width="480" height="159" /></a></p>
<p style="text-align:justify;">Now that you already have your App ID, go to your project in Xcode and open the plist file. You should change your Bundle ID to match the one you used to fill the form.</p>
<p style="text-align:justify;"><a href="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-8-52-50-pm.png"><img class="aligncenter size-full wp-image-109" title="plist file" src="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-8-52-50-pm.png?w=480&h=268" alt="" width="480" height="268" /></a></p>
<p style="text-align:justify;">Ok. Now you have to register your device ID  in the provisioning portal, so get it from either <a title="How to find it using iTunes" href="http://magellanmedia.com/blog/how-to-find-your-device-id/">iTunes (click here to see how)</a>. Or Organizer:</p>
<p style="text-align:justify;"><a href="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-9-29-12-pm.png"><img class="aligncenter size-full wp-image-118" title="Organizer" src="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-9-29-12-pm.png?w=480&h=143" alt="" width="480" height="143" /></a></p>
<p style="text-align:justify;">Since you already got your UDID, it is time to register it. Go to the Devices screen and tap on Add Device. Again just fill the form that will appear and confirm.</p>
<p style="text-align:justify;"><a href="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-8-58-51-pm.png"><img class="aligncenter size-full wp-image-110" title="Devices" src="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-8-58-51-pm.png?w=480&h=146" alt="" width="480" height="146" /></a></p>
<p style="text-align:justify;">Time to request your certificate. Open Spotlight and enter Keychain. Create a new certificate request.</p>
<p style="text-align:justify;"><a href="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-9-05-09-pm.png"><img class="aligncenter size-full wp-image-111" title="Request Certificate" src="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-9-05-09-pm.png?w=480&h=188" alt="" width="480" height="188" /></a>Fill the form just like I did on the following screenshot (with your e-mail and saving to disk).</p>
<p style="text-align:justify;"><a href="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-9-06-58-pm.png"><img class="aligncenter size-full wp-image-112" title="Certificate Form" src="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-9-06-58-pm.png?w=480&h=355" alt="" width="480" height="355" /></a>Once your are done, go back to the iOS Provisioning Portal and click on Certificates. Then click on &#8220;Request a Certificate&#8221;, that in your case should be where you can see the &#8220;Download&#8221; button.</p>
<p style="text-align:justify;"><a href="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-9-09-37-pm.png"><img class="aligncenter size-full wp-image-113" title="Certificate" src="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-9-09-37-pm.png?w=480&h=155" alt="" width="480" height="155" /></a></p>
<p style="text-align:justify;">I know, I know&#8230; but we are almost in the end of the process. Now it is time to create the Provisioning Profile, so go to the Provisioning screen and tap on &#8220;New Profile&#8221;.</p>
<p style="text-align:justify;"><a href="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-9-13-13-pm.png"><img class="aligncenter size-full wp-image-114" title="Provisioning" src="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-9-13-13-pm.png?w=480&h=87" alt="" width="480" height="87" /></a></p>
<p style="text-align:justify;">Just select your certificate, your App ID, your device and submit!</p>
<p style="text-align:justify;">Now, download the provisioning profile you just created and go back to the certificates section, to download your certificate.</p>
<p style="text-align:justify;">Hurting to much? 4 last steps and that is it:</p>
<ol style="text-align:justify;">
<li>Double click on your certificate file and it will get installed on your Keychain.</li>
<li>Double click on the provisioning profile file and it will get installed on your machine.</li>
<li>Change your application&#8217;s target to Device.</li>
<li>Build and Run!</li>
<li>Allow Keychain access and install the provisioning profile on the device by confirming both the alert views.</li>
</ol>
<blockquote><p>Ok, I said 4 but actually were 5 steps.</p></blockquote>
<p style="text-align:justify;">Now your app should be successfully installed on your device.</p>
<p style="text-align:justify;">You already know how the provisioning process works and how to do it. So take a time (when you can), to think about it and read the documentation I provided in the beginning of this post.</p>
<p style="text-align:justify;">And let me know if you got any problems <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/iosguy.wordpress.com/104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/iosguy.wordpress.com/104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/iosguy.wordpress.com/104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/iosguy.wordpress.com/104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/iosguy.wordpress.com/104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/iosguy.wordpress.com/104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/iosguy.wordpress.com/104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/iosguy.wordpress.com/104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/iosguy.wordpress.com/104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/iosguy.wordpress.com/104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/iosguy.wordpress.com/104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/iosguy.wordpress.com/104/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/iosguy.wordpress.com/104/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/iosguy.wordpress.com/104/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=104&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://iosguy.com/2010/09/08/provisioning-unveiled/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e2caa8fb0f5104c13fcc1dea0bd66d0e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cezarsignori</media:title>
		</media:content>

		<media:content url="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-8-44-59-pm.png" medium="image">
			<media:title type="html">iOS Provisioning Portal</media:title>
		</media:content>

		<media:content url="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-8-48-03-pm1.png" medium="image">
			<media:title type="html">App IDs</media:title>
		</media:content>

		<media:content url="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-8-52-50-pm.png" medium="image">
			<media:title type="html">plist file</media:title>
		</media:content>

		<media:content url="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-9-29-12-pm.png" medium="image">
			<media:title type="html">Organizer</media:title>
		</media:content>

		<media:content url="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-8-58-51-pm.png" medium="image">
			<media:title type="html">Devices</media:title>
		</media:content>

		<media:content url="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-9-05-09-pm.png" medium="image">
			<media:title type="html">Request Certificate</media:title>
		</media:content>

		<media:content url="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-9-06-58-pm.png" medium="image">
			<media:title type="html">Certificate Form</media:title>
		</media:content>

		<media:content url="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-9-09-37-pm.png" medium="image">
			<media:title type="html">Certificate</media:title>
		</media:content>

		<media:content url="http://iosguy.files.wordpress.com/2010/09/screen-shot-2010-09-08-at-9-13-13-pm.png" medium="image">
			<media:title type="html">Provisioning</media:title>
		</media:content>
	</item>
		<item>
		<title>View Management Cycle reviewed</title>
		<link>http://iosguy.com/2010/09/07/view-management-cycle-unveiled/</link>
		<comments>http://iosguy.com/2010/09/07/view-management-cycle-unveiled/#comments</comments>
		<pubDate>Wed, 08 Sep 2010 03:21:04 +0000</pubDate>
		<dc:creator>Cezar Augustus Signori</dc:creator>
				<category><![CDATA[Technical stuff]]></category>

		<guid isPermaLink="false">http://iosguy.com/?p=98</guid>
		<description><![CDATA[Almost all developers when get a little more experienced, don&#8217;t stop to carefully read all the documentation or to think about what they are already used to do everyday. But I myself already stopped to think and discuss with my team how we are supposed to handle some issues, and between these issues there is [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=98&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Almost all developers when get a little more experienced, don&#8217;t stop to carefully read all the documentation or to think about what they are already used to do everyday.</p>
<p>But I myself already stopped to think and discuss with my team how we are supposed to handle some issues, and between these issues there is a very simple one: How are we <strong>really supposed</strong> to use methods like <a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/init">init</a>, <a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/loadView">loadView</a>, <a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/viewDidLoad">viewDidLoad</a>, <a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/didReceiveMemoryWarning">didReceiveMemoryWarning</a>, <a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/viewDidUnload">viewDidUnload</a> and <a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/dealloc">dealloc</a> from our view controllers?</p>
<p>After discussing a lot and obviously checking the documentation, these are my thoughts about this topic:</p>
<p><span id="more-98"></span></p>
<ul>
<li><a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/init">Init</a> methods should be used to allocate data structures needed by your view controller.</li>
<li>The <a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/loadView">loadView</a> method should be used to allocate and add subviews, as well as to define the view controller&#8217;s root view (the well-known self.view). When you override this method, <strong>be sure to do not call super</strong> (because it is your responsibility to create all that you need). This method should not be used when a nib file defines your view. In this case, use <a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/initWithNibName:bundle:" target="_top">initWithNibName:bundle:</a> to configure your view.</li>
<li>The <a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/viewDidLoad">viewDidLoad</a> method should be used to populate your views with data, because your views are ready for that. Do not create view here, now you know that it is wrong.</li>
<li>The <a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/didReceiveMemoryWarning">didReceiveMemoryWarning</a> is called when you are almost out of memory, meaning that is time to release all the data that you are able to, <strong>but not views</strong>. I mean that the best use for this method is to release the data you allocated on viewDidLoad. This method&#8217;s default implementation is also responsible for calling <a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/viewDidUnload">viewDidUnload</a> if needed. This is why you should <strong>always call it&#8217;s super method in the end of your implementation</strong>.</li>
<li>The <a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/viewDidUnload">viewDidUnload</a> method is called when you root view is released, meaning that if you are keeping any references to it&#8217;s subviews (from <a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/loadView">loadView</a>) it is time to release them.</li>
<li>The <a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/dealloc">dealloc</a> method is called when your reference count reaches 0 and therefore is the opposite of the init method. So obviously you should release here all that you allocated on your init method. This is also the time to release any objects that for some reason weren&#8217;t release before. I know that this is pretty basic stuff, but I would be naive to believe that everybody releases everything that is supposed to be release here.</li>
</ul>
<p>A good practice is to use your accessors to release properties, instead of calling release followed by nil. I mean, this code is already provided by the <a href="http://developer.apple.com/mac/library/documentation/cocoa/conceptual/objectivec/articles/ocProperties.html">@synthesize</a>, why would you write it again?</p>
<p>Ah&#8230;and some developers already asked me this, so there it goes: <em>It doesn&#8217;t matter if you are using a property or not, you always have to release instance variables in the end. Be assigning nil through it&#8217;s accessor or releasing the variable itself.</em></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/iosguy.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/iosguy.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/iosguy.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/iosguy.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/iosguy.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/iosguy.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/iosguy.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/iosguy.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/iosguy.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/iosguy.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/iosguy.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/iosguy.wordpress.com/98/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/iosguy.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/iosguy.wordpress.com/98/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=iosguy.com&#038;blog=15606689&#038;post=98&#038;subd=iosguy&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://iosguy.com/2010/09/07/view-management-cycle-unveiled/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/e2caa8fb0f5104c13fcc1dea0bd66d0e?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cezarsignori</media:title>
		</media:content>
	</item>
	</channel>
</rss>
