<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">

<channel>
	<title>Cocoa Is My Girlfriend</title>
	
	<link>http://www.cimgf.com</link>
	<description>Taglines are for Windows programmers</description>
	<pubDate>Mon, 17 Nov 2008 14:57:35 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/CocoaIsMyGirlfriend" type="application/rss+xml" /><item>
		<title>Landscape Tab Bar Application for the iPhone</title>
		<link>http://www.cimgf.com/2008/11/13/landscape-tab-bar-application-for-the-iphone/</link>
		<comments>http://www.cimgf.com/2008/11/13/landscape-tab-bar-application-for-the-iphone/#comments</comments>
		<pubDate>Fri, 14 Nov 2008 02:53:06 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
		
		<category><![CDATA[Cocoa]]></category>

		<category><![CDATA[Cocoa Touch]]></category>

		<category><![CDATA[Objective-C]]></category>

		<category><![CDATA[iPhone]]></category>

		<category><![CDATA[iPod Touch]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=361</guid>
		<description><![CDATA[As you develop applications for the iPhone, you will likely use the project templates provided in Xcode. One such template, called &#8220;Tab Bar Application&#8221; helps you get a tab bar application set up quickly, but by default the application it generates only supports portrait mode for display. So how can you make the application also [...]]]></description>
			<content:encoded><![CDATA[<p>As you develop applications for the iPhone, you will likely use the project templates provided in Xcode. One such template, called &#8220;Tab Bar Application&#8221; helps you get a tab bar application set up quickly, but by default the application it generates only supports portrait mode for display. So how can you make the application also support landscape or even only support landscape? In this post we will address that question.<br />
<span id="more-361"></span><br />
To duplicate the problem, create a new tab bar application in Xcode. To do so,</p>
<ol>
<li>Press Command-Shift-N and select Tab Bar Application in the iPhone OS | Application templates. Click Choose&#8230;</li>
<li>Provide a name for the project. I chose &#8220;Tab Test&#8221;</li>
<li>Click Save</li>
</ol>
<p>The first thing you&#8217;ll notice is that the template has generated two classes for us. One called FirstViewController, which is used to control the first view (ya think?). The other is called Tab_TestAppDelegate which is our application delegate&#8211;the entry point and main controller class for our application.</p>
<p>Take a look at the stub code generated in the FirstViewController. It is commented out for the most part, but you&#8217;ll notice that there is a method in there that gives us what we want for allowing different orientations for our application. In particular, we are interested in <strong>-shouldAutorotateToInterfaceOrientation</strong>. Uncomment that code and have it simply return YES. This setting will enable the controller to support all orientations.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Override to allow orientations other than the default portrait orientation.</span>
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>shouldAutorotateToInterfaceOrientation<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIInterfaceOrientation<span style="color: #002200;">&#41;</span>interfaceOrientation <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// Return YES for supported orientations</span>
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>This <em>should</em> cause our view to change orientation when the device is turned. Build and run the application using the simulator. Once the simulator has loaded the application, select Hardware | Rotate Left. You will notice that while the device did rotate, the view did not. Why is this?</p>
<h2>All Or None</h2>
<p>Remember that the default tab bar application template creates a tab bar component with <strong>two</strong> views. While we have explicitly told the FirstViewController object to allow all orientations, we have not done so with our second view. The way the tab bar controller works is that if <strong>any</strong> of the view controllers have a limitation on the orientation of the view, then <strong>all</strong> views are constrained by the same limitation.</p>
<p>What this means is that all view controllers must override the call to <strong>-shouldAutorotateToInterfaceOrientation</strong> to return the appropriate setting&#8211;YES to allow all. In our default tab bar app, we have not assigned the second view to a controller because we have not defined one, so where is it getting its controller from? Well, the answer is found in interface builder. If you double-click MainWindow.xib in the Resources group of the Xcode project, Interface Builder will load. Click on the tab for the first view in the main window, and then select the Identity tab in the Inspector, you&#8217;ll see what is going on.</p>
<div id="attachment_368" class="wp-caption alignleft" style="width: 310px"><a href="http://www.cimgf.com/wp-content/uploads/2008/11/firstview.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2008/11/firstview-300x245.png" alt="FirstViewController" title="FirstViewController" width="300" height="245" class="size-medium wp-image-368" /></a><p class="wp-caption-text">FirstViewController</p></div>
<p>Notice in the first view <strong>Class</strong> field, it is set to <strong>FirstViewController</strong>. Take a close look now at our second view by clicking the second tab.</p>
<div id="attachment_370" class="wp-caption alignleft" style="width: 310px"><a href="http://www.cimgf.com/wp-content/uploads/2008/11/secondview.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2008/11/secondview-300x245.png" alt="SecondView Controller" title="SecondView Controller" width="300" height="245" class="size-medium wp-image-370" /></a><p class="wp-caption-text">SecondView Controller</p></div>
<p>Notice that the class we&#8217;re using here is the base UIViewController class. This is our view&#8217;s controller. It only provides the base functionality&#8211;which is to say it doesn&#8217;t provide a whole lot. Furthermore it implements the default functionality. The default setting for the orientation of a view controller is portrait only. In other words, only derivative classes are going to be able to override <strong>-shouldAutorotateToInterfaceOrientation</strong> and set it to something other than the default.</p>
<p>If you want your application to be able to support more than the default portrait orientation, all of your tab views must have their own view controller that overrides <strong>-shouldAutorotateToInterfaceOrientation</strong></p>
<h2>Conclusion</h2>
<p>The iPhone is a fun and interesting computing platform. It is very powerful, but it has a lot of nuances that make it fairly different from what you may be used to on OS X. The trick is to remember the principles you&#8217;ve already learned in Cocoa, MVC in particular, and you should be able to deal with the nuances and make them submit to your own will. Until next time.</p>

<p><a href="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?a=SZgqMQ"><img src="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?i=SZgqMQ" border="0"></img></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/11/13/landscape-tab-bar-application-for-the-iphone/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Core Animation Tutorial: Interrupting Animation Progress</title>
		<link>http://www.cimgf.com/2008/11/05/core-animation-tutorial-interrupting-animation-progress/</link>
		<comments>http://www.cimgf.com/2008/11/05/core-animation-tutorial-interrupting-animation-progress/#comments</comments>
		<pubDate>Thu, 06 Nov 2008 00:10:46 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
		
		<category><![CDATA[Cocoa]]></category>

		<category><![CDATA[Core Animation]]></category>

		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=317</guid>
		<description><![CDATA[Starting and stopping animations in Core Animation is as simple as adding and removing your animation from the layer upon which is being run. In this post I am going to talk about how to interrupt animation progress and how to determine whether an animation completed its full run or was interrupted. This is accomplished [...]]]></description>
			<content:encoded><![CDATA[<p>Starting and stopping animations in Core Animation is as simple as adding and removing your animation from the layer upon which is being run. In this post I am going to talk about how to interrupt animation progress and how to determine whether an animation completed its full run or was interrupted. This is accomplished with the animation delegate <em>-animationDidStop:finished</em>.<br />
<span id="more-317"></span></p>
<h2>Differentiating Keypath From Key</h2>
<p>Each core animation layer contains a dictionary that enables you to add and remove animations based on a key that you define. I created a layer-backed view that receives mouse clicks and animates the position of the layer toward that mouse click.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>mouseDown<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSEvent</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>event;
<span style="color: #002200;">&#123;</span>
    CABasicAnimation <span style="color: #002200;">*</span>animation <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>CABasicAnimation animationWithKeyPath<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;position&quot;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>animation setDelegate<span style="color: #002200;">:</span>self<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>animation setFromValue<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSValue</span> valueWithPoint<span style="color: #002200;">:</span>previousValue<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    previousValue <span style="color: #002200;">=</span> NSMakePoint<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>event locationInWindow<span style="color: #002200;">&#93;</span>.x, <span style="color: #002200;">&#91;</span>event locationInWindow<span style="color: #002200;">&#93;</span>.y<span style="color: #002200;">&#41;</span>;
    <span style="color: #002200;">&#91;</span>animation setToValue<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSValue</span> valueWithPoint<span style="color: #002200;">:</span>previousValue<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>animation setDuration<span style="color: #002200;">:</span><span style="color: #2400d9;">2.0</span><span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #002200;">&#91;</span>objectLayer addAnimation<span style="color: #002200;">:</span>animation forKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;follow&quot;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Notice that when I create the animation, I am creating it with a keypath&#8211;in this case <em>position</em>. The keypath is different from the key by which we store the animation in the animations dictionary contained by the layer. In the sample code I add the animation to the dictionary using a key called &#8220;follow&#8221;. This could be any string that is meaningful to keep track of the animation in question. Consider it a tag.</p>
<p>I only make this distinction because I&#8217;ve seen some confusion about the difference between the two. To summarize, the keypath <em>specifies which layer property you want to animate</em> while the key is <em>the key by which you will store, recall, and delete an animation from the animation dictionary contained by the layer</em>.</p>
<h2>Adding The Animation, Again</h2>
<p>In the code above, you&#8217;ll also notice that we are adding the animation to the layer for the same key each time we receive a <em>-mouseDown</em>. If we are setting a new object in the dictionary each time, then how are we able to keep track of whether or not the animation finished?</p>
<p>By setting a delegate for the animation, we can be notified when animation has been removed from the animations dictionary. We implement the <em>-animationDidStop:finished</em> delegate.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>animationDidStop<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CAAnimation <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>theAnimation finished<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>flag
<span style="color: #002200;">&#123;</span>
    NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Animation interrupted: %@&quot;</span>, <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>flag<span style="color: #002200;">&#41;</span>?<span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Yes&quot;</span> <span style="color: #002200;">:</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;No&quot;</span><span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>There are several things going on here. When we call <em>[objectLayer addAnimation:animation forKey:@"follow"];</em> in our <em>-mouseDown</em> code, the animation that was there previously, if there was one, is replaced by the new one. If the user clicked on the screen before the animation completed, the animation is removed and the delegate <em>-animationDidStop</em> gets called. If instead of clicking the mouse again before the current animation is finished, you just let it finish, the animation is also removed from the dictionary because this is the default behavior for an animation. If you don&#8217;t specify <em>[animation setRemovedOnCompletion:NO]</em> explicitly, the animation will be removed.</p>
<h2>Changing Direction While In Flight</h2>
<p>When the view receives a click the basic animation is re-created and added to the layer for the key &#8220;follow&#8221; again. The fromValue field needs set again, but if you click another spot on the view before the animation finishes, what value do you set it to? If you set it to the previous value, it will simply animate from the previous location which won&#8217;t look right. You want it to change direction rather than starting from the previous start location.</p>
<p>If instead of using a basic animation in our example code we had simply opted to use the animator proxy, calling <em>-setPosition</em> on the layer would do this for us. The problem is that we want to be able to demonstrate the <em>-animationDidStop</em> delegate which we can&#8217;t do with the animator proxy. So how do we provide this functionality of changing direction in flight?</p>
<p>Look no further than the <em>presentationLayer</em> which is accessible through our layer object. We can obtain the last location of our &#8220;position&#8221; parameter by first getting the presentationLayer and getting the position from it instead. We&#8217;ve modified our <em>-mouseDown</em> event to reflect this change.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>mouseDown<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #400080;">NSEvent</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>event;
<span style="color: #002200;">&#123;</span>
  CABasicAnimation <span style="color: #002200;">*</span>animation <span style="color: #002200;">=</span> 
          <span style="color: #002200;">&#91;</span>CABasicAnimation animationWithKeyPath<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;position&quot;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>animation setDelegate<span style="color: #002200;">:</span>self<span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #11740a; font-style: italic;">// Get the presentationLayer</span>
  CALayer <span style="color: #002200;">*</span>p <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span>CALayer<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#91;</span>objectLayer presentationLayer<span style="color: #002200;">&#93;</span>;
  CGPoint position <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>p position<span style="color: #002200;">&#93;</span>;
  <span style="color: #400080;">NSValue</span> <span style="color: #002200;">*</span>prevVal <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSValue</span> valueWithPoint<span style="color: #002200;">:</span>
                      NSPointFromCGPoint<span style="color: #002200;">&#40;</span>position<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #002200;">&#91;</span>animation setFromValue<span style="color: #002200;">:</span>prevVal<span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #002200;">&#91;</span>animation setToValue<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSValue</span> valueWithPoint<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>event locationInWindow<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>animation setDuration<span style="color: #002200;">:</span><span style="color: #2400d9;">2.0</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>animation setRemovedOnCompletion<span style="color: #002200;">:</span><span style="color: #a61390;">NO</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #002200;">&#91;</span>objectLayer addAnimation<span style="color: #002200;">:</span>animation forKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;follow&quot;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Now, when we click in our view, the animation changes directions from its current location in the animation. The <em>presentationLayer</em> provides you with current values of whatever field you are currently animating. If a value is not being animated, you will get the same value as what is in the main layer.</p>
<h2>Conclusion</h2>
<p>It&#8217;s very handy to have a way to know when an animation is completed. You simply set your app delegate to be your animation&#8217;s delegate and when the animation completes, <em>-animationDidStop:finished</em> gets called conveying through the <em>finished</em> flag whether the animation was interrupted or not. To get our in flight values when the animation hasn&#8217;t completed, we simply look at the <em>presentationLayer</em>. These features of Core Animation are very powerful. Given the choice I would like to see the <em>presentationLayer</em> values become KVO compliant as this would let you monitor changes in real time, but being able to read the current value at any given time is a great capability in its own right. It&#8217;s very cool technology. Until next time.</p>
<p><a href='http://www.cimgf.com/wp-content/uploads/2008/11/followme.zip'><img src="http://www.cimgf.com/wp-content/uploads/2008/03/xcode.png" alt="xcode.png" border="0" width="64"/><br />Follow Me Demo Project</a></p>

<p><a href="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?a=dSyrj4"><img src="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?i=dSyrj4" border="0"></img></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/11/05/core-animation-tutorial-interrupting-animation-progress/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Announcement: Marcus’ Core Data Book Just Went Beta!</title>
		<link>http://www.cimgf.com/2008/10/27/announcement-marcus-core-data-book-just-went-beta/</link>
		<comments>http://www.cimgf.com/2008/10/27/announcement-marcus-core-data-book-just-went-beta/#comments</comments>
		<pubDate>Mon, 27 Oct 2008 18:23:12 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
		
		<category><![CDATA[Announcement]]></category>

		<category><![CDATA[Cocoa]]></category>

		<category><![CDATA[Core Data]]></category>

		<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=335</guid>
		<description><![CDATA[A lot of hard work has gone into this book already and I see it becoming the definitive text on the subject of Core Data. The release date is slated for March 30, 2009, but it&#8217;s great to see it in beta. If you want to pick up the beta in PDF, it is available [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.cimgf.com/wp-content/uploads/2008/10/mzcd.jpg" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2008/10/mzcd.jpg" alt="Core Data Book" title="Core Data Book" width="190" height="228" class="size-full wp-image-338" align='left' /></a>A lot of hard work has gone into this book already and I see it becoming the definitive text on the subject of Core Data. The release date is slated for March 30, 2009, but it&#8217;s great to see it in beta. If you want to pick up the beta in PDF, it <strong>is available now from Pragmatic here:</strong> <a href="http://www.pragprog.com/titles/mzcd/core-data">Core Data: Apple&#8217;s API for Persisting Data under Mac OS X</a>. </p>
<p>While new Cocoa programmers will find it a great help to getting started quickly with Core Data, the book also covers some really interesting and advanced topics such as data versioning and migration, Spotlight/Quick Look integration, Sync Services, and multi-threading. You can really see Marcus&#8217; command of the subject shine in these chapters which are already available in the beta.</p>
<p>Give Marcus some feedback on the book as it progresses. It&#8217;s going to be a great reference for any Cocoa Developer looking to harness the power of Core Data.</p>
<p>$21.00 for the beta PDF<br />
$41.35 for the beta PDF plus hard copy when it&#8217;s released in March.</p>
<p>Mad props to Marcus. Congratulations!</p>

<p><a href="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?a=jpV2ui"><img src="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?i=jpV2ui" border="0"></img></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/10/27/announcement-marcus-core-data-book-just-went-beta/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Core Animation Tutorial: Slider Based Layer Rotation</title>
		<link>http://www.cimgf.com/2008/10/25/core-animation-tutorial-slider-based-layer-rotation/</link>
		<comments>http://www.cimgf.com/2008/10/25/core-animation-tutorial-slider-based-layer-rotation/#comments</comments>
		<pubDate>Sun, 26 Oct 2008 00:15:50 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
		
		<category><![CDATA[Cocoa]]></category>

		<category><![CDATA[Core Animation]]></category>

		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=322</guid>
		<description><![CDATA[It is often helpful to create a custom control for you application that will display a value as a level like a gas gauge shows how full your tank is. In this post I will demonstrate how to create a three layer tree that will show the current rotation of a circular layer as the [...]]]></description>
			<content:encoded><![CDATA[<p>It is often helpful to create a custom control for you application that will display a value as a level like a gas gauge shows how full your tank is. In this post I will demonstrate how to create a three layer tree that will show the current rotation of a circular layer as the value from a slider (NSSlider) is updated in real time. The layers include the root layer, the rotation layer, and a text layer that will display the current rotation in degrees.<br />
<span id="more-322"></span></p>
<h2>The Slider Value</h2>
<p>We connect a slider to an IBAction in xcode that will get called continuously as we have checked the checkbox called &#8216;Continuous&#8217; in Interface Builder. We can read the slider value and apply it to our animation that we use to rotate the layer. In interface builder, we have specified a minimum value of -180, a maximum value of 180 and a current value (our starting value) of 0 on the slide control. When the slider is moved, the rotation updates as does the value of our text layer.</p>
<p>While it is coincidental that the demo application sort of looks like a pumpkin, it seems appropriate considering the time of year.</p>
<div id="attachment_325" class="wp-caption alignleft" style="width: 283px"><a href="http://www.cimgf.com/wp-content/uploads/2008/10/layerrotate.png" rel="lightbox"><img src="http://www.cimgf.com/wp-content/uploads/2008/10/layerrotate-273x300.png" alt="Layer Rotate" title="Layer Rotate" width="273" height="300" class="size-medium wp-image-325" /></a><p class="wp-caption-text">Layer Rotate</p></div>
<h2>Rotation Animation</h2>
<p>Rotating a layer is very simple. You just need to create an animation with &#8220;transform.rotation.z&#8221; as your keypath and then you can set from and to values that the animation will rotate between. We simply keep track of the last value we rotated (<em>previousValue</em> in the code) to and use this as our from value in the next change to the slider.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>CAAnimation<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>rotateAnimation;
<span style="color: #002200;">&#123;</span>
  CABasicAnimation <span style="color: #002200;">*</span> animation;
  animation <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>CABasicAnimation 
               animationWithKeyPath<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;transform.rotation.z&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #002200;">&#91;</span>animation setFromValue<span style="color: #002200;">:</span>DegreesToNumber<span style="color: #002200;">&#40;</span>previousValue<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>animation setToValue<span style="color: #002200;">:</span>DegreesToNumber<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>slider floatValue<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #002200;">&#91;</span>animation setRemovedOnCompletion<span style="color: #002200;">:</span><span style="color: #a61390;">NO</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>animation setFillMode<span style="color: #002200;">:</span>kCAFillModeForwards<span style="color: #002200;">&#93;</span>;
&nbsp;
  previousValue <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>slider floatValue<span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #a61390;">return</span> animation;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>When our -sliderChange function gets called when the user moves the slider, we add the animation to the layer again using the key &#8220;rotate&#8221;. This is done first in our -awakeFromNib call and then in the -sliderChange call.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>sliderChange<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender;
<span style="color: #002200;">&#123;</span>
  <span style="color: #002200;">&#91;</span>degreesTextLayer setString<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%f&quot;</span>, <span style="color: #002200;">&#91;</span>slider floatValue<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>needleLayer addAnimation<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>self rotateAnimation<span style="color: #002200;">&#93;</span> forKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;rotate&quot;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>needleLayer setNeedsDisplay<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>You will notice that we call -setNeedsDisplay on the layer. This is necessary as we have implemented the delegate method -drawLayer:inContext. We use this method to draw the vertical and horizontal black lines that intersect in the center of the circle layer.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>drawLayer<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CALayer <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>layer inContext<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGContextRef<span style="color: #002200;">&#41;</span>context;
<span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span> layer <span style="color: #002200;">==</span> needleLayer <span style="color: #002200;">&#41;</span>
  <span style="color: #002200;">&#123;</span>
      CGMutablePathRef path <span style="color: #002200;">=</span> CGPathCreateMutable<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;
&nbsp;
      CGPathMoveToPoint<span style="color: #002200;">&#40;</span>path,<span style="color: #a61390;">NULL</span>, <span style="color: #002200;">&#91;</span>view bounds<span style="color: #002200;">&#93;</span>.size.width<span style="color: #002200;">/</span><span style="color: #2400d9;">2.0</span>, <span style="color: #2400d9;">0.0</span><span style="color: #002200;">&#41;</span>;
      CGPathAddLineToPoint<span style="color: #002200;">&#40;</span>path, <span style="color: #a61390;">NULL</span>, <span style="color: #002200;">&#91;</span>view bounds<span style="color: #002200;">&#93;</span>.size.width<span style="color: #002200;">/</span><span style="color: #2400d9;">2.0</span>, <span style="color: #002200;">&#91;</span>view bounds<span style="color: #002200;">&#93;</span>.size.height<span style="color: #002200;">&#41;</span>;
&nbsp;
      CGPathMoveToPoint<span style="color: #002200;">&#40;</span>path,<span style="color: #a61390;">NULL</span>, <span style="color: #2400d9;">0.0</span>, <span style="color: #002200;">&#91;</span>view bounds<span style="color: #002200;">&#93;</span>.size.height<span style="color: #002200;">/</span><span style="color: #2400d9;">2.0</span><span style="color: #002200;">&#41;</span>;
      CGPathAddLineToPoint<span style="color: #002200;">&#40;</span>path, <span style="color: #a61390;">NULL</span>, <span style="color: #002200;">&#91;</span>view bounds<span style="color: #002200;">&#93;</span>.size.width, <span style="color: #002200;">&#91;</span>view bounds<span style="color: #002200;">&#93;</span>.size.height<span style="color: #002200;">/</span><span style="color: #2400d9;">2.0</span><span style="color: #002200;">&#41;</span>;
&nbsp;
      CGColorRef black <span style="color: #002200;">=</span>
              CGColorCreateGenericRGB<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0.0</span>, <span style="color: #2400d9;">0.0</span>, <span style="color: #2400d9;">0.0</span>, <span style="color: #2400d9;">1.0</span><span style="color: #002200;">&#41;</span>;
      CGContextSetStrokeColorWithColor<span style="color: #002200;">&#40;</span>context, black<span style="color: #002200;">&#41;</span>;
      CFRelease<span style="color: #002200;">&#40;</span>black<span style="color: #002200;">&#41;</span>;
&nbsp;
      CGContextBeginPath<span style="color: #002200;">&#40;</span>context<span style="color: #002200;">&#41;</span>;
      CGContextAddPath<span style="color: #002200;">&#40;</span>context, path<span style="color: #002200;">&#41;</span>;
&nbsp;
      CGContextSetLineWidth<span style="color: #002200;">&#40;</span>context, <span style="color: #2400d9;">3.0</span><span style="color: #002200;">&#41;</span>;
&nbsp;
      CGContextStrokePath<span style="color: #002200;">&#40;</span>context<span style="color: #002200;">&#41;</span>;
&nbsp;
      CFRelease<span style="color: #002200;">&#40;</span>path<span style="color: #002200;">&#41;</span>;
&nbsp;
  <span style="color: #002200;">&#125;</span>  
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<h2>Retaining The Rotation Position</h2>
<p>There are two parameters of an animation that must be set otherwise the layer transform will just revert back to the original rotation. These two lines of code in our animation creation code ensure that what you see remains <em>sticky</em> when the value is changed.</p>

<div class="wp_syntax"><div class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span>animation setRemovedOnCompletion<span style="color: #002200;">:</span><span style="color: #a61390;">NO</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>animation setFillMode<span style="color: #002200;">:</span>kCAFillModeForwards<span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>Now, when the slider moves, the vertical and horizontal lines will stay in the correct rotation position. If you comment those two lines of code out in the demo project, you will see that while the rotation layer animates, it jumps right back to its original rotation as soon as the animation completes.</p>
<h2>Conclusion</h2>
<p>You will likely find many uses for this type of control. You could of course control the rotation based upon some other value or control other than a slider, but this code demonstrates how simple it is to rotate a layer based upon user input. Until next time.</p>
<p><a href='http://www.cimgf.com/wp-content/uploads/2008/10/layerrotate.zip'><img src="http://www.cimgf.com/wp-content/uploads/2008/03/xcode.png" alt="xcode.png" border="0" width="64"/><br />Layer Rotate Demo Project</a></p>

<p><a href="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?a=RCoVcJ"><img src="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?i=RCoVcJ" border="0"></img></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/10/25/core-animation-tutorial-slider-based-layer-rotation/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Announcement: Marcus will be a Panelist at O’Reilly’s iPhoneLive conference</title>
		<link>http://www.cimgf.com/2008/10/04/announcement-marcus-will-be-a-panelist-at-oreillys-iphonelive-conference/</link>
		<comments>http://www.cimgf.com/2008/10/04/announcement-marcus-will-be-a-panelist-at-oreillys-iphonelive-conference/#comments</comments>
		<pubDate>Sat, 04 Oct 2008 16:34:50 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=313</guid>
		<description><![CDATA[Now that the NDA has been lifted we can all finally come out of the closet :)
If you have not heard, O&#8217;Reilly is hosting a conference on November 18, 2008 to discuss all things iPhone.  I have been invited to attend the conference as a Panelist.
Please come and join the conference, if nothing else, [...]]]></description>
			<content:encoded><![CDATA[<p>Now that the NDA has been lifted we can all finally come out of the closet :)</p>
<p>If you have not heard, O&#8217;Reilly is hosting a conference on November 18, 2008 to discuss all things iPhone.  I have been invited to attend the conference as a Panelist.</p>
<p>Please come and join the conference, if nothing else, to heckle me :)</p>
<p><a href='http://en.oreilly.com/iphonelive2008/public/content/home'>iPhone Live</a></p>
<p>The list of speakers (as opposed to panelists), is quite impressive and definitely worth the trip.</p>
<p><a href='http://en.oreilly.com/iphonelive2008/public/schedule/speakers'>Speakers</a></p>

<p><a href="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?a=MHXEDF"><img src="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?i=MHXEDF" border="0"></img></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/10/04/announcement-marcus-will-be-a-panelist-at-oreillys-iphonelive-conference/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Cocoa Touch Tutorial: iPhone Application Example</title>
		<link>http://www.cimgf.com/2008/10/01/cocoa-touch-tutorial-iphone-application-example/</link>
		<comments>http://www.cimgf.com/2008/10/01/cocoa-touch-tutorial-iphone-application-example/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 15:34:34 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
		
		<category><![CDATA[Cocoa Touch]]></category>

		<category><![CDATA[Objective-C]]></category>

		<category><![CDATA[iPhone]]></category>

		<category><![CDATA[iPod Touch]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=131</guid>
		<description><![CDATA[Similar to one of my first blog posts on building a basic application for Mac OS X using xcode 3.0, I am going to explain for beginning iPhone/iPod Touch developers how to build the most basic Cocoa Touch application using Interface Builder and an application delegate in xcode 3.1. This tutorial post is really to [...]]]></description>
			<content:encoded><![CDATA[<p>Similar to one of my first blog posts on building a basic application for Mac OS X using xcode 3.0, I am going to explain for beginning iPhone/iPod Touch developers how to build the most basic Cocoa Touch application using Interface Builder and an application delegate in xcode 3.1. This tutorial post is really to provide a quick how-to. I won&#8217;t go into any depth explaining why things are done the way they are done, but this should help you get up and running with your first application pretty quickly so that you too can clog the App Store with useless superfluous apps (kidding&#8230; just kidding).</p>
<p>If you are a visual learner, it may be helpful to you to instead watch a video presentation of this tutorial. I&#8217;ve posted it on the site, but you&#8217;ll have to click the link to see my <a href="http://www.cimgf.com/videos/iphonetutorial/">Cocoa Touch Video Tutorial</a>.<br />
<span id="more-131"></span><br />
Understanding Cocoa programming is much simpler if you learn MVC, <strong>Model, View, Controller</strong>. You can probably step through code examples and figure some things out without learning MVC, but I wouldn&#8217;t recommend it. Go Google it and read up on it.</p>
<p>I will say as an introduction to MVC for those who are not familiar that it should probably be called <strong>(Model <--> Controller <--> View)</strong> or <strong>(View <--> Controller <--> Model)</strong> as the controller always sits between the other two. Your controller is either telling your model to update its data or it is telling the view to update its display. That&#8217;s the crux of the whole paradigm. The details run much deeper, but that&#8217;s how I will nutshell it for you.</li>
</ul>
<h1>Create Your Application</h1>
<p>Let&#8217;s get started. Create a Cocoa Application using the following steps:</p>
<ol>
<li>Select <strong>File > New Project&#8230;</strong>, under the <em>iPhone OS</em> templates choose <em>Window-Based Application</em> in the ensuing dialog. Click <strong>Choose&#8230;</strong></li>
<p>
<a href='http://www.cimgf.com/wp-content/uploads/2008/07/new-project.png' rel='lightbox'><img src="http://www.cimgf.com/wp-content/uploads/2008/07/new-project-276x300.png" alt="iPhone Project Templates" title="iPhone Project Templates" width="276" height="300" class="alignleft size-medium wp-image-146" /></a></p>
<li>Enter &#8216;Basic iPhone App&#8217; as the project name. Click <strong>Save</strong></li>
</ol>
<p>You should see a project workspace like the following:</p>
<p><a href='http://www.cimgf.com/wp-content/uploads/2008/07/basic-iphone-app.png' rel='lightbox'><img src="http://www.cimgf.com/wp-content/uploads/2008/07/basic-iphone-app-300x212.png" alt="Basic iPhone Application" title="Basic iPhone Application" width="300" height="212" class="alignleft size-medium wp-image-141" /></a></p>
<p>The next thing you should do is create a class to act as your controller or delegate.</p>
<h1>Delegate == Controller</h1>
<p>The words delegate and controller can be used synonymously. You&#8217;ll see later that we delegate the work of the different controls we create in Interface Builder to a delegate or controller class. In the iPhone template projects, this application delegate is created for you. Our app delegate has been named <em>Basic_iPhone_AppAppDelegate</em>.</p>
<p>In our app delegate class we need to add what Cocoa developers refer to as <em>outlets</em> and <em>actions</em>. I could spend an entire post explaining these two things in depth, but for the sake of brevity and walking you through the steps to build your first application, the definition will have to suffice.</p>
<blockquote><p>
Outlets represent controls in your user interface that can have some action performed upon them. Action are functions in your code that are connected to controls in your user interface such as a button or a drop down list. When connected to a button for instance, the action code will be run when the user clicks the button.</p></blockquote>
<p>In xcode, open your app delegate header file <em>Basic_iPhone_AppAppDelegate.h</em>. Add an outlet for the text field and the label below the window outlet as in the following snippet:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> Basic_iPhone_AppAppDelegate <span style="color: #002200;">:</span> <span style="color: #400080;">NSObject</span> &lt;UIApplicationDelegate&gt; <span style="color: #002200;">&#123;</span>
    IBOutlet UIWindow <span style="color: #002200;">*</span>window;
    IBOutlet UITextField <span style="color: #002200;">*</span>textField;
    IBOutlet UILabel <span style="color: #002200;">*</span>label;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>You will also want to add an action that will be performed when our button is clicked. Add that below the property for our window:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #a61390;">@interface</span> Basic_iPhone_AppAppDelegate <span style="color: #002200;">:</span> <span style="color: #400080;">NSObject</span> &lt;UIApplicationDelegate&gt; <span style="color: #002200;">&#123;</span>
    IBOutlet UIWindow <span style="color: #002200;">*</span>window;
    IBOutlet UITextField <span style="color: #002200;">*</span>textField;
    IBOutlet UILabel <span style="color: #002200;">*</span>label;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UIWindow <span style="color: #002200;">*</span>window;
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>click<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender;</pre></td></tr></table></div>

<li>Now switch over to the implementation file, <em>Basic_iPhone_AppAppDelegate.m</em>. Add the <em>click:</em> action below our <em>applicationDidFinishLaunching:</em> function:

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>applicationDidFinishLaunching<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIApplication <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>application <span style="color: #002200;">&#123;</span>	
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Override point for customization after app launch	</span>
    <span style="color: #002200;">&#91;</span>window makeKeyAndVisible<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>click<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender;
<span style="color: #002200;">&#123;</span>
&nbsp;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>
We will actually add some code to do something in the <em>click:</em> action handler, but first we need to hook it up to the user interface in Interface Builder.
</li>
<p>
</ol>
<h1>Interface Builder And Controller/Delegate Implementation</h1>
<p>Now that you&#8217;ve specified the outlets&#8211;a <em>UITextField</em> and a <em>UILabel</em> and an action called <em>click:</em>, you will see these items available for connecting to the UI in Interface builder. Let&#8217;s open Interface Builder and make the connections we need using the following steps:</p>
<ol>
<li>In your xcode workspace, expand the folder in the tree view called <strong>Resources</strong> and double click the file called &#8216;MainMenu.xib&#8217;.<br />
<blockquote><p><strong>Note:</strong>: A <em>.xib</em> is a <em>.nib</em> that uses XML for the internal data structure.</p></blockquote>
<p>
This will open the <em>xib</em> file in Interface Builder</p>
<li>Once Interface Builder loads, you will notice that there is an object representation of our app delegate in the <em>MainWindow.xib</em> window. This is the object you will use to create connections for your actions and outlets.
<p><a href='http://www.cimgf.com/wp-content/uploads/2008/07/mainwindowxib.png' rel='lightbox'><img src="http://www.cimgf.com/wp-content/uploads/2008/07/mainwindowxib-300x190.png" alt="MainWindow.xib" title="MainWindow.xib" width="300" height="190" class="alignnone size-medium wp-image-145" /></a></p>
</li>
</ol>
<h1>Design The User Interface</h1>
<p>Now you simply need to add the controls to the main window in Interface Builder and then we can connect the <em>action</em> and <em>outlet</em> accordingly. To finish the interface, complete the following steps:</p>
<ol>
<li>Drag a <em>TextField</em>, a <em>Label</em>, and a <em>Button</em> to the main window so that the user interface looks like the screenshot below:
<p><a href='http://www.cimgf.com/wp-content/uploads/2008/07/ibwindow.png' rel='lightbox'><img src="http://www.cimgf.com/wp-content/uploads/2008/07/ibwindow-191x300.png" alt="iPhone Application UI" title="iPhone Application UI" width="191" height="300" class="alignleft size-medium wp-image-143" /></a></p>
<li><strong>Control-Click</strong> and drag from the <em>Button</em> to your app delegate object in the &#8216;MainWindow.xib&#8217; window.
<p><a href='http://www.cimgf.com/wp-content/uploads/2008/07/buttonconnect.png' rel='lightbox'><img src="http://www.cimgf.com/wp-content/uploads/2008/07/buttonconnect-300x247.png" alt="Button Connection" title="Button Connection" width="300" height="247" class="alignleft size-medium wp-image-142" /></a></p>
<p>
A pop-up will display. Select <em>click:</em></p>
</li>
<li><strong>Control-Click</strong> the app delegate object and drag it to the text field in the main window.
<p><a href='http://www.cimgf.com/wp-content/uploads/2008/07/textfieldconnect.png' rel='lightbox'><img src="http://www.cimgf.com/wp-content/uploads/2008/07/textfieldconnect-300x248.png" alt="Textfield Connection" title="Textfield Connection" width="300" height="248" class="alignleft size-medium wp-image-147" /></a></p>
<p>
A pop-up will display. Select <em>textField</em></p>
</li>
<li><strong>Control-Click</strong> the app delegate object and drag it to the label in the main window.
<p><a href='http://www.cimgf.com/wp-content/uploads/2008/07/labelconnect.png' rel='lightbox'><img src="http://www.cimgf.com/wp-content/uploads/2008/07/labelconnect-300x244.png" alt="Label Connection" title="Label Connection" width="300" height="244" class="alignleft size-medium wp-image-144" /></a></p>
<p>A pop-up will display. Select <em>label</em>
</li>
</ol>
<p>That&#8217;s it for Interface Builder. You can quit interface builder and return to xcode. We have one more piece of code to add and then our application will be finished.</p>
<h1>Finishing Up</h1>
<p>When the button is clicked, it will simply grab the text from the text field and place it into the label. That&#8217;s all the application does. Here&#8217;s the code you need. Just make your implementation of the <em>click:</em> action in the <em>Basic_iPhone_AppAppDelegate.m</em> file look like this:<br />
</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>click<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender;
<span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span>label setText<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>textField text<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Notice we are grabbing the text from the text field, and setting the text in our label with it. Now all you need to do is click &#8220;Build and Go&#8221;. When the application runs the <em>iPhone Simulator</em> will be started. You will see the application load. Type some text into the text field and click the <strong>Change</strong> button. You will see the label update with the text from the text field.</p>
<h1>Next Steps</h1>
<p>This tutorial has just scratched the surface. It&#8217;s is intended to get you going quickly. For a more in-depth path to gaining a deeper understanding of iPhone development, take a look at Apple&#8217;s, <a href="https://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhone101/Articles/chapter_1_section_1.html">Your First iPhone Application</a>. You will need to log in with your ADC account to see the article, but it is definitely worth while.</p>
<h1>Conclusion</h1>
<p>The limit with iPhone development is really just your imagination. It is an extremely fun platform to develop on and the resulting applications are very rewarding. Have fun with it and learn as much as you can. Just do me a favor and don&#8217;t clog the App Store with any more flashlight apps or tip calculators&#8230; Seriously ;-) . Until next time.</p>
<p><a href='http://www.cimgf.com/wp-content/uploads/2008/10/basiciphoneapp.zip'><img src="http://www.cimgf.com/wp-content/uploads/2008/03/xcode.png" alt="xcode.png" border="0" width="64"/><br />Basic iPhone Application Demo Project</a></p>

<p><a href="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?a=6FjJCO"><img src="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?i=6FjJCO" border="0"></img></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/10/01/cocoa-touch-tutorial-iphone-application-example/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Core Animation Tutorial: Core Animation And Quartz Composer (QCCompositionLayer)</title>
		<link>http://www.cimgf.com/2008/09/24/core-animation-tutorial-core-animation-and-quartz-composer-qccompositionlayer/</link>
		<comments>http://www.cimgf.com/2008/09/24/core-animation-tutorial-core-animation-and-quartz-composer-qccompositionlayer/#comments</comments>
		<pubDate>Wed, 24 Sep 2008 16:18:16 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
		
		<category><![CDATA[Cocoa]]></category>

		<category><![CDATA[Core Animation]]></category>

		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=289</guid>
		<description><![CDATA[Last night at NSCoder night, Fraser Hess was asking question about being able to draw in a Quartz Composer View (QCView) about which none of the rest of us had any knowledge or experience. As I&#8217;ve been doing a lot with Core Animation lately, I asked him if it was possible to just make the [...]]]></description>
			<content:encoded><![CDATA[<p>Last night at NSCoder night, Fraser Hess was asking question about being able to draw in a Quartz Composer View (QCView) about which none of the rest of us had any knowledge or experience. As I&#8217;ve been doing a lot with Core Animation lately, I asked him if it was possible to just make the view layer backed and start adding layers to it. Fraser hasn&#8217;t worked with Core Animation much yet, so he was unsure. The other three of us set to looking at docs and making demo apps. The race was on&#8230; Oh. It&#8217;s not a race? Sorry about that. I thought we were practicing for Iron Coder&#8230;<br />
<span id="more-289"></span><br />
My first attempt to get a QCView working succeeded. I was able to display a Quartz Composition in a window, but then I decided to try to make the QCView layer-backed like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>window contentView<span style="color: #002200;">&#93;</span> setWantsLayer<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>qcView setWantsLayer<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
&nbsp;
CATextLayer <span style="color: #002200;">*</span>text <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>CATextLayer layer<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>text setString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;hello World&quot;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span>text setFrame<span style="color: #002200;">:</span>NSRectToCGRect<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>qcView frame<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>qcView layer<span style="color: #002200;">&#93;</span> addSublayer<span style="color: #002200;">:</span>text<span style="color: #002200;">&#93;</span>;</pre></td></tr></table></div>

<p>This code would allow the text layer to show up, however, the Quartz Composition was gone and all I got was a gray window with the &#8220;hello World&#8221; text on it.</p>
<h2>Two Heads Better Than One</h2>
<p>This is what I love about NSCoder Night. You get some Cocoa geeks together and the collective wisdom starts this synergy where we can bounce things off each other and a solution emerges.</p>
<p>Chad, in the mean time, had been searching the web for some examples and at about the time I started to wonder if there was a Core Animation specific layer for Quartz Compositions, he said, &#8220;QCCompositionLayer&#8221;. Marcus and I were both at that point thinking, &#8220;ah, I should have thought of that since there are Core Animation layers to do everything else media related.&#8221;</p>
<p>I then went to town slinging some code and here is what I came up with:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>awakeFromNib;
<span style="color: #002200;">&#123;</span>
  <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>window contentView<span style="color: #002200;">&#93;</span> setWantsLayer<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  QCCompositionLayer <span style="color: #002200;">*</span>layer <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>QCCompositionLayer alloc<span style="color: #002200;">&#93;</span> 
            initWithFile<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;/Developer/Examples/Quartz Composer/Plugins/OpticalFlow/Teapotii.qtz&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #002200;">&#91;</span>layer setFrame<span style="color: #002200;">:</span>NSRectToCGRect<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>window contentView<span style="color: #002200;">&#93;</span> frame<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  CATextLayer <span style="color: #002200;">*</span>text <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>CATextLayer layer<span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>text setString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;hello World&quot;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>text setFrame<span style="color: #002200;">:</span>NSRectToCGRect<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>window contentView<span style="color: #002200;">&#93;</span> frame<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #002200;">&#91;</span>ayer addSublayer<span style="color: #002200;">:</span>text<span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>window contentView<span style="color: #002200;">&#93;</span> layer<span style="color: #002200;">&#93;</span> addSublayer<span style="color: #002200;">:</span>layer<span style="color: #002200;">&#93;</span>;    
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>I got rid of the QCView altogether and just added the Quartz Composer layer to the sublayers of the window&#8217;s content view. The Quartz Composition in a QCCompositionLayer begins to play automatically, so really this code is all there is to it. And notice that the text overlay works as well. You could really add anything you wanted in a Core Animation layer at this point.</p>
<h2>Your Own Composition</h2>
<p>If you&#8217;re anything like me this will whet your appetite for playing with some very cool technology. I decided to create my own Quartz Composition and include that in the demo project. The demo composition takes the vide input of your iSight camera and applies the image to each side of a cube. It then rotates the cube. Creating the composition was pretty easy with a cursory reading of Apple&#8217;s <a href="http://developer.apple.com/documentation/GraphicsImaging/Conceptual/QuartzComposerUserGuide/qc_intro/chapter_1_section_1.html">Quartz Composer User Guide</a>. It&#8217;s quite helpful.</p>
<p>You can take a look at the Quartz Composition in Quartz Composer. The <a href='http://www.cimgf.com/wp-content/uploads/2008/09/caquartzcomposition.zip'>demo application</a> has two .qtz files in it. You can just double click either of those from the Finder to see what I did. The one I&#8217;m using in the demo app is the one called &#8220;VideoCub.qtz&#8221;. You can switch it in the code to see the other one as well, which is a quad of four iSight inputs. </p>
<div id="attachment_294" class="wp-caption alignleft" style="width: 160px"><a href="http://www.cimgf.com/wp-content/uploads/2008/09/vidcubeeditor.jpg" rel='lightbox'><img src="http://www.cimgf.com/wp-content/uploads/2008/09/vidcubeeditor-150x150.jpg" alt="VideoCube QC Editor" title="VideoCube QC Editor" width="150" height="150" class="size-thumbnail wp-image-294" /></a><p class="wp-caption-text">VideoCube QC Editor</p></div>
<div id="attachment_297" class="wp-caption alignleft" style="width: 310px"><a href="http://www.cimgf.com/wp-content/uploads/2008/09/qclayer.jpg" rel='lightbox'><img src="http://www.cimgf.com/wp-content/uploads/2008/09/qclayer-300x237.jpg" alt="Quartz Composer Layer" title="Quartz Composer Layer" width="300" height="237" class="size-medium wp-image-297" /></a><p class="wp-caption-text">Quartz Composer Layer</p></div>
<p>You can see I added a CATextLayer to the QCCompositionLayer which displays the words, &#8220;hello World&#8221;. I also applied a Gaussian blur filter to the whole thing so you can see how easy it is to add filters as well. Here is *all* of the code needed to make this work.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>awakeFromNib;
<span style="color: #002200;">&#123;</span>
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>window contentView<span style="color: #002200;">&#93;</span> setWantsLayer<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>path <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSBundle</span> mainBundle<span style="color: #002200;">&#93;</span> 
                      pathForResource<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;VideoCube&quot;</span> 
                      ofType<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;qtz&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
    QCCompositionLayer <span style="color: #002200;">*</span>layer <span style="color: #002200;">=</span> 
        <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>QCCompositionLayer alloc<span style="color: #002200;">&#93;</span> initWithFile<span style="color: #002200;">:</span>path<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #002200;">&#91;</span>layer setFrame<span style="color: #002200;">:</span>NSRectToCGRect<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>window contentView<span style="color: #002200;">&#93;</span> frame<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
    CATextLayer <span style="color: #002200;">*</span>text <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>CATextLayer layer<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>text setString<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;hello World&quot;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>text setFrame<span style="color: #002200;">:</span>NSRectToCGRect<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>window contentView<span style="color: #002200;">&#93;</span> frame<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>layer addSublayer<span style="color: #002200;">:</span>text<span style="color: #002200;">&#93;</span>;
&nbsp;
    CIFilter <span style="color: #002200;">*</span>blurFilter <span style="color: #002200;">=</span> 
    <span style="color: #002200;">&#91;</span>CIFilter filterWithName<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;CIGaussianBlur&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #002200;">&#91;</span>blurFilter setDefaults<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>blurFilter setValue<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithFloat<span style="color: #002200;">:</span><span style="color: #2400d9;">2.0</span><span style="color: #002200;">&#93;</span> 
                  forKey<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;inputRadius&quot;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>blurFilter setName<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;blur&quot;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #002200;">&#91;</span>layer setFilters<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span><span style="color: #400080;">NSArray</span> arrayWithObject<span style="color: #002200;">:</span>blurFilter<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
&nbsp;
    <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>window contentView<span style="color: #002200;">&#93;</span> layer<span style="color: #002200;">&#93;</span> addSublayer<span style="color: #002200;">:</span>layer<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>What&#8217;s even more exciting to me is that if you know a bit of OpenGL, you can do all kinds of other manipulations of the image since QCCompositionLayer inherits from CAOpenGLLayer. Take a close look at -drawInCGLContext in the CAOpenGLLayer API docs. There is a ton of great potential there.</p>
<h2>Conclusion</h2>
<p>The conclusion is that Quartz Compositions are very cool and they are now even cooler since you can work with them in Core Animation. Take a look a the Quartz Composer guide and start building your own compositions that you can easily incorporate into your Core Animation based applications. Until next time.</p>
<p><a href='http://www.cimgf.com/wp-content/uploads/2008/09/caquartzcomposition.zip'><img src="http://www.cimgf.com/wp-content/uploads/2008/03/xcode.png" alt="xcode.png" border="0" width="64"/><br />Quartz Composition Layer Demo Project</a></p>

<p><a href="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?a=fP0GeM"><img src="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?i=fP0GeM" border="0"></img></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/09/24/core-animation-tutorial-core-animation-and-quartz-composer-qccompositionlayer/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Cocoa Tutorial: Adding Plugins to a Cocoa Application</title>
		<link>http://www.cimgf.com/2008/09/17/cocoa-tutorial-adding-plugins-to-a-cocoa-application/</link>
		<comments>http://www.cimgf.com/2008/09/17/cocoa-tutorial-adding-plugins-to-a-cocoa-application/#comments</comments>
		<pubDate>Wed, 17 Sep 2008 17:45:11 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
		
		<category><![CDATA[Advanced]]></category>

		<category><![CDATA[Cocoa]]></category>

		<category><![CDATA[Frameworks]]></category>

		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=272</guid>
		<description><![CDATA[A couple of weeks ago we discussed how to build frameworks and how to bundle them with a Cocoa application.  This week we are going to build on that knowledge and add Plug-ins to a Cocoa application.

Why are these topics linked?
Generally, there are a few ways to add plug-ins to a Cocoa application.
Scriptable plug-ins
Scriptable [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of weeks ago we discussed <a href="http://www.cimgf.com/2008/09/04/cocoa-tutorial-creating-your-very-own-framework/">how to build frameworks and how to bundle them with a Cocoa application</a>.  This week we are going to build on that knowledge and add Plug-ins to a Cocoa application.</p>
<p><span id="more-272"></span></p>
<h2>Why are these topics linked?</h2>
<p>Generally, there are a few ways to add plug-ins to a Cocoa application.</p>
<h3>Scriptable plug-ins</h3>
<p>Scriptable plug-ins are probably the easiest to add to an application.  They exist in a known location where the application can load them and run them in the appropriate virtual machine.  This makes them fairly easy to construct even though the code to run them may be rather complicated.</p>
<h3>Publishing a Formal Protocol Plug-ins Interface</h3>
<p>This one is a bit more complicated.  The developer (you and me) publish a formal protocol that the plug-ins must adhere to.  This design works rather well but does not allow us, the application developer, to impart any functionality to the plug-ins easily.</p>
<h3>Publishing an Informal Protocol Plug-ins Interface</h3>
<p>This is very similar to the formal plug-ins above but a little more tricky.  Since the protocol is informal, we have to test for each method that we want to use in the plug-ins before we can use it.  Again, it does not make it very easy for us to impart functionality to the plug-ins.</p>
<h3>Publishing a Base Class Plug-ins Interface</h3>
<p>This is the hardest option I have found so far.  Not only do we have to give our plug-ins developers a header file but something to actually compile against.  However, with a base class we can easily impart functionality to our plug-ins without the plug-ins developer having to jump through <em>too many</em> hoops.</p>
<p>Creating a base class solution is where frameworks come in.  It makes it fairly trivial to hand off a base class to plug-ins developers when we give them a framework.  Therefore, we are going to add one class to the plug-ins we wrote previously with the following header:</p>

<div class="wp_syntax"><div class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &lt;Cocoa/Cocoa.h&gt;</span>
&nbsp;
<span style="color: #a61390;">@interface</span> AbstractPlugin <span style="color: #002200;">:</span> <span style="color: #400080;">NSObject</span> 
<span style="color: #002200;">&#123;</span>
&nbsp;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>name;
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>fire<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender;
&nbsp;
<span style="color: #a61390;">@end</span></pre></div></div>

<p>And since I like to make it stupidly easy for people, we are going to use the following implementation of the base &#8220;abstract&#8221; class:</p>

<div class="wp_syntax"><div class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &quot;AbstractPlugin.h&quot;</span>
&nbsp;
<span style="color: #6e371a;">#define kErrFormat @&quot;%s not implemented in subclass %@&quot;</span>
<span style="color: #6e371a;">#define kExceptName @&quot;CIMGF&quot;</span>
&nbsp;
<span style="color: #a61390;">@implementation</span> AbstractPlugin
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>name;
<span style="color: #002200;">&#123;</span>
  <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>reason <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span>kErrFormat, 
    _cmd, <span style="color: #002200;">&#91;</span>self class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">@throw</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSException</span> exceptionWithName<span style="color: #002200;">:</span>kExceptName 
                                 reason<span style="color: #002200;">:</span>reason 
                               userInfo<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>fire<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender;
<span style="color: #002200;">&#123;</span>
  <span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span> reason <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSString</span> stringWithFormat<span style="color: #002200;">:</span>kErrFormat, 
    _cmd, <span style="color: #002200;">&#91;</span>self class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
  <span style="color: #a61390;">@throw</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSException</span> exceptionWithName<span style="color: #002200;">:</span>kExceptName 
                                 reason<span style="color: #002200;">:</span>reason 
                               userInfo<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #a61390;">@end</span></pre></div></div>

<p>For every method that the subclass <strong>must</strong> override the abstract class will throw an exception if it is not overwritten with a polite message explaining what method in which class is missing.</p>
<h2>Building the plug-ins</h2>
<p>A plug-ins is effectively just a bundle, like a framework or an application.  Inside of the bundle is a Contents directory, MacOS directory (where the binary goes) and a Resources directory.</p>
<div style="text-align:center;">
<p><a href="http://www.cimgf.com/wp-content/uploads/2008/09/bundlestructure.png" rel="lightbox" title="Bundle Structure"></p>
<p><img src="http://www.cimgf.com/wp-content/uploads/2008/09/bundlestructure.png" width="50%" alt="Bundle Structure"/></p>
<p></a>
</div>
<p>Xcode has a template for building plug-ins that we can use to get started.  For this first plug-ins, we are going to just add it to our existing project as a new target.</p>
<div style="text-align:center;">
<p><a href="http://www.cimgf.com/wp-content/uploads/2008/09/newproject.png" rel="lightbox" title="New Bundle Project"></p>
<p><img src="http://www.cimgf.com/wp-content/uploads/2008/09/newproject.png" width="50%" alt="New Bundle Project"/></p>
<p></a>
</div>
<p>This new target is very similar to the Framework target that we built previously.  We want to drag it up into the Application&#8217;s target so that it is a dependency; this can also be done from the Get Info window.  We will also want to add the Framework product as a linked framework in the plug-ins.  The end result looks like this.</p>
<div style="text-align:center;">
<p><a href="http://www.cimgf.com/wp-content/uploads/2008/09/targetstructure.png" rel="lightbox" title="Target Structure"></p>
<p><img src="http://www.cimgf.com/wp-content/uploads/2008/09/targetstructure.png" width="50%" alt="Target Structure"/></p>
<p></a>
</div>
<p>Once we have the target set up, it is time to add some code.  Plug-ins needs to have either a main class defined or a main nib defined.  It is this definition that helps determine how to launch the bundle.  In our case, we will want to define a main class which will be explained below.  To define a main class (or nib), we need to look at the properties tab of the target.</p>
<div style="text-align:center;">
<p><a href="http://www.cimgf.com/wp-content/uploads/2008/09/propertiestab.png" rel="lightbox" title="Properties Tab"></p>
<p><img src="http://www.cimgf.com/wp-content/uploads/2008/09/propertiestab.png" width="50%" alt="Properties Tab"/></p>
<p></a>
</div>
<p>The next step is to create the main class for our plug-ins.  Since we are using a base class design for our plug-ins, our main class must extend the AbstractPlugin class and it needs to import the framework directly in the header.  For our example, our plug-ins is going to display a new window on the screen, therefore the header must also include a NSWindow attribute and since we want to programmatically close the window, a -closeWindow: IBAction.</p>

<div class="wp_syntax"><div class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &lt;Cocoa/Cocoa.h&gt;</span>
<span style="color: #6e371a;">#import &lt;Example/Example.h&gt;</span>
&nbsp;
<span style="color: #a61390;">@interface</span> PluginMainClass <span style="color: #002200;">:</span> AbstractPlugin 
<span style="color: #002200;">&#123;</span>
  IBOutlet <span style="color: #400080;">NSWindow</span> <span style="color: #002200;">*</span>mainWindow;
<span style="color: #002200;">&#125;</span>
&nbsp;
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>IBAction<span style="color: #002200;">&#41;</span>closeWindow<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>sender;
&nbsp;
<span style="color: #a61390;">@end</span></pre></div></div>

<p>Note that we are importing the framework which contains the AbstractPlugin super class we built earlier.</p>
<p>Once we have the main class defined it is time to build the user interface to go along with this plug-ins.  It is not a requirement that plug-ins have a user interface, they can be pure code instead.  However for the sake of completeness, we are going to add one for this example.</p>
<div style="text-align:center;">
<p><a href="http://www.cimgf.com/wp-content/uploads/2008/09/pluginwindowstructure.png" rel="lightbox" title="Plug-ins Window Structure"></p>
<p><img src="http://www.cimgf.com/wp-content/uploads/2008/09/pluginwindowstructure.png" width="50%" alt="Plug-ins Window Structure"/></p>
<p></a>
</div>
<p>The structure of the plug-ins nib is simple.  The file owner is the PluginMainClass we wrote previously and there is one window which we bind to the file owner.</p>
<div style="text-align:center;">
<p><a href="http://www.cimgf.com/wp-content/uploads/2008/09/pluginwindow.png" rel="lightbox" title="Plug-ins Window"></p>
<p><img src="http://www.cimgf.com/wp-content/uploads/2008/09/pluginwindow.png" width="50%" alt="Plug-ins Window"/></p>
<p></a>
</div>
<p>The window is also equally simple, just one button that binds back to the file owner&#8217;s -closeWindow: method.</p>
<p>The last step is to add a copy phase to our application.  Like the framework copy phase we built last time, this is a &#8220;Copy Files&#8221; build phase and we need to configure it to copy files to the &#8220;PlugIns&#8221; directory.  This is another top level directory next to Resources and Frameworks.  Once the build phase is added, drag the plug-ins product into that build phase.</p>
<p>With the window and the main class built we can compile the plug-ins and make sure everything is ready for inclusion into our application.  Once the app is built, we should see a copy of the plug-ins inside of the application bundle.  Now it is time to dynamically load the bundle.</p>
<p>The flow of loading bundles dynamically is as follows:</p>
<ol>
<li>Find the paths of the bundles.</li>
<li>Instantiate NSBundle objects for the paths.</li>
<li>Execute the -load method on the bundle.</li>
<li>Retrieve the principal class from the bundle.</li>
<li>Instantiate an object from the principal class.</li>
</ol>
<p>And the code for this is as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSArray</span><span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>loadPlugins
<span style="color: #002200;">&#123;</span>
  <span style="color: #400080;">NSBundle</span> <span style="color: #002200;">*</span>main <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSBundle</span> mainBundle<span style="color: #002200;">&#93;</span>;
  <span style="color: #400080;">NSArray</span> <span style="color: #002200;">*</span>all <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>main pathsForResourcesOfType<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;bundle&quot;</span> 
                                   inDirectory<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;../PlugIns&quot;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #400080;">NSMutableArray</span> <span style="color: #002200;">*</span>availablePlugins <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSMutableArray</span> array<span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #a61390;">id</span> plugin <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
  <span style="color: #400080;">NSBundle</span> <span style="color: #002200;">*</span>pluginBundle <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
&nbsp;
  <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #400080;">NSString</span> <span style="color: #002200;">*</span>path <span style="color: #a61390;">in</span> all<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    pluginBundle <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSBundle</span> bundleWithPath<span style="color: #002200;">:</span>path<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>pluginBundle load<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #a61390;">Class</span> prinClass <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>pluginBundle principalClass<span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>prinClass isSubclassOfClass<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>AbstractPlugin class<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
      <span style="color: #a61390;">continue</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    plugin <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>prinClass alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>availablePlugins addObject<span style="color: #002200;">:</span>plugin<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#91;</span>plugin release<span style="color: #002200;">&#93;</span>, plugin <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
    pluginBundle <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
  <span style="color: #002200;">&#125;</span>
  <span style="color: #a61390;">return</span> availablePlugins;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>In this new method that we have added to the AppDelegate we first get a reference to the main bundle and we then request a path for every file in the PlugIns directory that has an extension of bundle.  With that array in hand we then start to loop over the array and construct a new NSBundle for each path.  Once the bundle is constructed we ask for it to load.  After the load, we grab its principal class, check to make sure we can use it, and construct an object from it.</p>
<p>Since we want to have a list of the loaded plug-ins, we throw this new object into an array that will be returned back from the method.  Once this method is complete we now have every plug-ins dynamically loaded and ready to use.  So lets use them!</p>
<p>We really want to call this method before the application has finished loading, therefore we need to add an -init method to our AppDelegate and load the plug-ins there.  This will guarantee that they are loaded before the UI with some obvious benefits.</p>

<div class="wp_syntax"><div class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>init
<span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>super init<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #a61390;">return</span> <span style="color: #a61390;">nil</span>;
&nbsp;
  <span style="color: #002200;">&#91;</span>self setPlugins<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>self loadPlugins<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
  <span style="color: #a61390;">return</span> self;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>Here are we calling our new -loadPlugins method and setting the returned array into a ivar.  This ivar will then be used by our UI once it loads to display a list of the plug-ins.</p>
<div style="text-align:center;">
<p><a href="http://www.cimgf.com/wp-content/uploads/2008/09/mainappwindow.png" rel="lightbox" title="Main Application Window"></p>
<p><img src="http://www.cimgf.com/wp-content/uploads/2008/09/mainappwindow.png" width="50%" alt="Main Application Window"/></p>
<p></a>
</div>
<p>The main window has a pop up button with a list of the plug-ins using their inherited -name method for display.  When the run button is clicked, our application will find out which plug-ins were selected via the NSArrayController and call the inherited -run: method on the plug-ins with predictable results.</p>
<h2>Conclusion</h2>
<p>For clarity we did leave a few things out of this project.  For example, there is no code for unloading the plug-ins nor do we search the Application Support directory for user added plug-ins.  However these are easy to add based on the code that was included.</p>
<p>I should also note that we used the default extension for these plug-ins.  I would recommend changing this extension to something unique to your application and add that extension (or UTI) to your main application as an accepted file type.  See previous articles here on CIMGF to see how to do each of those.</p>
<p><center><a href="http://www.cimgf.com/wp-content/uploads/2008/09/frameworks.zip" title="Example Project"><img src="http://www.cimgf.com/wp-content/uploads/2008/03/xcode.png" alt="xcode.png" border="0" width="64"/><br/>Example Project</a></center></p>

<p><a href="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?a=Fq3qtm"><img src="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?i=Fq3qtm" border="0"></img></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/09/17/cocoa-tutorial-adding-plugins-to-a-cocoa-application/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Core Animation Tutorial: Rendering QuickTime Movies In A CAOpenGLLayer</title>
		<link>http://www.cimgf.com/2008/09/10/core-animation-tutorial-rendering-quicktime-movies-in-a-caopengllayer/</link>
		<comments>http://www.cimgf.com/2008/09/10/core-animation-tutorial-rendering-quicktime-movies-in-a-caopengllayer/#comments</comments>
		<pubDate>Wed, 10 Sep 2008 15:20:38 +0000</pubDate>
		<dc:creator>Matt Long</dc:creator>
		
		<category><![CDATA[Advanced]]></category>

		<category><![CDATA[Cocoa]]></category>

		<category><![CDATA[Core Animation]]></category>

		<category><![CDATA[Core Video]]></category>

		<category><![CDATA[Objective-C]]></category>

		<category><![CDATA[QTKit]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=219</guid>
		<description><![CDATA[I&#8217;ve been experimenting a great deal lately with OpenGL and QuickTime trying to see how the two technologies work together. It&#8217;s been a bit challenging, but fortunately Apple provides two really great resources&#8211;number one, sample code. I&#8217;ve been able to learn a lot just from the samples they provide in the development tools examples as [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been experimenting a great deal lately with OpenGL and QuickTime trying to see how the two technologies work together. It&#8217;s been a bit challenging, but fortunately Apple provides two really great resources&#8211;number one, sample code. I&#8217;ve been able to learn a lot just from the samples they provide in the development tools examples as well as online. And second, the cocoa-dev and quicktime-api lists are great. Lot&#8217;s of brilliant people there who are willing to share their knowledge. It&#8217;s very helpful, prohibition to discuss the iPhone SDK notwithstanding.</p>
<p>Getting two technologies to work together can be a challenge especially when the bridges between the two are not necessarily clearly laid out in documentation. As I pointed out Apple provides some excellent sample code to help you along, but there is no hand-holding approach to any of it. I actually appreciate that having come from the Windows world as it seems that there all you get sometimes is hand-holding where Microsoft doesn&#8217;t trust you, the developer to figure things out and really own what you&#8217;re doing. But I digress (wouldn&#8217;t be a CIMGF post if I didn&#8217;t dig on MS a bit).<br />
<span id="more-219"></span></p>
<p>Like peanut butter and chocolate, what you get when you put together QuickTime and OpenGL is something greater than either of them left on their own (ok, this is subjective. Not everyone likes peanut butter and chocolate together, but again, I digress).</p>
<p>If you read the <a href="http://developer.apple.com/documentation/GraphicsImaging/Conceptual/CoreVideo/CVProg_Intro/chapter_1_section_1.html">Core Video Programming Guide</a> from Apple, you see they provide the reasons for using Core Video:</p>
<blockquote><p>
CoreVideo is necessary only if you want to manipulate individual video frames. For example, the following types of video processing would require CoreVideo:</p>
<ul>
<li>Color correction or other filtering, such as provided by Core Image filters
<li>Physical transforms of the video images (such as warping, or mapping on to a surface)
<li>Adding video to an OpenGL scene
<li>Adding additional information to frames, such as a visible timecode
<li>Compositing multiple video streams
</ul>
</blockquote>
<p>If all you need to do is display a movie, you should simply use either a QTMovieView or, if you want to stick with the Core Animation route, use a QTMovieLayer. They both function similarly, however, the view provides a lot of features that you won&#8217;t have to implement in the UI yourself such as a scrubber or play/pause buttons. Plus the view is very fast and efficient. I&#8217;m in the process of exploring performance differences between the two, but I will save my comments about that for another post.</p>
<p>For our example code we are most interested in the third point above&#8211;<strong>adding video to an OpenGL scene</strong>. It seems that new QuickTime developers often want to know how to manipulate movie images before displaying them. Often this leads them to pursue adding sub-views to the movie view which can become a big mess. Because we are using OpenGL, doing other drawing on the scene is very fast. I won&#8217;t kid you. OpenGL is a pain. I don&#8217;t know anybody who loves it, but everybody respects it because of its raw speed.</p>
<p>Point number five above&#8211;<strong>compositing multiple video streams</strong>&#8211;is also interesting. While I won&#8217;t be covering it in this post, I will say that it makes a world of difference performance wise if you composite the movies into a OpenGL scene. If you&#8217;ve ever tried to run multiple videos simultaneously in two different views or layers, it can get pretty herky jerky. You can see why it is necessary to use OpenGL instead.</p>
<h2>The OpenGL QuickTime Two Step</h2>
<p>Ok, it actually will take more than two steps, however, when you are working with Core Animation layers things get a whole lot easier than they are for rendering a movie in an NSOpenGLView. Here is what you get for free, as the kids say.</p>
<ul>
<li>You don&#8217;t have to set up the OpenGL context. It is already available for you to send your OpenGL calls to.
<li>The viewport for display is already configured
<li>You don&#8217;t need to set up a display link callback
</ul>
<p>What took over 400 lines of code when rendering a QuickTime movie with no filters to an NSOpengGLView now only takes around 150 lines. Any time you can reduce code to something simpler, it makes life easier. It also makes it much easier to grok, in my opinion.</p>
<p>There really are two primary steps you take when using a CAOpenGLLayer. First you check to see if you should draw. Then, depending upon the answer, drawInCGLContext gets called or doesn&#8217;t. Really thats it. Determining whether or not you should draw depends upon what you are trying to do. In our case, we only want to draw if all of the following are true:</p>
<ul>
<li>The movie is actually playing back
<li>The visual context for the movie has been initialized
<li>The visual context has a new image ready to be rendered
</ul>
<p>If all of these are true, then our call to canDrawInCGLContext returns YES. Here is the code I use to check these contraints in canDrawInCGLContext:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">BOOL</span><span style="color: #002200;">&#41;</span>canDrawInCGLContext<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGLContextObj<span style="color: #002200;">&#41;</span>glContext 
                pixelFormat<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGLPixelFormatObj<span style="color: #002200;">&#41;</span>pixelFormat 
               forLayerTime<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CFTimeInterval<span style="color: #002200;">&#41;</span>timeInterval 
                displayTime<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">const</span> CVTimeStamp <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>timeStamp
<span style="color: #002200;">&#123;</span> 
    <span style="color: #11740a; font-style: italic;">// There is no point in trying to draw anything if our</span>
    <span style="color: #11740a; font-style: italic;">// movie is not playing.</span>
    <span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span> <span style="color: #002200;">&#91;</span>movie rate<span style="color: #002200;">&#93;</span> &lt;<span style="color: #002200;">=</span> <span style="color: #2400d9;">0.0</span> <span style="color: #002200;">&#41;</span>
        <span style="color: #a61390;">return</span> <span style="color: #a61390;">NO</span>;
&nbsp;
    <span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span> <span style="color: #002200;">!</span>qtVisualContext <span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #11740a; font-style: italic;">// If our visual context for our QTMovie has not been set up</span>
        <span style="color: #11740a; font-style: italic;">// we initialize it now</span>
        <span style="color: #002200;">&#91;</span>self setupVisualContext<span style="color: #002200;">:</span>glContext withPixelFormat<span style="color: #002200;">:</span>pixelFormat<span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Check to see if a new frame (image) is ready to be draw at</span>
    <span style="color: #11740a; font-style: italic;">// the time specified.</span>
    <span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span>QTVisualContextIsNewImageAvailable<span style="color: #002200;">&#40;</span>qtVisualContext,timeStamp<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>
    <span style="color: #002200;">&#123;</span>
        <span style="color: #11740a; font-style: italic;">// Release the previous frame</span>
        CVOpenGLTextureRelease<span style="color: #002200;">&#40;</span>currentFrame<span style="color: #002200;">&#41;</span>;
&nbsp;
        <span style="color: #11740a; font-style: italic;">// Copy the current frame into our image buffer</span>
        QTVisualContextCopyImageForTime<span style="color: #002200;">&#40;</span>qtVisualContext,
                                        <span style="color: #a61390;">NULL</span>,
                                        timeStamp,
                                        <span style="color: #002200;">&amp;</span>currentFrame<span style="color: #002200;">&#41;</span>;
&nbsp;
        <span style="color: #11740a; font-style: italic;">// Returns the texture coordinates for the part of the image that should be displayed</span>
        CVOpenGLTextureGetCleanTexCoords<span style="color: #002200;">&#40;</span>
                            currentFrame, 
                            lowerLeft, 
                            lowerRight, 
                            upperRight, upperLeft<span style="color: #002200;">&#41;</span>;
        <span style="color: #a61390;">return</span> <span style="color: #a61390;">YES</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #a61390;">return</span> <span style="color: #a61390;">NO</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>The call to setup the visual context is where we are associating the QuickTime movie itself with a QTVisualContextRef object which is what OpenGL needs to draw the current frame. We will then use this object to load image data into a CVImageBufferRef which can be used for rendering with OpenGL. Here is the code to set up the visual context.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setupVisualContext<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGLContextObj<span style="color: #002200;">&#41;</span>glContext 
           withPixelFormat<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGLPixelFormatObj<span style="color: #002200;">&#41;</span>pixelFormat;
<span style="color: #002200;">&#123;</span>
    OSStatus			    error;
&nbsp;
    <span style="color: #400080;">NSDictionary</span>	    <span style="color: #002200;">*</span>attributes <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
    attributes <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDictionary</span> dictionaryWithObjectsAndKeys<span style="color: #002200;">:</span>
                  <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDictionary</span> dictionaryWithObjectsAndKeys<span style="color: #002200;">:</span>
                   <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithFloat<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>self frame<span style="color: #002200;">&#93;</span>.size.width<span style="color: #002200;">&#93;</span>,
                   kQTVisualContextTargetDimensions_WidthKey,
                   <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithFloat<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>self frame<span style="color: #002200;">&#93;</span>.size.height<span style="color: #002200;">&#93;</span>,
                   kQTVisualContextTargetDimensions_HeightKey, <span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>, 
                  kQTVisualContextTargetDimensionsKey, 
                  <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSDictionary</span> dictionaryWithObjectsAndKeys<span style="color: #002200;">:</span>
                   <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithFloat<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>self frame<span style="color: #002200;">&#93;</span>.size.width<span style="color: #002200;">&#93;</span>, 
                   kCVPixelBufferWidthKey, 
                   <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithFloat<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>self frame<span style="color: #002200;">&#93;</span>.size.height<span style="color: #002200;">&#93;</span>, 
                   kCVPixelBufferHeightKey, <span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>, 
                  kQTVisualContextPixelBufferAttributesKey,
                  <span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Create our quicktimee visual context</span>
    error <span style="color: #002200;">=</span> QTOpenGLTextureContextCreate<span style="color: #002200;">&#40;</span><span style="color: #a61390;">NULL</span>,
                                         glContext,
                                         pixelFormat,
                                         <span style="color: #002200;">&#40;</span>CFDictionaryRef<span style="color: #002200;">&#41;</span>attributes,
                                         <span style="color: #002200;">&amp;</span>qtVisualContext<span style="color: #002200;">&#41;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Associate it with our movie.</span>
    SetMovieVisualContext<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>movie quickTimeMovie<span style="color: #002200;">&#93;</span>,qtVisualContext<span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>Next we check to see if there is an image ready using:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span>QTVisualContextIsNewImageAvailable<span style="color: #002200;">&#40;</span>qtVisualContext,timeStamp<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span></pre></td></tr></table></div>

<p>And then we copy the image to our CVImageBufferRef with:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Copy the current frame into our image buffer</span>
QTVisualContextCopyImageForTime<span style="color: #002200;">&#40;</span>qtVisualContext,
                                <span style="color: #a61390;">NULL</span>,
                                timeStamp,
                                <span style="color: #002200;">&amp;</span>currentFrame<span style="color: #002200;">&#41;</span>;</pre></td></tr></table></div>

<p>Now it&#8217;s all a matter of rendering the frame for the current time stamp.</p>
<h2>But Wait! What TimeStamp?</h2>
<p>If you asked this question, then you are a very astute reader. In order to obtain the next image, we simply passed the CVTimeStamp parameter, <em>timeStamp</em> to our call to QTVisualContextCopyImageForTime. But how do we even have a timestamp? Isn&#8217;t that something we need to get from a display link? If you&#8217;re asking what is a display link at this point, take a look at the <a href="http://developer.apple.com/documentation/GraphicsImaging/Conceptual/CoreVideo/CVProg_Concepts/chapter_2_section_3.html">Core Video Programming Guide</a> which states:</p>
<blockquote><p>
To simplify synchronization of video with a display’s refresh rate, Core Video provides a special timer called a display link. The display link runs as a separate high priority thread, which is not affected by interactions within your application process.</p>
<p>In the past, synchronizing your video frames with the display’s refresh rate was often a problem, especially if you also had audio. You could only make simple guesses for when to output a frame (by using a timer, for example), which didn’t take into account possible latency from user interactions, CPU loading, window compositing and so on. The Core Video display link can make intelligent estimates for when a frame needs to be output, based on display type and latencies.
</p></blockquote>
<p>I will provide a more complete answer to the question in the future as I am still studying it myself, however, I will mention that a display link callback is unnecessary in this context as the CAOpenGLLayer is providing this for us. The timestamp field is all we need in order to get the current frame assuming that the movie is playing back.</p>
<h2>Drawing The Frame</h2>
<p>There is a special group of people who really get OpenGL. I salute all of you to whom this applies. You are amazing. I, however, only write as much of it as necessary and you&#8217;ll see that most of the code I have here is simply a copy and paste from sample code I got from Apple. I am starting to understand it more and more, however, it makes my brain hurt. Here is my drawing code for when a frame is ready to be rendered.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>drawInCGLContext<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGLContextObj<span style="color: #002200;">&#41;</span>glContext 
             pixelFormat<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGLPixelFormatObj<span style="color: #002200;">&#41;</span>pixelFormat 
            forLayerTime<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CFTimeInterval<span style="color: #002200;">&#41;</span>interval 
             displayTime<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">const</span> CVTimeStamp <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>timeStamp
<span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">NSRect</span>    bounds <span style="color: #002200;">=</span> NSRectFromCGRect<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>self bounds<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
&nbsp;
    GLfloat 	minX, minY, maxX, maxY;        
&nbsp;
    minX <span style="color: #002200;">=</span> NSMinX<span style="color: #002200;">&#40;</span>bounds<span style="color: #002200;">&#41;</span>;
    minY <span style="color: #002200;">=</span> NSMinY<span style="color: #002200;">&#40;</span>bounds<span style="color: #002200;">&#41;</span>;
    maxX <span style="color: #002200;">=</span> NSMaxX<span style="color: #002200;">&#40;</span>bounds<span style="color: #002200;">&#41;</span>;
    maxY <span style="color: #002200;">=</span> NSMaxY<span style="color: #002200;">&#40;</span>bounds<span style="color: #002200;">&#41;</span>;
&nbsp;
    glMatrixMode<span style="color: #002200;">&#40;</span>GL_MODELVIEW<span style="color: #002200;">&#41;</span>;
    glLoadIdentity<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;
    glMatrixMode<span style="color: #002200;">&#40;</span>GL_PROJECTION<span style="color: #002200;">&#41;</span>;
    glLoadIdentity<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;
    glOrtho<span style="color: #002200;">&#40;</span> minX, maxX, minY, maxY, <span style="color: #002200;">-</span><span style="color: #2400d9;">1.0</span>, <span style="color: #2400d9;">1.0</span><span style="color: #002200;">&#41;</span>;
&nbsp;
    glClearColor<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0.0</span>, <span style="color: #2400d9;">0.0</span>, <span style="color: #2400d9;">0.0</span>, <span style="color: #2400d9;">0.0</span><span style="color: #002200;">&#41;</span>;	     
    glClear<span style="color: #002200;">&#40;</span>GL_COLOR_BUFFER_BIT<span style="color: #002200;">&#41;</span>;
&nbsp;
    CGRect imageRect <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self frame<span style="color: #002200;">&#93;</span>;
    <span style="color: #11740a; font-style: italic;">// Enable target for the current frame</span>
    glEnable<span style="color: #002200;">&#40;</span>CVOpenGLTextureGetTarget<span style="color: #002200;">&#40;</span>currentFrame<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #11740a; font-style: italic;">// Bind to the current frame</span>
    <span style="color: #11740a; font-style: italic;">// This tells OpenGL which texture we are wanting </span>
    <span style="color: #11740a; font-style: italic;">// to draw so that when we make our glTexCord and </span>
    <span style="color: #11740a; font-style: italic;">// glVertex calls, our current frame gets drawn</span>
    <span style="color: #11740a; font-style: italic;">// to the context.</span>
    glBindTexture<span style="color: #002200;">&#40;</span>CVOpenGLTextureGetTarget<span style="color: #002200;">&#40;</span>currentFrame<span style="color: #002200;">&#41;</span>, 
                  CVOpenGLTextureGetName<span style="color: #002200;">&#40;</span>currentFrame<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
    glMatrixMode<span style="color: #002200;">&#40;</span>GL_TEXTURE<span style="color: #002200;">&#41;</span>;
    glLoadIdentity<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;
    glColor4f<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">1.0</span>, <span style="color: #2400d9;">1.0</span>, <span style="color: #2400d9;">1.0</span>, <span style="color: #2400d9;">1.0</span><span style="color: #002200;">&#41;</span>;
    glBegin<span style="color: #002200;">&#40;</span>GL_QUADS<span style="color: #002200;">&#41;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Draw the quads</span>
    glTexCoord2f<span style="color: #002200;">&#40;</span>upperLeft<span style="color: #002200;">&#91;</span>0<span style="color: #002200;">&#93;</span>, upperLeft<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">1</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
    glVertex2f  <span style="color: #002200;">&#40;</span>imageRect.origin.x, 
                 imageRect.origin.y <span style="color: #002200;">+</span> imageRect.size.height<span style="color: #002200;">&#41;</span>;
    glTexCoord2f<span style="color: #002200;">&#40;</span>upperRight<span style="color: #002200;">&#91;</span>0<span style="color: #002200;">&#93;</span>, upperRight<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">1</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
    glVertex2f  <span style="color: #002200;">&#40;</span>imageRect.origin.x <span style="color: #002200;">+</span> imageRect.size.width, 
                 imageRect.origin.y <span style="color: #002200;">+</span> imageRect.size.height<span style="color: #002200;">&#41;</span>;
    glTexCoord2f<span style="color: #002200;">&#40;</span>lowerRight<span style="color: #002200;">&#91;</span>0<span style="color: #002200;">&#93;</span>, lowerRight<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">1</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
    glVertex2f  <span style="color: #002200;">&#40;</span>imageRect.origin.x <span style="color: #002200;">+</span> imageRect.size.width, 
                 imageRect.origin.y<span style="color: #002200;">&#41;</span>;
    glTexCoord2f<span style="color: #002200;">&#40;</span>lowerLeft<span style="color: #002200;">&#91;</span>0<span style="color: #002200;">&#93;</span>, lowerLeft<span style="color: #002200;">&#91;</span><span style="color: #2400d9;">1</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;
    glVertex2f  <span style="color: #002200;">&#40;</span>imageRect.origin.x, imageRect.origin.y<span style="color: #002200;">&#41;</span>;
&nbsp;
    glEnd<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// This CAOpenGLLayer is responsible to flush</span>
    <span style="color: #11740a; font-style: italic;">// the OpenGL context so we call super</span>
    <span style="color: #002200;">&#91;</span>super drawInCGLContext<span style="color: #002200;">:</span>glContext 
                pixelFormat<span style="color: #002200;">:</span>pixelFormat 
               forLayerTime<span style="color: #002200;">:</span>interval 
                displayTime<span style="color: #002200;">:</span>timeStamp<span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Task the context</span>
    QTVisualContextTask<span style="color: #002200;">&#40;</span>qtVisualContext<span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>

<p>If you&#8217;re not familiar with OpenGL it would help you to know that it&#8217;s all about the current state. What does this mean? Well, simply put, it means that the call you are making right now, applies to whatever state the context is in. These two calls are what are the most important for our purposes.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="objc objc" style="font-family:monospace;">glEnable<span style="color: #002200;">&#40;</span>CVOpenGLTextureGetTarget<span style="color: #002200;">&#40;</span>currentFrame<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
glBindTexture<span style="color: #002200;">&#40;</span>CVOpenGLTextureGetTarget<span style="color: #002200;">&#40;</span>currentFrame<span style="color: #002200;">&#41;</span>, 
                  CVOpenGLTextureGetName<span style="color: #002200;">&#40;</span>currentFrame<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;</pre></td></tr></table></div>

<p>With these two calls we have told OpenGL which texture to use. Now, every subsequent call applies to this texture until the state is changed to something else. So now, when we set a color or draw a quad, it applies to the texture that has been set here.</p>
<h2>Conclusion</h2>
<p>I love both of these technologies, QuickTime and OpenGL. They are so powerful. It&#8217;s harnessing the power that&#8217;s the trick. I&#8217;ve got some other ideas for some related posts that I plan to cover in the weeks to come, but this was a real breakthrough for me. With the help of John Clayton, Jean-Daniel Dupas, and David Duncan on the cocoa-dev list, I was able to get the sample code put together for this post. Feel free to ask questions in the comments. I will do my best to answer, but I&#8217;m still pretty new to these technologies. Write some code yourself and have fun. This is really exciting stuff. Until next time.</p>
<h2>About The Demo Code</h2>
<p><strike>John Clayton has some issues getting the code to work on his Mac Pro. I successfully ran it on  my MacBook Pro, and the family iMac without any issues. Anyhow, we&#8217;re not sure what the problem is, so if you do run into trouble, let me know. Maybe we can figure it out. Meanwhile we&#8217;re investigating it as we have time.</strike></p>
<p><strong>Update:</strong> John Clayton figured it out. Apparently the visual context needs to be reset because the pixel format is not correct on the first run. We just reset the visual context now in the call to -copyCGLContextForPixelFormat and everything seems happy. The demo code has been updated to reflect the change.</p>
<p><a href='http://www.cimgf.com/wp-content/uploads/2008/09/qtglcalayerdemo.zip'><img src="http://www.cimgf.com/wp-content/uploads/2008/03/xcode.png" alt="Quicktime CAOpenGLLayer Demo" title="Quicktime CAOpenGLLayer Demo" width="64" class="aligncenter size-medium wp-image-49" /><br />Quicktime CAOpenGLLayer Demo</a></p>

<p><a href="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?a=hEyZ9w"><img src="http://feeds.feedburner.com/~a/CocoaIsMyGirlfriend?i=hEyZ9w" border="0"></img></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.cimgf.com/2008/09/10/core-animation-tutorial-rendering-quicktime-movies-in-a-caopengllayer/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Cocoa Tutorial: Creating your very own framework</title>
		<link>http://www.cimgf.com/2008/09/04/cocoa-tutorial-creating-your-very-own-framework/</link>
		<comments>http://www.cimgf.com/2008/09/04/cocoa-tutorial-creating-your-very-own-framework/#comments</comments>
		<pubDate>Thu, 04 Sep 2008 18:05:25 +0000</pubDate>
		<dc:creator>Marcus Zarra</dc:creator>
		
		<category><![CDATA[Cocoa]]></category>

		<category><![CDATA[Coding Practice]]></category>

		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.cimgf.com/?p=229</guid>
		<description><![CDATA[There are numerous situations where creating your own framework is advantageous.  Perhaps you have a block of code that you use repeatedly in many different projects.  Perhaps you are building a plug-in system for your application and want the infrastructure to be available both to the application and to any plugins that are [...]]]></description>
			<content:encoded><![CDATA[<p>There are numerous situations where creating your own framework is advantageous.  Perhaps you have a block of code that you use repeatedly in many different projects.  Perhaps you are building a plug-in system for your application and want the infrastructure to be available both to the application and to any plugins that are coded.</p>
<p>A Cocoa framework is another project type in Xcode.  The end result is a bundle, similar to an application bundle.  Inside of this bundle is the compiled code you wrote and any headers that you want exposed.  The headers are important.  Without them, just like any other piece of Objective-C code, it is very hard to code against.</p>
<p><span id="more-229"></span></p>
<h2>Building a Framework in Xcode</h2>
<p>Building a framework within Xcode is straight-forward.  There is already a project template specifically for Cocoa frameworks so that is where we will start.</p>
<div style="text-align:center;"> <a href="http://www.cimgf.com/wp-content/uploads/2008/09/newframework.png" rel="lightbox" title="New Framework Project"><img src="http://www.cimgf.com/wp-content/uploads/2008/09/newframework.png" width="250"alt="New Framework Project" /></a></div>
<p>Once the framework is build, the rest of the code development is almost identical to an application bundle.  C, C++ and Objective-C files can be included along with nibs, xibs, images and just about anything else we would stick into an application bundle.  When the code is complied, the end result is also a bundle, again very similar to an application.  The bundle structure, however, is a bit different and will be discussed in detail below.</p>
<p>Care must be given to the headers that we write and that we expose as part of that framework.  In general, we really only want to expose the headers that users of the framework are going to interact with.  If a header is completely internal to the framework then do not plan on exposing it.  In addition, it is a good idea to have a wrapper header that users can import and gain references to all of the public headers.  Since a framework will undoubtably contain more than one class file, how do we roll all of that up into one header?  One solution I have seen is to create a separate header file and copy all of the interfaces into it.  Unfortunately that solution can become unwieldy very quickly.  My preferred solution is to build a &#8220;wrapper&#8221; header file that imports all of the headers that you want exposed.  This is demonstrated in <i>Code Sample 1</i>.</p>
<hr/>
<small><strong><i>Code Sample 1: Example.h</i></strong></small></p>

<div class="wp_syntax"><div class="code"><pre class="objc objc" style="font-family:monospace;"><span style="color: #6e371a;">#import &quot;ExampleOne.h&quot;</span>
<span style="color: #6e371a;">#import &quot;ExampleTwo.h&quot;</span></pre></div></div>

<p>Once the framework is built but before we distribute it, there are a few tweaks we need to deal with.  First, we need to declare which headers are public and which are project.  There is also an option for private but honestly I cannot see the logic behind them.  If we flag a header as private it gets included in the resulting framework in a directory called &#8220;PrivateHeaders&#8221;.  However, if we flag a header as &#8220;project&#8221; then it is correctly not included in the framework.  Public headers are naturally included in the framework under the Headers directory.</p>
<h2>Which headers should be included</h2>
<p>For some headers, the answer to that question is easy.  However, there are some gotchas that need to be planned around.  If an object is referenced in one of the public headers then its header