<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0"> <channel><title>iOS/Web Developer's Life in Beta</title> <link>http://nachbaur.com</link> <description>Making broken software somewhat less broken</description> <lastBuildDate>Mon, 09 Jan 2012 18:10:15 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/nachbaur" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="nachbaur" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">nachbaur</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><item><title>Core Graphics isn’t scary, honest!</title><link>http://nachbaur.com/blog/core-graphics-isnt-scary-honest</link> <comments>http://nachbaur.com/blog/core-graphics-isnt-scary-honest#comments</comments> <pubDate>Mon, 02 Jan 2012 06:20:29 +0000</pubDate> <dc:creator>Michael Nachbaur</dc:creator> <category><![CDATA[Objective-C]]></category> <category><![CDATA[apple]]></category> <category><![CDATA[Core Animation]]></category> <category><![CDATA[Core Graphics]]></category> <category><![CDATA[development]]></category> <category><![CDATA[iphone]]></category> <category><![CDATA[performance optimization]]></category> <category><![CDATA[Programming]]></category> <guid isPermaLink="false">http://nachbaur.com/?p=724</guid> <description><![CDATA[For anyone who&#8217;s developed exclusively with UIViews on iOS may take the title of this post a bit oddly. &#8220;WHAT?!&#8221; they might say, &#8220;Are you insane? Core Graphics is not only a C-only API, but has confusing function names, and needs way more code to do the same thing I can do in less code [...]]]></description> <content:encoded><![CDATA[<div
class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fcore-graphics-isnt-scary-honest"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fcore-graphics-isnt-scary-honest&amp;source=NachoMan&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6239b17e17b21092b11716b59a2de343&amp;b=2" height="61" width="50" /><br
/> </a></div><p>For anyone who&#8217;s developed exclusively with UIViews on iOS may take the title of this post a bit oddly. &#8220;WHAT?!&#8221; they might say, &#8220;Are you insane? Core Graphics is not only a C-only API, but has confusing function names, and needs way more code to do the same thing I can do in less code in UIView&#8221;.  Yes, they might be right, but there&#8217;s a reason why Core Graphics exists. It&#8217;s FAST!</p><p>But using Core Graphics doesn&#8217;t mean that your code has to be confusing, or that you have to compromise flexibility for performance. You can have your cake and eat it too (aka you can have high-performing code that is easy to read). Read on to see what I mean.<br
/> <span
id="more-724"></span></p><h1>Baby steps in using drawRect:</h1><p>The drawRect: method is your entry point to drawing in Core Graphics, and is (for the most part) the only place where drawing operations can be performed. This is the biggest problem newbies have when getting started with low-level drawing on iOS because they&#8217;re used to being able to add subViews or subLayers arbitrarily in whatever method they happen to be in.</p><p><code>drawRect:</code> is called by the underlying graphics subsystem in its main frame rendering loop.  When it&#8217;s time to draw the next frame, iOS digs through all the views on the screen and checks to see if its content needs to be updated. If it does, then your <code>drawRect:</code> method is called with the appropriate rect that needs to be updated.  It&#8217;s as simple as that.  You get asked to draw your content when, and only when, it needs something from you.</p><h2>Finding your context</h2><p>All drawing operations in Core Graphics utilize a context pointer to keep track of what region your drawing operations will be made to. This is a standard thing you&#8217;ll find in C APIs because without an Object-Oriented &#8220;self&#8221; property easily available, you have to provide some means of providing context.</p><pre class="brush: objc; title: ; notranslate">
- (void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    // Do something with your context
}
</pre><p>From that point on you can use the &#8220;<code>ctx</code>&#8221; variable for all subsequent Core Graphics calls.</p><h2>Saving state</h2><p>If you want to draw anything on the screen, even if it&#8217;s something as simple as a single line, you&#8217;ll need to use several function calls to do so. This is because separate calls are used to set attributes such as the line colour, the line width, any end-cap settings you may want for the corners of your line, and then the actual path that your line will follow.  Core Graphics keeps track of all these different attributes by updating its internal state.</p><p>Think of the drawing state as a pen: you change the tip, you change the colour, and then you can draw many separate lines with the same pen.  But if you forget to change your pen back, you can mess future drawing calls up if you don&#8217;t clean up after yourself.</p><p>To work around problems like this it&#8217;s best to use the <code>CGContextSaveGState</code> and <code>CGContextRestoreGState</code> functions.  Think of it as saving a bookmark or a checkpoint of your current graphics state.  You can then change any drawing attributes you like, you can draw or fill or stroke any path, and when you&#8217;re done you reset the graphics state back to what it was before.</p><p>There is one important catch however: the number of times you call Save and Restore must match perfectly, because otherwise you may screw up the drawing state for whomever is calling your class. This is important because otherwise some really weird garbage may end up getting drawn to your screen.  To get around this, I use a very simple technique that I&#8217;ll show in the code sample below.</p><pre class="brush: objc; title: ; notranslate">
- (void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSaveGState(ctx);
    {
        // Draw whatever you like
    }
    CGContextRestoreGState(ctx);
}
</pre><p>By including a new set of brackets in your code, you give yourself a visual indentation of code that is covered by a set of save and restore calls.</p><h1>Simple drawing using UIView classes</h1><p>There are some fairly simple operations that some people want to do that are made easy by a few simple helper methods provided in a few UIView subclasses. For example, assume you&#8217;re building the next greatest Twitter application and you want to squeeze as much performance out of your feed items as you possibly can.  Obviously rendering text, images, gradients, borders and shadows are fairly expensive operations if you want to handle scrolling through thousands of feed posts at 60fps.</p><p>Fortunately you don&#8217;t have to replace your UIView classes with hundreds of lines of Core Graphics calls. Many of the most common classes like UIImage, UIBezierPath and so on, all provide convenience methods for drawing their content within drawRect: using Core Graphics directly.</p><blockquote><p><b>Update:</b> The original post had a few bugs in it, mostly due to writing this post exclusively from memory during the Christmas holidays.  As a result of some very helpful comments on this post however, I&#8217;ve had to make some changes.  I apologize for the bugs in the first version.</p></blockquote><h2>UIImage drawing</h2><p>We can use UIImage objects to directly draw to a Core Graphics context. Using raw API calls makes for very verbose code, since you&#8217;d have to create a CGImage object, a color-space object, and so forth.  Instead, drawing an image can be as easy as the following.</p><pre class="brush: objc; title: ; notranslate">
- (void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    UIImage *img = [UIImage imageNamed:@&quot;MyImage.png&quot;];
    [img drawInRect:rect];
}
</pre><p>With this technique you have many more options, such as blending and alpha arguments.  There are other methods that let you draw an image at a particular point, drawing a pattern, and so forth.</p><h2>UIBezierPath drawing</h2><p>Often times you might want to show rounded corners on some view, but you only want certain corners to be rounded.  For example lets assume you want to show a container view with only the top two corners rounded.  The most straight-forward strategy is to drop into Core Graphics to render.  While it&#8217;s possible to compose a path using low-level APIs alone, it&#8217;s quite simple to do the following.</p><pre class="brush: objc; title: ; notranslate">
- (void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(ctx, [UIColor blackColor].CGColor);
    CGContextSetLineWidth(ctx, 3);
    UIBezierPath *path;
    path = [UIBezierPath bezierPathWithRoundedRect:rect
                                 byRoundingCorners:(UIRectCornerTopLeft |
                                                    UIRectCornerTopRight)
                                       cornerRadii:10.0];
    [path stroke];
}
</pre><h1>Responding to user input</h1><p>Core Graphics tries to be as efficient as possible, and so it takes some shortcuts on your behalf. For the most part these are exactly what you want and would expect, and come as a pleasant surprise when you come from other platforms.  But there are times that it can get in your way, so knowing in advance what those optimizations are and how to control them helps. And knowing is half the battle…</p><h2>Knowing when your view &#8220;Needs Display&#8221;</h2><p>Your <code>drawRect:</code> method will only be invoked when UIKit feels your content has become stale and needs to be redrawn.  For the most part this typically means your <code>drawRect:</code> method will be called when the view is added to a superview.  Since drawRect is called when the frame is drawn, calling it explicitly won&#8217;t work as you&#8217;d expect, so if some user interaction requires you to redraw your content, there&#8217;s a simple solution for that.</p><p>All UIView objects have a method called &#8220;<code>setNeedsDisplay</code>&#8220;.  Invoking this will toggle a flag inside your object indicating that your view needs to be redrawn upon the next frame. This has several advantages, including the fact that it makes your code very quick; this is because no matter how many times you call it within the same runloop, your frame will still only be redrawn once on the next frame.  Therefore you don&#8217;t have to worry about over-invoking it, ensuring that you can keep your content fresh from wherever your UI logic determine content needs to change.</p><pre class="brush: objc; title: ; notranslate">
- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        CGRect labelRect = CGRectMake(32, CGRectGetHeight(frame) - 32, CGRectGetWidth(frame), 32);
        self.likeLabel = [[[UILabel alloc] initWithFrame:labelRect] autorelease];
        self.likeLabel.font = [UIFont systemFontWithSize:12.0];
        self.likeLabel.autoresizingMask = (UIViewAutoresizingFlexibleTopMargin |
                                           UIViewAutoresizingFlexibleRightMargin);
        [self addSubview:self.likeLabel];
        
        self.likeIcon = [UIImage imageNamed:@&quot;likeIcon.png&quot;];
        self.unlikedIcon = [UIImage imageNamed:@&quot;unlikedIcon.png&quot;];
    }
}
 
- (void)dealloc {
    self.likeLabel = nil;
    self.likeIcon = nil;
    self.unlikedIcon = nil;
    [super dealloc];
}
 
- (IBAction)likeClicked:(id)sender {
    // Update the label's text
    self.isLiked = !self.isLiked;
    self.likeLabel.text = (self.isLiked) ? @&quot;Liked by you&quot; : @&quot;&quot;;
 
    [self setNeedsDisplay];
}
 
- (void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    
    // Determine the coordinates we want our content drawn at
    CGPoint iconPoint = CGPointMake(floorf(self.likeIcon.size.width / 2),
                                    CGRectGetMidY(self.textLabel.frame));
    
    // Draw the content
    UIImage *image = (self.isLiked) ? self.likedIcon : self.unlikedIcon;
    [image drawAtPoint:iconPoint];
}
</pre><p>In the code example above you&#8217;ll notice that we&#8217;re creating the UIImage object in <code>initWithFrame:</code>, and are destroying it in dealloc, so that we don&#8217;t have to allocate objects within the drawRect: method.  It&#8217;s important to keep that method as quick as possible so you don&#8217;t negatively impact your screen&#8217;s framerate.</p><h2>Responding to frame size changes</h2><p>When your view changes its size, either when explicitly set or when a superview autoresizes its subviews, your content will be invalidated in some way. But rather than calling expensive drawRect: methods all the time when this happens, UIView objects have a <code>contentMode</code> property that lets you give UIKit a hint about what you want it to do in this situation.</p><p>This property is an <code>typedef enum</code> named <code>UIViewContentMode</code> and has a bunch of different options that you should check out.  The default value is <code>UIViewContentModeScaleToFill</code> which means if your frame&#8217;s size changes, UIKit will simply take the last-rendered result your <code>drawRect:</code> method created and will scale it up or down to fill the available space.</p><p>The simplest way to get your content to redraw is to set your view&#8217;s <code>contentMode</code> to <code>UIViewContentModeRedraw</code>, but in many cases this may be overkill.</p><p>For example, lets assume your <code>drawRect:</code> method draws a border and some comments along the bottom of your frame, as the &#8220;Like&#8221; example does in the previous section. If your frame changes its height it would be wasteful to perform a full redrawing operation when most of the content hasn&#8217;t changed.  So if you set the <code>contentMode</code> to <code>UIViewContentModeBottomLeft</code> UIKit will align the content in the bottom-left corner of the view, cropping the rest of the content as it does so.</p><h2>Avoid drawing across pixel boundaries</h2><p>When you position elements on the screen (not just with Core Graphics, but in UIKit in general) you need to make sure that your views exist at integer pixel coordinates.  iOS&#8217; drawing coordinate system works in points, not absolute pixels, which means it&#8217;s possible to tell UIKit or Core Graphics to draw content at a fractional-pixel. Since this is impossible, the device attempts to anti-alias your content so that it blurs between several pixels.  This is almost never what you want, so when calculating positions (especially when dividing one value by another) it&#8217;s important to use the <code>floorf</code> or <code>ceilf</code> functions to round the values down or up to the nearest integer.</p><p>This is more obvious when drawing or stroking lines or paths on the screen.  Lets take the following example where we draw a single line along the bottom of the view.  For this example however we&#8217;ll use the low-level drawing routines to compose a path, instead of using a <code>UIBezierPath</code> object.</p><pre class="brush: objc; title: ; notranslate">
- (void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(ctx, [UIColor blackColor].CGColor);
    CGContextSetLineWidth(ctx, 1);
    
    CGContextBeginPath(ctx);
    CGContextMoveToPoint(ctx, 0, CGRectGetMaxY(rect));
    CGContextAddLineToPoint(ctx, CGRectGetMaxX(rect), CGRectGetMaxY(rect));
    CGContextStrokePath(ctx);
}
</pre><p>This code seems pretty straightforward; move the drawing &#8220;pen&#8221; position to the bottom-left corner, add a line to the bottom-right corner, and stroke the resulting path with the line width and line color previously defined.</p><p>The &#8220;gotcha&#8221; here is that when you create a point at <code>(0, 0)</code>, that represents the logical upper-left corner of the screen.  However the pixel in the top-left corner occupies the space defined by the frame <code>(0, 0, 1, 1)</code> (e.g. a 1-point square starting at (0, 0)).  When you draw a line it is centred on whatever coordinates you give it.  Therefore in the code example above, your code is asking Core Graphics to draw a line that has 0.5 in one pixel, and 0.5 in another pixel.</p><p>To get around this you should offset your drawing frame so that you draw 0.5 points offset.  Here&#8217;s an updated version of that code which draws a solid unblurred line:</p><pre class="brush: objc; title: ; notranslate">
- (void)drawRect:(CGRect)rect {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(ctx, [UIColor blackColor].CGColor);
    CGContextSetLineWidth(ctx, 1);
    
    CGContextBeginPath(ctx);
    CGContextMoveToPoint(ctx, 0, CGRectGetMaxY(rect)) - 0.5;
    CGContextAddLineToPoint(ctx, CGRectGetMaxX(rect), CGRectGetMaxY(rect));
    CGContextStrokePath(ctx);
}
</pre><h2>Drawing with colour the easy way</h2><p>Core Graphics has evolved over time, with new and improved APIs.  This means that for many drawing operations there might be several different function calls that will give you the same result.  This is especially true when dealing with colour.</p><p><a
href="http://nachbaur.com/wp-content/uploads/2012/01/SetStrokeColorCodeComplete1.png" rel="lightbox[724]"><img
class="alignright size-full wp-image-746" title="Set StrokeColor Code Completion" src="http://nachbaur.com/wp-content/uploads/2012/01/SetStrokeColorCodeComplete1.png" alt="" width="563" height="71" /></a>For example, if you want to set the stroke (aka &#8220;line&#8221;) colour in Core Graphics, there are four separate function calls that will achieve the same result.  Your impulse might be to pick the first result that comes up, but that means more work for yourself.  The standard <code>CGContextSetStrokeColor</code> function call takes an array of <code>CGFloat</code>s indicating the different colour values you want to draw with.</p><p>However there&#8217;s a much easier way. <code>CGContextSetStrokeColorWithColor</code> is a slightly more verbose function name, but allows you to supply a <code>CGColorRef</code> value to describe a colour.  And as a convenience, the <code>UIColor</code> class provides a helper property called <code>CGColor</code> that returns a pre-calculated colour reference, which automatically releases its memory when the <code>UIColor</code> object goes away.  This means you don&#8217;t need to manually malloc or release your colour references, and results in much less code.</p><p>You can see some of the code examples up above where I&#8217;ve already used this function and property.  Whenever you see a function that has a &#8220;ColorWithColor&#8221; option, it uses this pattern.</p><h1>Use the right tool for the job</h1><p>Perhaps the best advice I can give is to use the right tool for the job.  For example, if you need to visually style some interface element, you shouldn&#8217;t add unnecessary subviews just to draw things like borders, rounded corners, tiled patterns, and so on.  Additionally there are cases where having a large number of subviews (such as in UITableViewCells) is inefficient and rendering simple elements like icons, text, or borders is better suited to Core Graphics.</p><p>iOS and UIKit is really a different environment than HTML, and you can&#8217;t treat device layout and rendering the same way.</p><p>And finally, make sure you practice, and don&#8217;t be afraid of trying out Core Graphics.  Start simple with things like borders, rendering images and text, or programmatically rendering effects that would otherwise be slow using Core Animation or image-based textures.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nachbaur?a=etCDUC8xTEk:S2-9hBOm1Rc:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=bcOpcFrp8Mo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=etCDUC8xTEk:S2-9hBOm1Rc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=etCDUC8xTEk:S2-9hBOm1Rc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=etCDUC8xTEk:S2-9hBOm1Rc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nachbaur?i=etCDUC8xTEk:S2-9hBOm1Rc:V_sGLiPBpWU" border="0"></img></a>
</div>]]></content:encoded> <wfw:commentRss>http://nachbaur.com/blog/core-graphics-isnt-scary-honest/feed</wfw:commentRss> <slash:comments>9</slash:comments> </item> <item><title>Back To Basics: Simple debugging tips in Xcode</title><link>http://nachbaur.com/blog/basics-xcode-debugging-tips</link> <comments>http://nachbaur.com/blog/basics-xcode-debugging-tips#comments</comments> <pubDate>Wed, 21 Dec 2011 20:13:12 +0000</pubDate> <dc:creator>Michael Nachbaur</dc:creator> <category><![CDATA[Objective-C]]></category> <category><![CDATA[apple]]></category> <category><![CDATA[Back To Basics]]></category> <category><![CDATA[debugging]]></category> <category><![CDATA[development]]></category> <category><![CDATA[iphone]]></category> <category><![CDATA[Xcode]]></category> <guid isPermaLink="false">http://nachbaur.com/?p=726</guid> <description><![CDATA[As developers we spend most of our lives dealing with broken and barely-functional software: our own software. We do our best to make the applications we develop somewhat less broken and try to add features to make it functional. And once we finally get our software working bug-free and functioning stably, what do we do? [...]]]></description> <content:encoded><![CDATA[<div
class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fbasics-xcode-debugging-tips"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fbasics-xcode-debugging-tips&amp;source=NachoMan&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6239b17e17b21092b11716b59a2de343&amp;b=2" height="61" width="50" /><br
/> </a></div><p>As developers we spend most of our lives dealing with broken and barely-functional software: our own software. We do our best to make the applications we develop somewhat less broken and try to add features to make it functional. And once we finally get our software working bug-free and functioning stably, what do we do? Do we bask in the joy of a stable app and spend countless hours enjoying that moment? No, we move on to v1.1 or v2.0, adding more features and consequently more bugs.  It&#8217;s kind of sad if you think about it.</p><p>Since much of our lives are spent with applications in various states of brokenness, understanding how to debug our software and catch those exceptions that arise is vital to getting our applications to a stable state so we can release, consequently moving on to create a whole new set of bugs that need to be fixed.</p><p>Here are some basic tips and tricks to make your life easier dealing with Xcode 4, and tracking down those places where your code runs off into the bushes.</p><h1><span
id="more-726"></span>Using breakpoints</h1><p><a
href="http://nachbaur.com/wp-content/uploads/2011/12/Simple-Breakpoint.png" rel="lightbox[726]"><img
class="alignright size-full wp-image-727" title="Simple Breakpoint" src="http://nachbaur.com/wp-content/uploads/2011/12/Simple-Breakpoint.png" alt="" width="290" height="120" /></a>Most people are familiar with the concept of breakpoints, but if you&#8217;re not I&#8217;ll reproduce it here. Click the line number next to a line of code, and a breakpoint icon will show up, causing your application to pause when it gets there.  From that point you can inspect the values of variables within your scope, you can single-step from one line of code to the next, etc. It&#8217;s something most web developers wish they had.</p><h2>Editing breakpoints</h2><p><img
class="alignright size-full wp-image-728" title="Edit Breakpoint" src="http://nachbaur.com/wp-content/uploads/2011/12/Edit-Breakpoint.png" alt="" width="277" height="127" /></p><p>You can also edit breakpoints.  Right-click on a particular breakpoint and you can click the &#8220;Edit Breakpoint&#8221; menu. You also have a few other options available to you, including the ability to disable or delete a breakpoint. However there&#8217;s easier ways to do the same things; you can either drag the breakpoint off of the line-number margin, just like removing an icon from your dock, or you can click the line to toggle its &#8220;disabled&#8221; state.</p><h2>Conditional breakpoints</h2><p><a
href="http://nachbaur.com/wp-content/uploads/2011/12/Breakpoint-Details.png" rel="lightbox[726]"><img
class="alignright size-medium wp-image-729" title="Breakpoint Details" src="http://nachbaur.com/wp-content/uploads/2011/12/Breakpoint-Details-300x95.png" alt="" width="300" height="95" /></a>When you select &#8220;Edit Breakpoint&#8221; you are presented with a context menu showing additional options for that breakpoint. You can set a condition that will cause your breakpoint to trigger only when that condition is met, you can cause it to ignore the breakpoint until a certain number of times, and can even trigger complex actions to be performed automatically when that breakpoint is hit.</p><p>For example, you can log a line to the console, you can play a sound, you can capture an OpenGL frame for later comparison, and can even invoke a shell script or AppleScript.</p><h2>Managing your breakpoints</h2><p><a
href="http://nachbaur.com/wp-content/uploads/2011/12/Breakpoint-Navigator.png" rel="lightbox[726]"><img
class="alignright size-medium wp-image-730" title="Breakpoint Navigator" src="http://nachbaur.com/wp-content/uploads/2011/12/Breakpoint-Navigator-247x300.png" alt="" width="247" height="300" /></a>Once you have a lot of breakpoints in your code it can often be difficult to manage it. So in the Xcode 4 navigator pane you can click on the &#8220;Breakpoints&#8221; tab (or you can press ⌘-6) to see a full list of your current breakpoints.</p><p>You can enable or disable the breakpoints right from there, you can delete them, etc. But as you can see, at the bottom of the navigator, there&#8217;s a toolbar.  From there you can create new breakpoints, filter breakpoints, and other fun tasks.</p><p>The most important feature here however is the ability to add explicit breakpoints without having to have an associated line number.  Clicking the &#8220;+&#8221; button brings up a menu with two options: &#8220;Add Exception Breakpoint&#8221; and &#8220;Add Symbolic Breakpoint&#8221;.</p><h2>Exception breakpoint</h2><p>This is perhaps one of the most powerful breakpoints you can have in your debugging arsenal, and is something you&#8217;ll almost always want to add to your project. In a nutshell it will cause your program to pause at a line that triggers an exception, rather than simply crashing and burning with an <code>EXC_BAD_ACCESS</code> or some other similar exception.</p><p>This makes debugging your code quite a lot easier because instead of seeing a mysterious crash in <code>main.m</code>, or in <code>objc_msgSend</code>, you will see the line of code in your application that resulted in that exception happening in the first place. This is true debugging power because without that bit of context you&#8217;d have no other idea about where or why your application is crashing.</p><h2>Symbolic breakpoints</h2><p>Symbolic breakpoints are just like regular breakpoints, but instead of catching a particular line of code, you can pause your application when a method or function call is made.  There are some pre-defined symbols you can use, or you can break on a particular method name.  For example, &#8220;<code>objc_exception_throw</code>&#8221; is a handy symbol to break on since it will capture an exception being thrown, regardless of whether or not it is caught. Another useful breakpoint to set is &#8220;<code>-[NSObject doesNotRecognizeSelector:]</code>&#8221; which will allow you to capture situations where a selector is being invoked against the wrong object.</p><p>There are of course other symbolic breakpoints you can set but there&#8217;s too exhaustive of a list to outline them here, so use the Almighty Google for future reference.</p><h1>Using the debugger console</h1><p>Once your breakpoint has triggered, your next question may be &#8220;Well now what?&#8221; What can you do with your code once your program has suspended? The most obvious thing you can do is single-step through the following lines to see what happens, what paths your code takes, and so forth.  But there will be times that you&#8217;ll want to deeply inspect properties or ivars in ways that the variable window won&#8217;t let you.  For this you can use the debugger console to control the debugger explicitly to find answers to your question &#8220;What&#8217;s my app doing right now?&#8221;</p><h2>Printing objects</h2><p>Say for the sake of argument that you&#8217;ve got an ivar named &#8220;<code>_myDictionary</code>&#8221; that contains some object, and you want to print out its default value.  That&#8217;s simple, you can click in the console window (the right-hand pane of the bottom debugger panel), and you can type: &#8220;<code>po _myDictionary</code>&#8220;.  That will print out the result of the <code>-[NSObject description]</code> method for that object.</p><p>However lets say you want to dig deeper, and want to print the result of a method call on that dictionary.  This is also simple: &#8220;<code>po [_myDictionary allKeys]</code>&#8221; works just as well.  The debugger console doesn&#8217;t understand Objective-C 2.0 Properties, but regular bracket-notation method calls works.</p><h2>Printing primitives and structs</h2><p>What if what you want to print isn&#8217;t an object? What if you want to print out the value of a literal (e.g. a <code>float</code> or <code>NSUInteger</code>), a struct (e.g. <code>CGRect</code>, <code>CGPoint</code>, etc), or really anything else that may or may not be an object?  With that you can use the &#8220;p&#8221; command.  However since you&#8217;re not printing an object, you need to give the debugger a hint about what kind of primitive you&#8217;re expecting.</p><p>To print a float, I would say: &#8220;<code>p (float)_myFloatValue</code>&#8220;. Simple variable casting here works just great.</p><p>Printing out the frame of a view is also pretty simple. &#8220;<code>p (CGRect)[[self view] frame]</code>&#8220;.  You notice here that I&#8217;m combining a set of method calls with a casted print statement. This will give you a pretty-formatted rendition of the rect, making it easier to debug.</p><h2>Printing CPU registers</h2><p>When your code is compiled down into machine code and is run on a device, your CPU steps through each operation and invokes them sequentially. When something goes wrong, and your program suspends, there are ways to inspect the state the CPU was in when a crash occurred and you can glean information from it. This is a lot less difficult than you might think.  For more information on this topic, please refer to this excellent post titled &#8220;<a
title="So you crashed in objc_msgSend()" href="http://www.sealiesoftware.com/blog/archive/2008/09/22/objc_explain_So_you_crashed_in_objc_msgSend.html">So you crashed in objc_msgSend()</a>&#8220;.  I&#8217;ll only be giving a high-level overview, so I highly suggest you read and bookmark that link.</p><p>Consider the sample that that above post tries to cover: your application has crashed in the <code>objc_msgSend()</code> method, which is Objective-C&#8217;s low-level method invocation function.  When this happens you usually don&#8217;t have any information to go on, other than a cryptic exception titled <code>EXC_BAD_ACCESS</code>, with your breakpoint pointing at your <code>main.m</code> file.</p><p>By printing the value of the CPU registers in the debugger console you can extract information about what method was being invoked.  Typing &#8220;<code>x/s $ecx</code>&#8221; for the iOS Simulator, or &#8220;<code>x/s $r1</code>&#8221; for an iOS device, will print the name of the selector that was being run that resulted in a crash.  It&#8217;s that simple!</p><h1>Defensive coding</h1><p>Above all else some of your best debugging techniques will be to avoid crashes altogether. Practice defensive coding by using some common C and Objective-C patterns. Don&#8217;t retain delegates, release your ivars in <code>dealloc</code> or in <code>viewDidUnload</code>. And when you release an ivar, also set its value to <code>nil</code>.  In fact I go so far as to create a macro that handles that for me.</p><pre class="brush: objc; title: ; notranslate">
#define DNRelease(x) [x release], x = nil
</pre><p>A technique referred to as &#8220;Yoda-Conditions&#8221; means for you to reverse your conditionals so that constants are placed on the left-hand side of your operator.  For example:</p><pre class="brush: objc; title: ; notranslate">
if (YES == someBoolean) ...
</pre><p>That is much less intuitive since nobody but Yoda speaks in reverse like that, but what this does buy you is compile-time protection against accidentally assigning a value instead of comparing it.  A simple &#8220;<code>if (someBoolean = YES)</code>&#8221; statement can be time-consuming to track down and is easily avoided if you always write your comparisons the other way around.</p><p>And above all else make sure you write readable code. Nobody likes ugly code, but for more than pure aesthetics. Ugly or confusing code can hide more bugs, and when you use good whitespace, sensible variable names, and you structure your code cleanly, you can expose bugs earlier and make them easier to track down later.</p><p>Good luck and happy bug-hunting, and I hope this starts you off on the right foot!</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nachbaur?a=jR6Gsh0B3fU:pOPMweNqJU0:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=bcOpcFrp8Mo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=jR6Gsh0B3fU:pOPMweNqJU0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=jR6Gsh0B3fU:pOPMweNqJU0:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=jR6Gsh0B3fU:pOPMweNqJU0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nachbaur?i=jR6Gsh0B3fU:pOPMweNqJU0:V_sGLiPBpWU" border="0"></img></a>
</div>]]></content:encoded> <wfw:commentRss>http://nachbaur.com/blog/basics-xcode-debugging-tips/feed</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Building a static library with Jenkins</title><link>http://nachbaur.com/blog/building-a-static-library-with-jenkins</link> <comments>http://nachbaur.com/blog/building-a-static-library-with-jenkins#comments</comments> <pubDate>Mon, 26 Sep 2011 16:07:36 +0000</pubDate> <dc:creator>Michael Nachbaur</dc:creator> <category><![CDATA[Continuous Integration]]></category> <category><![CDATA[Objective-C]]></category> <category><![CDATA[continuous integration]]></category> <category><![CDATA[development]]></category> <category><![CDATA[libraries]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[tutorial]]></category> <guid isPermaLink="false">http://nachbaur.com/?p=710</guid> <description><![CDATA[One of my pet peeves is Open Source iOS libraries distributed as just a collection of Objective-C classes, rather than being bundled as a static library. I know a lot of people prefer it that way, but from a maintainability standpoint it really doesn&#8217;t make much sense to me. So when I&#8217;m faced with another [...]]]></description> <content:encoded><![CDATA[<div
class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fbuilding-a-static-library-with-jenkins"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fbuilding-a-static-library-with-jenkins&amp;source=NachoMan&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6239b17e17b21092b11716b59a2de343&amp;b=2" height="61" width="50" /><br
/> </a></div><p>One of my pet peeves is Open Source iOS libraries distributed as just a collection of Objective-C classes, rather than being bundled as a static library. I know a lot of people prefer it that way, but from a maintainability standpoint it really doesn&#8217;t make much sense to me. So when I&#8217;m faced with another library I want to use that doesn&#8217;t have a static library readily available for it, I typically wrap it up in my own Xcode project, check it in to Github, and configure my Jenkins continuous integration build server to compile it for me.</p><p>I thought I&#8217;d walk you through the steps I go through to make this happen, so you can use this technique too.<span
id="more-710"></span></p><h2>Why I prefer static libraries</h2><p>Before I go too far on this topic I wanted to explain my reasoning behind preferring static libraries, as opposed to loosely-distributed sets of classes.</p><p>Consider a large project where I&#8217;m utilizing a few libraries built by third-parties to speed up my development; a recent example of this on one of my projects is using the AFNetworking library from Gowalla. Now I could simply sync their source tree from Github, drag-n-drop their classes into my project, and I could be done with it. But what happens when one of their classes is upgraded? I have to re-sync the code, resolve any differences, and drag it back into my project.  I could of course make their project a git sub-module of my own, but then whenever I perform an update to my git project I may not know which changes their source has undergone, meaning I have no control whether or not my project will pass or fail.  And this assumes I&#8217;m using Git for my project; at work we use Perforce which has terrible Git integration.</p><p>Assuming I have an up-to-date set of classes from a third-party integrated into my project, what happens in the event I change some C pre-processor definitions that break those classes? Since every time I compile my code I have to also compile the third-party code, I don&#8217;t know if a compilation bug in the third-party classes are a problem caused by my build settings, or is a problem in their code.  If I were to consume a static library I could re-use that binary safe in the knowledge that no random changes will take place in it.  If I wanted to bring in any updates from a third-party I can choose when to integrate those updates in since I can choose when to copy over the new library.</p><p>And finally, the reason why I had to create a static library for AFNetworking in the first place, is in the transition from manual reference counting to &#8220;Automatic Reference Counting&#8221; (also known as ARC).  ARC requires actual code-level changes since such method calls as &#8220;release&#8221;, &#8220;autorelease&#8221;, &#8220;dealloc&#8221; etc are now a compilation error.  This means you can&#8217;t mix-and-match ARC and non-ARC classes in the same project.  Non-ARC code compiled in its own separate static library though can still play nice within a different ARC project.</p><h2>How to create a static library</h2><p><a
href="http://nachbaur.com/wp-content/uploads/2011/09/New-Xcode-Static-Library-Project.png" rel="lightbox[710]"><img
class="alignright size-medium wp-image-712" title="New Xcode Static Library Project" src="http://nachbaur.com/wp-content/uploads/2011/09/New-Xcode-Static-Library-Project-300x209.png" alt="" width="300" height="209" /></a></p><p>First you should begin by either forking the target library on Github, or by acquiring the source code in some other way. If you fork from Github it will make it easier to merge changes down later as the project is updated in the future, or provides for the ability to merge your static library up into the main project.</p><p>Regardless, once you get the code you begin by creating a new static library project in Xcode. It&#8217;s simple enough; just make sure you select the &#8220;Cocoa Touch&#8221; static library project and you should be good to go.  Once this opens up it will give you some boilerplate classes and settings; feel free to delete those.  You might want to create the new project somewhere within the source tree for the library in a way that won&#8217;t annoy other developers.  For example, you might not want to move the original classes around too much since it might make it difficult for other developers to merge your change into their own branches.</p><p>Once you have your empty library project you can go ahead and add all the classes you&#8217;ll be wanting to include in the library, either by using the &#8220;Add files to&#8230;&#8221; menu item, or by drag-and-dropping them from Finder into an appropriate folder in the navigation pane of your project.</p><p>At this point the code might compile, but you need to make some changes to the project settings in order to make it possible to compile, and to make it easy for you to get at the built results of the project.  Click on the root of your project to open the project settings, and make the following changes:</p><p><a
href="http://nachbaur.com/wp-content/uploads/2011/09/Library-Project-Settings.png" rel="lightbox[710]"><img
class="alignleft size-medium wp-image-714" title="Library Project Settings" src="http://nachbaur.com/wp-content/uploads/2011/09/Library-Project-Settings-300x179.png" alt="" width="300" height="179" /></a></p><ol><li><strong>Installation Directory (INSTALL_PATH):</strong> Set this to &#8220;/&#8221;. This indicates where the products of the build (namely the static libAFNetworking.a file) will be installed, relative to the target installation root.</li><li><strong>Public Headers Folder Path (PUBLIC_HEADERS_FOLDER_PATH):</strong> This controls where the public headers for your library will be installed, relative to the installation root. Set this to &#8220;Headers&#8221;.</li><li><strong>Header Search Paths (HEADER_SEARCH_PATHS):</strong> This isn&#8217;t strictly necessary for all projects, but in this case we&#8217;re going to compile against the JSONKit library, but are not going to be including it in the resulting static library. So we need to tell Xcode where to find the header so it can properly compile the classes that might potentially depend on it.</li><li><strong>Skip Install (SKIP_INSTALL):</strong>Set this to &#8220;No&#8221; or, in the example in the above screenshot, set delete it so the Xcode default of &#8220;No&#8221; will take effect. This is important because without this we won&#8217;t be able to install the results of this build into a directory where we can get at it.</li><li><strong>Precompile Prefix Header &amp; Prefix Header (Optional):</strong> In the example I&#8217;m showing here I didn&#8217;t actually want to add more unnecessary files to the project than needed, and since the prefix header only adds a global import of &#8220;Foundation.h&#8221;, I removed those from the Xcode project.</li></ol><p><a
href="http://nachbaur.com/wp-content/uploads/2011/09/Library-Build-Phases.png" rel="lightbox[710]"><img
class="alignright size-medium wp-image-715" title="Library Build Phases" src="http://nachbaur.com/wp-content/uploads/2011/09/Library-Build-Phases-300x235.png" alt="" width="300" height="235" /></a>Once you get the static library settings configured you can take one final step to control the build phases your library will go through.  The particular build phase we want to configure is the &#8220;Copy Headers&#8221; build step.  This setting is broken down into three sections: Public, Private, and Project sections. By default all the header files of your project will reside in the &#8220;Project&#8221; section, meaning those headers will only be available to your project and will not be installed when you complete your build. The other two sections, &#8220;Public&#8221; and &#8220;Private&#8221; let you indicate a directory path where you&#8217;d like your headers put when it&#8217;s installed.</p><p>You can see in the screenshot that I&#8217;ve moved all of the AFNetworking headers into the Public section, and left JSONKit in the Project section. This is because if a user of this library wants to use JSONKit they&#8217;ll presumably get it on their own, so any headers we include here might result in a conflict. So it&#8217;s best to just include the headers for the code that is actually present in your project.</p><p>If you&#8217;re creating an SDK or a reusable API for others to use and there are some parts of your code that you would rather remain hidden, simply don&#8217;t move those headers into the &#8220;Public&#8221; section.</p><h2>Building your library in Jenkins</h2><p>At this point your code should compile cleanly when you click the &#8220;Build&#8221; button. But more than that we want to be able to simplify the compilation of this library so it can easily be packaged up and shipped off.  I like to either use shell scripts or &#8220;Ant&#8221; to automate my build process since it allows me to predictably run my builds deterministically with little room for human error.</p><p>There are several things we want the build script to accomplish:</p><ol><li>Create a directory where the results of the build will reside;</li><li>Compile versions of the static library for both the device and the simulator;</li><li>Create a &#8220;FAT&#8221; library containing both the device and simulator results for easy debugging;</li><li>Create a ZIP file containing the static library and its headers.</li></ol><pre class="brush: objc; title: ; notranslate">#!/bin/sh
set -ex
INSTALL_PATH=$WORKSPACE/artifacts
[ -z $INSTALL_PATH ] || INSTALL_PATH=$PWD/artifacts
rm -rf $INSTALL_PATH
mkdir -p $INSTALL_PATH
PROJ=AFNetworking/AFNetworking.xcodeproj
xcodebuild -project $PROJ -sdk iphoneos INSTALL_ROOT=$INSTALL_PATH/device install
xcodebuild -project $PROJ -sdk iphonesimulator INSTALL_ROOT=$INSTALL_PATH/simulator install
lipo -create -output $INSTALL_PATH/libAFNetworking.a $INSTALL_PATH/device/libAFNetworking.a $INSTALL_PATH/simulator/libAFNetworking.a
mv $INSTALL_PATH/device/Headers $INSTALL_PATH
rm -rf $INSTALL_PATH/device $INSTALL_PATH/simulator
(cd $INSTALL_PATH; zip -r ../AFNetworking.zip libAFNetworking.a Headers)
</pre><p>If you understand Bourne Shell that code should be pretty straight-forward. You simply set up an install path relative to the Jenkins workspace (or relative to your current directory if you&#8217;re running the script by hand), run two separate builds using &#8220;xcodebuild&#8221;, use &#8220;lipo&#8221; to merge the resulting static libraries, and we create a ZIP file of the resulting files.</p><p>I&#8217;ll go through each part of the &#8220;xcodebuild&#8221; command to point out why I&#8217;m doing things this way.</p><ul><li>&#8220;xcodebuild -project $PROJ&#8221; – Indicate the project file that you want to build. I&#8217;m using a variable defined higher up in the script to make it easy to change.</li><li>&#8220;-sdk iphoneos&#8221; or &#8220;-sdk iphonesimulator&#8221; – Manually specifying the SDK to use so we can compile both the device and simulator versions.</li><li>&#8220;INSTALL_ROOT=&#8230;&#8221; – This passes a variable into the build process, allowing us to customize the path the resulting artifacts will be installed to. By default, as you can see from the above screenshots, that the path &#8220;/tmp/AFNetworking.dst&#8221; is defined.  This command-line argument lets us override that setting to configure a path of our choosing.</li><li>&#8220;install&#8221; – Perhaps the most important part, we&#8217;re saying we want to install the files, rather than just simply building them. Xcode normally creates its build artifacts in a folder in ~/Library/Developer/Xcode/DerivedData, keyed off some awfully long UUID, and there&#8217;s no easy and deterministic way of identifying the path Xcode will choose when building its artifacts.  When using &#8220;install&#8221; the appropriate files are copied from that interim build directory and into the directory you selected above.</li></ul><h2>Getting Jenkins to rebuild when code is checked in</h2><p>The final and most useful step is to get your code rebuilding automatically when you check new code into Github. This technique will work for other version control systems, but Github is certainly the easiest to control.</p><p>Make sure your build script is checked into your source tree, and configure a new job in Jenkins for your static library project. I won&#8217;t walk you through the entire process, but it&#8217;s simple enough to create a &#8220;Freestyle&#8221; project, set up your Github credentials for checking code out when a build is triggered.  From there, add a new &#8220;Execute Shell&#8221; build step, and add the following to the command:</p><p
style="padding-left: 30px;">&#8220;$WORKSPACE/build.sh&#8221;</p><p>Make sure you include the quotes, because your $WORKSPACE path that Jenkins assigns you may potentially contain whitespaces that would break that command.  From there you should be able to trigger a new build manually and have it compile your project for you.  Give it a try and make sure it works.</p><p>Next you&#8217;ll want to do something with the resulting build artifacts. What I like to do is create a single directory under which all my compiled resources will be collected and archived by Jenkins, but since the above build script created a single convenient ZIP file we can just archive that. Check the &#8220;Archive the artifacts&#8221; box, and type &#8220;AFNetworking.zip&#8221; into the field.</p><p>At this point we&#8217;re finally able to integrate our build into Github, but it&#8217;s a lot simpler than you might think.  Jenkins has an amazing REST API that lets you interact with it programmatically. If you want to kick off a new build, all you need to do is perform an HTTP GET against the &#8220;build&#8221; URL for your job. If your Jenkins server is located at http://jenkins.mycompany.com/ and your job is named &#8220;MyLibrary&#8221;, you only need to issue a GET to http://jenkins.mycompany.com/job/MyLibrary/build.</p><p><a
href="http://nachbaur.com/wp-content/uploads/2011/09/Github-Service-Hook.png" rel="lightbox[710]"><img
class="alignright size-medium wp-image-717" title="Github Service Hook" src="http://nachbaur.com/wp-content/uploads/2011/09/Github-Service-Hook-300x207.png" alt="" width="300" height="207" /></a>With that in mind, go to your &#8220;Admin&#8221; settings on Github for your project, and click on the &#8220;Service Hooks&#8221; menu.  Github provides a long list of services it can interact with, but the simplest and most straightforward is the &#8220;Post-Receive URLs&#8221; section. This lets you supply a list of URLs that Github should issue a request to after it has received a new checkin.</p><p>As you can see from the screenshot to the right, it&#8217;s fairly simple and is easy to test.  Next time you perform a &#8220;git push&#8221; back up to Github, your Jenkins server should automatically trigger a new build.</p><p>If you want to see everything I&#8217;ve talked about here, go to my <a
href="https://github.com/NachoMan/AFNetworking">Github fork of AFNetworking</a> or <a
title="Download AFNetworking.zip" href="nachbaur.com/AFNetworking/AFNetworking.zip">download the AFNetworking.zip</a> file from my website created from the process I describe above.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nachbaur?a=S__BPR5q0dw:kAoJyaqaQkg:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=bcOpcFrp8Mo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=S__BPR5q0dw:kAoJyaqaQkg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=S__BPR5q0dw:kAoJyaqaQkg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=S__BPR5q0dw:kAoJyaqaQkg:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nachbaur?i=S__BPR5q0dw:kAoJyaqaQkg:V_sGLiPBpWU" border="0"></img></a>
</div>]]></content:encoded> <wfw:commentRss>http://nachbaur.com/blog/building-a-static-library-with-jenkins/feed</wfw:commentRss> <slash:comments>8</slash:comments> </item> <item><title>Using GCD and Blocks Effectively</title><link>http://nachbaur.com/blog/using-gcd-and-blocks-effectively</link> <comments>http://nachbaur.com/blog/using-gcd-and-blocks-effectively#comments</comments> <pubDate>Fri, 02 Sep 2011 00:39:09 +0000</pubDate> <dc:creator>Michael Nachbaur</dc:creator> <category><![CDATA[Objective-C]]></category> <category><![CDATA[blocks]]></category> <category><![CDATA[development]]></category> <category><![CDATA[howto]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[threading]]></category> <category><![CDATA[tutorial]]></category> <guid isPermaLink="false">http://nachbaur.com/?p=688</guid> <description><![CDATA[With iOS 4.0 Apple introduced two new technologies to the iOS platform: Grand Central Dispatch, and blocks.  Simply put, it is to multi-threaded programming what fire is to a barbecue.  Sure you can do without it, but the end result is much better. Despite all this, developers still seem to avoid using it. Some of [...]]]></description> <content:encoded><![CDATA[<div
class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fusing-gcd-and-blocks-effectively"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fusing-gcd-and-blocks-effectively&amp;source=NachoMan&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6239b17e17b21092b11716b59a2de343&amp;b=2" height="61" width="50" /><br
/> </a></div><p>With iOS 4.0 Apple introduced two new technologies to the iOS platform: Grand Central Dispatch, and blocks.  Simply put, it is to multi-threaded programming what fire is to a barbecue.  Sure you can do without it, but the end result is much better.</p><p>Despite all this, developers still seem to avoid using it. Some of the reasons for this, off the top of my head, could be backwards-compatibility for older versions of iOS, unfamiliarity with the funky syntax it uses, or simply a lack of practice.  The biggest thing I find however is a general misunderstanding about the importance of multi-threading among new developers, which was made worse by the difficulty of dealing with threads before blocks and GCD was released.</p><p>Fortunately there&#8217;s no reason to avoid multi-threaded programming in iOS, but before I dive into the specifics I&#8217;d like to point out just how important it is to use an asynchronous approach to development on iOS, or any mobile platform in general.<br
/> <span
id="more-688"></span></p><h2>Why should I care about GCD?</h2><p>Before going into the specifics of how to use blocks and Grand Central Dispatch, I&#8217;d like to explain why it&#8217;s important. If you don&#8217;t take anything else away from this article, these points are important.  Here it goes:</p><blockquote><p>Don&#8217;t make the device wait around for you to figure out what you want it to do.</p></blockquote><p>The CPUs in mobile devices are really weak, memory is limited, you have some really hard limitations that you just can&#8217;t work around.  Performance problems aren&#8217;t often caused by a single slow operation, but many inefficiencies in how you utilize the hardware.  Performing expensive calculations, querying a database, reading images from disk, or other activities all take time.  Are you using caches effectively? Are you performing expensive tasks in the main thread?  There are many other things that you may be doing that can block the CPU from doing what really needs to happen: Rendering your interface to the screen 60 times per second.  If you can&#8217;t meet that target, your app is failing to provide smooth animations, and it will stick out like a sore thumb compared to the other applications on the device.</p><p>Each thread on your device runs its own event loop.  The operating system picks up a page of code, runs it, and when that chunk of code exits out the next iteration of the loop picks up.  When rendering your display, the main thread wakes up, runs all the code necessary to assemble your UI, paints a picture onto a memory buffer, and throws that on the screen. It tries to do this 60 times per second.  If each iteration of this runloop takes more than 16ms to run, then your device will drop frames and your display will get jittery.  If it takes less than 16ms, this means there&#8217;s spare CPU cycles available to do other work.</p><h2>The basics of asynchronous programming</h2><p>Developers in general are quite lazy; in fact, laziness is a great virtue to have as a programmer.  It means we&#8217;d rather be doing something else, so we want to do as little work as possible so we can get on with other work.  So it&#8217;s quite understanding why so many applications are developed with lots of synchronous code: It&#8217;s just easier to think about problems in a linear fashion.  You break a problem down into a series of steps, and write the code necessary to do those steps in order. Fortunately for us most computers are fast enough that this technique works well.  But once you switch to a mobile platform, long linear functions need to be broken down into smaller steps.</p><p>Consider an example where you download an image over the network, you resize and scale it to a thumbnail, and then put it onto the screen.  Because any operation interacting with the UI must be performed on the main thread, the easy route is to do all the above as a single synchronous set of instructions on the main thread.  Doing so however will result in the UI freezing up during the download, image conversion, and image resizing operations.</p><pre class="brush: objc; title: ; notranslate">
// Download the image
NSURL *url = [NSURL URLWithString:@&quot;http://bit.ly/nUX01h&quot;];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSURLResponse *res = [[NSURLResponse alloc] init];
NSError *err = nil;
NSData *data = nil;
data = [NSURLConnection sendSynchronousRequest:req
                             returningResponse:&amp;res
                                         error:&amp;err];
// Convert the data to a UIImage
UIImage *image = [UIImage imageWithData:data];
   
// Scale the image
UIImage *thumbImage = nil;
CGSize newSize = CGSizeMake(90, (90 / image.size.width) * image.size.height);
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
thumbImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
 
// Add this to a UIImageView
self.imageView.image = thumbImage;
</pre><p>Not only is converting the image from data to a UIImage or scaling the image to a  thumbnail expensive, but depending on the speed of the user&#8217;s network (e.g. wifi, 3G, AT&amp;T, etc) the download could take significantly longer.  So the best way is to break this up into multiple smaller steps. When each step finishes, the system will work on the next chunk.</p><p>Taking the above example of what not to do, lets refractor it slightly to use blocks.</p><pre class="brush: objc; title: ; notranslate">
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
    NSURL *url = [NSURL URLWithString:@&quot;http://bit.ly/nUX01h&quot;];
    NSURLRequest *req = [NSURLRequest requestWithURL:url];
    [NSURLConnection sendAsynchronousRequest:req
                                       queue:[NSOperationQueue currentQueue]
                           completionHandler:
     ^(NSURLResponse *res, NSData *data, NSError *err) {
         // Convert the data to a UIImage
         UIImage *image = [UIImage imageWithData:data];
          
         // Scale the image
         UIImage *thumbImage = nil;
         CGSize newSize = CGSizeMake(90, (90 / image.size.width) * image.size.height);
         UIGraphicsBeginImageContext(newSize);
         [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
         thumbImage = UIGraphicsGetImageFromCurrentImageContext();
         UIGraphicsEndImageContext();
          
         dispatch_async(dispatch_get_main_queue(), ^{
             self.imageView.image = thumbImage;
         });
     }];
});
</pre><p>As you can see most of the code is the same, except we&#8217;re breaking things down into smaller discrete chunks.  Each block is nested, allowing code to be called only when it is needed.  I&#8217;ll go into more detail with this shortly, but see if you can piece together what&#8217;s different between these two samples of code.</p><p>Doing the above fully asynchronously without blocks is entirely possible, but results in more complicated code that is more difficult to maintain.  The biggest difficulty is in keeping track of values and properties between threads, and results in a lot more boilerplate code.  Using blocks you can simply access the variables accessible within your current scope, making everything much easier.</p><h2>What is a block?</h2><p>Blocks in essence are nested functions that can be passed around as a pointer that has access to variables defined in the scope the block is defined in.  If you have ever worked in a language that supports &#8220;closures&#8221; (e.g. JavaScript, Perl, etc) you&#8217;ll probably already be familiar with this.</p><p>Blocks in Objective-C are defined rather strangely, but once you get used to it they make sense.  The carat &#8220;^&#8221; character is used to define a block. For example, &#8220;<tt>^{ … }</tt>&#8221; is a block. More specifically, it is a block that returns &#8220;void&#8221; and accepts no arguments.  It is equivalent to a method such like: &#8220;<tt>- (void)something;</tt>&#8221; but there is no inherent name associated with the code block.</p><p>Defining a block that can accept arguments work very similarly.  If you wanted to supply an argument to a block, you define the block like so: <tt>^(BOOL someArg, NSString* someStr) { … }</tt>.  When you use API calls that support blocks, you&#8217;ll be writing blocks that look similar to this, especially for animation blocks or NSURLConnection blocks as shown in the above example.</p><p>The easiest way to get started with blocks is to simply use existing APIs that support them. NSURLConnection above supports blocks, as do UIView animations, like so:</p><pre class="brush: objc; title: ; notranslate">
[UIView animateWithDuration:1.0
                 animations:^{
                     someView.alpha = 0;
                     otherView.alpha = 1;
                 }
                 completion:^(BOOL finished) {
                     [someView removeFromSuperview];
                 }];
</pre><p>If you have any experience with animating views without blocks, getting a completion handler to run after an animation has completed is extremely cumbersome, so much so that many developers don&#8217;t bother with them. Using the block-enabled alternative makes for much cleaner code, and makes it fun to create complex animations.</p><h2>How does GCD tie into this?</h2><p>Grand Central Dispatch is a facility for managing threads and queueing tasks in parallel efficiently, without you needing to worry about the boilerplate specifics around performance and startup / shutdown of threads.  Blocks and GCD are both completely different technologies, but since they work so well together it&#8217;s trivial to get started with it.</p><p>In order to use GCD, you use one of the functions that begin with &#8220;<tt>dispatch_</tt>&#8220;.  One of the common tasks a developer would want to perform is to run some small task in a background thread, and then run some other code on the main thread once that task has completed.  You may notice the call to &#8220;<tt>dispatch_async</tt>&#8221; up above, which explicitly runs a block on the main thread.</p><p>Dispatching blocks can either be triggered synchronously or asynchronously by using the <tt>dispatch_sync</tt> or <tt>dispatch_async</tt> functions, and they both take two arguments: The queue you want to dispatch your block on, and the block you&#8217;d like to dispatch.  Individual queues are analogous to threads, but the specifics about which thread your code will be run on is hidden from you, meaning the operating system can optimize the use of threads based on the number of cores your system possesses.</p><p>The two most common ways you&#8217;d get a pointer to a queue is to either fetch the main queue using &#8220;<tt>dispatch_get_main_queue()</tt>&#8221; or to fetch a queue with a specific priority, you use <tt>dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)</tt> and specify the priority you&#8217;d like (DEFAULT, LOW, HIGH, or BACKGROUND).</p><h2>How do I create my own block APIs?</h2><p>The most difficult part of dealing with blocks for many people is how to define your own methods or APIs that utilize blocks, mostly due to the confusing syntax used to define them.  Once you figure out how the syntax is broken down however, it&#8217;s quite easy.  Let me start with a few examples.</p><p>So first, let me show you how to define a block that takes no arguments and returns nothing.</p><pre class="brush: objc; title: ; notranslate">
- (void)noArgBlock:(void (^)(void))block;
</pre><p>The syntax we&#8217;re concerned about here is in the definition of the &#8220;<tt>block</tt>&#8221; argument.  As you know, you declare the type of an argument in parenthesis immediately before the name of the attribute.  So it&#8217;s easiest to ignore those outer parenthesis when dealing with block definitions.</p><pre class="brush: objc; title: ; notranslate">
void (^)(void)
</pre><p>Now things are looking a little more straight-forward, and a little closer to a standard C function.  The first word is the return type we expect a block with this definition to return.  Since we said we were creating a basic block that returned nothing, this is set to &#8220;<tt>void</tt>&#8220;.</p><p>Normally in a C function definition the very next thing after the return type would be the function name.  But since blocks aren&#8217;t actually named, instead we use &#8220;<tt>(^)</tt>&#8221; to denote that it&#8217;s an unnamed block that we&#8217;re defining.  So far so good, right?</p><p>Finally we define the parameters this block will accept.  Again with regular C functions this should be familiar, since you give a parenthesized list of arguments you&#8217;ll be providing to this function.  Since we&#8217;re not accepting any arguments to this block, we indicate that by putting in &#8220;<tt>void</tt>&#8220;.</p><p>And that&#8217;s it! Lets show you how you&#8217;d use that in your function!</p><pre class="brush: objc; title: ; notranslate">
- (void)noArgBlock:(void (^)(void))block {
    // Do something...
     
    // Call our block
    block();
}
</pre><p>When you want to invoke a block function supplied to your method, you can just call it like you would any C function.  But what if we want to call that block on a different queue or thread?  That&#8217;s easy enough too.</p><pre class="brush: objc; title: ; notranslate">
- (void)noArgBlock:(void (^)(void))block {
    // Do something...
     
    // Call our block
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), block);
}
</pre><p>We&#8217;re using the GCD dispatch function here to trigger our block asynchronously on a low-priority queue.  Blocks can be passed around as variables, so we don&#8217;t have to explicitly define our own inline block here like we did in the animation or image examples at the beginning of this article.</p><p>Armed with all that syntax in mind, lets create a block that accepts an argument, and I&#8217;ll show you how to use it.</p><pre class="brush: objc; title: ; notranslate">
- (void)hasArgsBlock:(void (^)(NSString *name, BOOL animated))block {
    block(@&quot;FOO&quot;, NO);
}
</pre><p>Remember from what I said that the second set of parenthesis in a block definition is the argument list you&#8217;ll be supplying to the block.  In this case, we&#8217;re accepting a callback that takes an <tt>NSString</tt> and a <tt>BOOL</tt> argument.  This is a contrived example since we&#8217;re simply dispatching the block immediately, but we could just as easily include our block call in our own block callback as the result of a <tt>UIView</tt> animation, an <tt>NSURLConnection</tt> completion block, or anything else.  A user of this method could look like this:</p><pre class="brush: objc; title: ; notranslate">
[self hasArgsBlock:^(NSString *name, BOOL animated) {
    NSLog(@&quot;Name: %@, animated %d&quot;, name, animated);
}];
</pre><h2>How do I store a block as an ivar?</h2><p>This is a much trickier question, and is one of the things that makes people run screaming from blocks, assuming they didn&#8217;t already do so when they saw the &#8220;<tt>void(^)(void)</tt>&#8221; syntax soup.  Consider the example where you want to store a block for later use, or re-use.  If we want to store a void block, a simple solution is to use a built-in GCD type to reference blocks.</p><p>The <tt>dispatch_block_t</tt> type can be used.</p><pre class="brush: objc; title: ; notranslate">
@interface MyViewController : UIViewController {
    dispatch_block_t _simpleBlock;
}
 
@property (nonatomic, copy) dispatch_block_t simpleBlock;
</pre><p>If you want to store a block that either accepts arguments or returns a value, it&#8217;s possible to use the block-parenthesis-soup as the type definition for an ivar.  For example, assume we want an ivar named &#8220;<tt>completionBlock</tt>&#8221; defined within our class. We can do so with the following code:</p><pre class="brush: objc; title: ; notranslate">
@interface MyViewController : UIViewController {
    void (^completionBlock)(NSString *name, BOOL animated);
}
</pre><p>However that looks hideous, and is difficult to maintain.  Instead it&#8217;s in your best interest to define your own custom type based on the block-soup you&#8217;d use in a method declaration.  If we wanted to create a typedef for our above block, the one that accepts a <tt>name</tt> and <tt>animated</tt> property.  We could do so with the following declaration.</p><pre class="brush: objc; title: ; notranslate">
typedef void (^MyCompletionBlock)(NSString *name, BOOL animated);
</pre><p>By including a name after the carat symbol you can assign the block definition a name.  Then, later, you can use that typedef in an ivar, in a property, or even as an argument to another method.</p><pre class="brush: objc; title: ; notranslate">
@interface MyViewController : UIViewController {
    MyCompletionBlock _completeBlock;
}
 
@property (nonatomic, copy) MyCompletionBlock completeBlock;
 
- (void)storeMyBlock:(MyCompletionBlock)block;
</pre><p>Since blocks are objects, you need to copy them if you want to store them as a property, and don&#8217;t forget to release them when you&#8217;re done with them, or in your class&#8217; <tt>dealloc</tt> method.</p><h2>Closures, variables, and retain cycles</h2><p>As I mentioned above, blocks work as closures, meaning you have access to the local variables within the scope a block is defined in.  This makes your code really easy to work with, but there are some limitations that are imposed for some very good reasons.  Consider the following example:</p><pre class="brush: objc; title: ; notranslate">
NSArray *someArray = ...;
int myCount = 0;
[someArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    int someValue = [obj intValue];
    myCount += someValue;
}];
</pre><p>This is a great way to perform an operation against an array or set using blocks because it will take advantage of multiple cores to be able to run your code faster when it&#8217;s possible.  However the above code won&#8217;t work if you actually tried it, because there&#8217;s a specific limitation in blocks which prevent you from writing to values declared outside of the block.  Think of it as a thread-locking problem. If you were to build that above code, you&#8217;d get an error that says &#8220;Variable is not assignable (missing __block type specifier)&#8221;.</p><p>It&#8217;s simple enough to work around this.  You can use the &#8220;<tt>__block</tt>&#8221; flag when declaring a variable so you can allow it to be writeable from within a block.  For example, the above code could just have this one change and everything would work as you&#8217;d expect:</p><pre class="brush: objc; title: ; notranslate">
 __block int myCount = 0;
</pre><p>One other gotcha is regarding retain cycles when using the special &#8220;self&#8221; variable.  In the case where you retain a block and, within that block you refer to your &#8220;self&#8221; object, this will cause an unbroken retain cycle where the block is retained by self, and &#8220;self&#8221; is retained by the block.</p><pre class="brush: objc; title: ; notranslate">
self.completionBlock = ^(NSData *result) {
    [self saveFile:result];
};
</pre><p>This little block will take some data returned from some code and save it in some way.  However because the &#8220;<tt>self</tt>&#8221; variable is retained by the block, as well as the scope outside of the block, this block will leak memory.  Yet again, this is easily solved by declaring a &#8220;weak&#8221; reference to the self variable, and then using that within the block.  If you&#8217;ve ever worked in JavaScript you&#8217;ll be familiar with this pattern.  The resulting code would look like the following:</p><pre class="brush: objc; title: ; notranslate">
__block __typeof__(self) _self = self;
self.completionBlock = ^(NSData *result) {
    [_self saveFile:result];
};
</pre><h2>Bringing it all together</h2><p>Blocks are an extraordinary enhancement to the language, and if you take full advantage of it in your applications you&#8217;ll be able to seamlessly take advantage of faster language features, your code can spread across multiple cores seamlessly, and you can easily break serialized tasks into fast divisible units of labour.</p><p>Take a look through the various block APIs that Apple supports, and embrace it as much as you can.  In the long run it&#8217;ll make your code easier to understand, and faster as technology advances.  Don&#8217;t be left behind!</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nachbaur?a=28GHYLhyOwo:8oI1sEnpNGo:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=bcOpcFrp8Mo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=28GHYLhyOwo:8oI1sEnpNGo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=28GHYLhyOwo:8oI1sEnpNGo:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=28GHYLhyOwo:8oI1sEnpNGo:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nachbaur?i=28GHYLhyOwo:8oI1sEnpNGo:V_sGLiPBpWU" border="0"></img></a>
</div>]]></content:encoded> <wfw:commentRss>http://nachbaur.com/blog/using-gcd-and-blocks-effectively/feed</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>Back to Basics: Using KVO</title><link>http://nachbaur.com/blog/back-to-basics-using-kvo</link> <comments>http://nachbaur.com/blog/back-to-basics-using-kvo#comments</comments> <pubDate>Fri, 29 Jul 2011 21:38:43 +0000</pubDate> <dc:creator>Michael Nachbaur</dc:creator> <category><![CDATA[Objective-C]]></category> <category><![CDATA[apple]]></category> <category><![CDATA[Back To Basics]]></category> <category><![CDATA[development]]></category> <category><![CDATA[iphone]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[tutorial]]></category> <guid isPermaLink="false">http://nachbaur.com/?p=664</guid> <description><![CDATA[One of the things I like most about Apple&#8217;s iOS SDK is the consistent and easy-to-use API they provide.  Across all their different frameworks there&#8217;s a pattern at work that makes using their classes easy to understand.  This is due in part to the simplicity for configuring those objects.  In most cases you don&#8217;t need [...]]]></description> <content:encoded><![CDATA[<div
class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fback-to-basics-using-kvo"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fback-to-basics-using-kvo&amp;source=NachoMan&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6239b17e17b21092b11716b59a2de343&amp;b=2" height="61" width="50" /><br
/> </a></div><p>One of the things I like most about Apple&#8217;s iOS SDK is the consistent and easy-to-use API they provide.  Across all their different frameworks there&#8217;s a pattern at work that makes using their classes easy to understand.  This is due in part to the simplicity for configuring those objects.  In most cases you don&#8217;t need to call cryptic methods to setup or teardown classes.  If you want to change a label’s font, you just set a property.  If you want to add a new set of tabs to a UITabBarController, you simply have to assign an array of view controllers to the &#8220;<tt>viewControllers</tt>&#8221; property and away you go.<br
/> <span
id="more-664"></span><br
/> This up front simplicity comes at a cost however: somebody had to write code to intercept the setting of those properties and update the view to reflect the changes made.  Fortunately for those developers at Apple, Cocoa and Cocoa Touch makes this simple through the use of Key-Value-Observing (KVO).  If you know how to use it, you can do the same thing in your applications as well.  Read on to see what I do to make implementing KVO in my projects easy and intuitive.</p><h2>What is Key-Value-Observing?</h2><p>Key-Value-Observing, or more commonly KVO, is a mechanism by which you can observe changes to keys and their values bound to an object.  It lets you make arbitrary objects aware of changes made to values in other objects that are important to you.  When those values are changed at all, the <tt>observeValueForKeyPath:ofObject:change:context:</tt> method is invoked on the listener, or &#8220;observer&#8221;.  In essence, it lets you listen to when people change properties on your object.</p><p>You might say &#8220;Really? That&#8217;s all it does? I can get the same by creating a custom setter!&#8221; and you might be right, but there&#8217;s several reasons why creating custom setters to handle update logic might be undesirable:</p><ol><li>It&#8217;s easy to create one or two custom setters, but quite tedious if you have lots of properties you want to observe.</li><li>Custom setters only work if you are monitoring properties under your control, but impossible if you want to monitor changes made to other objects you encapsulate.</li><li>You have to implement your own retain/release/copy cycles manually, instead of simply using <tt>@synthesize</tt>.</li><li>You have to manually keep track of what the old and new values of a property, if they’re important to you.</li><li>Your code looks like dog food.</li></ol><p>Using KVO in a class essentially buys you flexibility and easy-to-read code, and with a few general practices can be made easy to read and easy to extend.</p><h2>Setting up KVO the hard way</h2><p>Many developers getting started with KVO, myself included, typically start by assigning observers for one or two keyPath properties in either their init or viewDidLoad methods.  Then, within their <tt>observeValueForKeyPath:ofObject:change:context:</tt> method they will have code to respond to those setting changes.</p><p>As an example lets assume we’re creating a UIView subclass that has a UIColor property that controls the display of several subviews.</p><pre class="brush: objc; title: ; notranslate">
@property (nonatomic, copy) UIColor *color;
</pre><p>When that property changes lets make our view update all our sub-views to the appropriate color. We could do this with a custom setter, like so:</p><pre class="brush: objc; title: ; notranslate">
- (void)setColor:(UIColor *)color {
    if (color != color) {
        [color release];
        color = [color retain];
 
        mTitleLabel.textColor = color;
        mDescriptionLabel.textColor = color;
        [mButton setTitleColor:color
                      forState:UIControlStateNormal];
    }
}
</pre><p>For the purposes of this example though, lets utilize KVO for this.</p><pre class="brush: objc; title: ; notranslate">
 - (id)initWithFrame:(CGRect)frame { 
    self = [super initWithFrame:frame];
    if (self) { 
        [self addObserver:self
               forKeyPath:@&quot;color&quot;
                  options:0
                  context:nil];
    }
}
 
 - (void)observeValueForKeyPath:(NSString*)keyPath
                      ofObject:(id)object
                        change:(NSDictionary*)change
                       context:(void*)context
{
	if ([keyPath isEqualToString:@&quot;color&quot;]) {
        mTitleLabel.textColor = self.color;
        mDescriptionLabel.textColor = self.color;
        [mButton setTitleColor:self.color
                      forState:UIControlStateNormal];
	}
 
    else {
        [super observeValueForKeyPath:keyPath
                             ofObject:object
                               change:change
                              context:context];
    }
}
</pre><p>In the <tt>initWithFrame:</tt> method we add ourselves as an observer of the keyPath “<tt>color</tt>”, passing in the default options.  We also define a method that Cocoa Touch uses to notify the observer, in this case “<tt>self</tt>”, when a keyPath has been changed.  This method is invoked for different properties that are changed, so you should always pass the message along to “<tt>super</tt>” if this method is called for a property you didn’t explicitly add as an observer.</p><p>While the above code does look longer than the custom setter equivalent, in the long-run this code is much easier to extend over the life of your class, especially as you add more complex behaviors.</p><h2>Keeping Track of Your Key Paths</h2><p>As my experience with KVO improved, so did my techniques for managing my observers, responding to keyPath value changes, and generally keeping my code clean.  One of the things I found was that it is useful to keep a list of the keyPaths you’re observing so that you can conveniently iterate over them programmatically.</p><p>To illustrate my point, consider an example where you expose multiple subviews as properties, and when some values change you would like to perform some sort of redraw operation.</p><pre class="brush: objc; title: ; notranslate">
- (id)initWithFrame:(CGRect)frame {
     if (ObservableKeys == nil) {
        ObservableKeys = [[NSSet alloc] initWithObjects:
                          @&quot;titleLabel.font&quot;,
                          @&quot;descriptionLabel.font&quot;,
                          // ...
                          nil];
    }
 
    self = [super initWithFrame:frame];
    if (self) {
         for (NSString *keyPath in ObservableKeys)
            [self addObserver:self
                   forKeyPath:keyPath
                      options:0
                      context:nil];
    }
}
 
 - (void)dealloc {
    for (NSString *keyPath in ObservableKeys)
        [self removeObserver:self
                  forKeyPath:keyPath];
    [super dealloc];
}
 
  - (void)observeValueForKeyPath:(NSString*)keyPath
                      ofObject:(id)object
                        change:(NSDictionary*)change
                       context:(void*)context
{
    if ([ObservableKeys containsObject:keyPath]) {
        [self redrawView];
	}
 
    else {
        [super observeValueForKeyPath:keyPath
                             ofObject:object
                               change:change
                              context:context];
    }
}
</pre><p>As you can see not only would this be impossible to do with custom setters, but we managed to respond to several different property changes using a single block of code.</p><p>Additionally, keeping a static NSSet object around with a list of the keys you’re observing is convenient for several reasons:</p><ol><li>It lets you easily add your object as an observer of several keyPaths without having to copy/paste code.</li><li>Your generated code is tighter because you don’t have to worry about inline strings being littered throughout your class.</li><li>If you change the name of a keyPath, it happens in a much more limited area.</li></ol><p>There are other advantages, but this is just the tip of the iceberg.</p><h2>Implementing KVO in a UITableViewCell Subclass</h2><p><a
href="http://nachbaur.com/wp-content/uploads/2011/07/Screen-shot-2011-07-29-at-2.16.52-PM.png" rel="lightbox[664]"><img
src="http://nachbaur.com/wp-content/uploads/2011/07/Screen-shot-2011-07-29-at-2.16.52-PM-159x300.png" alt="" title="Gloss icon screenshot" width="159" height="300" class="alignright size-medium wp-image-684" /></a>In order to illustrate how to build a more complicated feature using KVO, lets create a UITableViewCell subclass that makes it easy to create a gloss icon in your table cells, just like the iTunes App Store app.  If we’re successful we should be able to create a table cell whose icon looks like the screenshot to the right.</p><p>Instead of requiring us to worry about the details of rendering the gloss icon overlay every time we want to display an app icon, lets create a property on our table cell that encapsulates this behavior.  Ideally we should be able to set the app icon’s original image once, and the UITableViewCell imageView.image property should be set to the appropriate content.  We could do this with a custom accessor, but I’d like to show you an easy way to do this with KVO.</p><pre class="brush: objc; title: ; notranslate">
#import &lt;UIKit/UIKit.h&gt;
 
@interface AppStoreItemView : UITableViewCell
 
@property (nonatomic, retain) UIImage *icon;
@property (nonatomic) BOOL iconNeedsGlossEffect;
 
@end
</pre><p>You can see from our interface declaration that we’re adding two properties for the icon image itself, and a boolean indicating whether or not we want the gloss effect.  Now lets look at the implementation.</p><pre class="brush: objc; title: ; notranslate">
#import &quot;AppStoreItemView.h&quot;
#import &lt;QuartzCore/QuartzCore.h&gt;
 
static NSSet * ObservableKeys = nil;
static NSString * const IconKeyPath = @&quot;icon&quot;;
static NSString * const IconNeedsGlossEffectKeyPath
    = @&quot;iconNeedsGlossEffect&quot;;
 
@interface AppStoreItemView ()
 
- (UIImage*)glossImageForImage:(UIImage*)image;
 
@end
 
@implementation AppStoreItemView
 
@synthesize icon;
@synthesize iconNeedsGlossEffect;
 
- (id)initWithStyle:(UITableViewCellStyle)style
    reuseIdentifier:(NSString *)reuseIdentifier
{
    // Setup our set of observable keys only once
    if (nil == ObservableKeys) {
        ObservableKeys = [[NSSet alloc] initWithObjects:
                          IconKeyPath,
                          IconNeedsGlossEffectKeyPath,
                          nil];
    }
 
    self = [super initWithStyle:UITableViewCellStyleSubtitle
                reuseIdentifier:reuseIdentifier];
    if (nil != self) {
        // Add observers for each of the keyPaths we care about
        for (NSString *keyPath in ObservableKeys)
            [self addObserver:self
                   forKeyPath:keyPath
                      options:(NSKeyValueObservingOptionOld |
                               NSKeyValueObservingOptionNew)
                      context:nil];
         
        self.imageView.layer.cornerRadius = 10.0;
        self.imageView.layer.masksToBounds = YES;
    }
     
    return self;
}
 
- (void)dealloc {
    // Tidy up and remove all the observers when the view is destroyed
    for (NSString *keyPath in ObservableKeys)
        [self removeObserver:self
                  forKeyPath:keyPath
                     context:nil];
     
    [super dealloc];
}
 
- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
    // If the keyPath being changed isn't one we care about,
    // pass this up to super and return immediately.
    if (![ObservableKeys containsObject:keyPath]) {
        [super observeValueForKeyPath:keyPath
                             ofObject:object
                               change:change
                              context:context];
        return;
    }
     
    // Fetch the old and new objects from the change dictionary
    id oldObject = [change objectForKey:NSKeyValueChangeOldKey];
    id newObject = [change objectForKey:NSKeyValueChangeNewKey];
     
    // Detect null values, since the changed object references
    // are object references.
    if ([NSNull null] == (NSNull*)oldObject)
        oldObject = nil;
    if ([NSNull null] == (NSNull*)newObject)
        newObject = nil;
     
    // Update imageView when the icon is changed
    if ([IconKeyPath isEqualToString:keyPath]) {
        self.imageView.image = [self glossImageForImage:newObject];
    }
     
    // If the gloss effect is changed, refresh the gloss image
    else if ([IconNeedsGlossEffectKeyPath isEqualToString:keyPath]) {
        self.imageView.image = [self glossImageForImage:self.icon];
    }
}
 
- (UIImage*)glossImageForImage:(UIImage*)image {
    // Code goes here to create the gloss image
    // and return the resulting image.  See the
    // sample code for the full example.
    return mergedImage;
}
 
@end
</pre><p>This code may seem complicated, but in the end it is very straight-forward. I’m also introducing a few additional concepts here that I’d like to call out specifically.</p><h3>Observing Options</h3><p>KVO allows you to specify different options for when you’re observing a set of keyPaths. It’s a bit-mask, so you can enable multiple options simultaneously.  In this example I’m indicating that I want to be notified of both the old and new values of these properties.  When the icon is changed, the change dictionary supplied to our callback tells us both the old and new values of the property.</p><h3>Using static strings for keyPaths</h3><p>This is a pattern I use which helps for simplicity of code, as well as a defensive coding mechanism. By declaring static NSString variables for each keyPath you’re observing, it ensures you won’t accidentally type the wrong keyPath somewhere in your code. It also gives you a single place for defining, or changing, the keyPath you’re interested in observing.</p><h3>Returning early from the observer callback</h3><p>In this example I’m returning early in the block, when the keyPath is not in my set of “<tt>ObservableKeys</tt>”. This makes the callback code cleaner since you eliminate one extra nested “if” block, and helps to prevent mistakes.</p><h3>Detecting null values in the observer callback</h3><p>I find it useful to extract values from the change dictionary as early as possible, and then cast those values as needed.</p><h3>Using private methods for observer callback behaviour</h3><p>If you’re not careful your observer callback can get quite large.  It’s powerful to be able to have a single point where complex behaviours and patterns can be established between different properties, but you should make sure it doesn’t become overgrown with logic. It’s better to start out by pushing complex logic into private methods, and simply invoke that from within your callback.</p><h1>Where to go for help</h1><p>Apple’s own documentation, as always, is a good source of information but it can tend to be a lot to take in.  At this point you should have a basic understanding of how KVO works, and how you can use it in your application.  You can also <a
href="http://github.com/NachoMan/KVOTest1">download the sample application</a> created above at Github.</p><p>Once you get started, finding answers to your questions becomes simpler when you’ve gotten the hang of KVO.  Good luck, and happy coding!</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nachbaur?a=Xa3EO9K-EVw:kthzRQKDRe8:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=bcOpcFrp8Mo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=Xa3EO9K-EVw:kthzRQKDRe8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=Xa3EO9K-EVw:kthzRQKDRe8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=Xa3EO9K-EVw:kthzRQKDRe8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nachbaur?i=Xa3EO9K-EVw:kthzRQKDRe8:V_sGLiPBpWU" border="0"></img></a>
</div>]]></content:encoded> <wfw:commentRss>http://nachbaur.com/blog/back-to-basics-using-kvo/feed</wfw:commentRss> <slash:comments>8</slash:comments> </item> <item><title>Back to Basics: Simple UITableViews</title><link>http://nachbaur.com/blog/back-to-basics-simple-uitableviews</link> <comments>http://nachbaur.com/blog/back-to-basics-simple-uitableviews#comments</comments> <pubDate>Thu, 28 Apr 2011 16:30:15 +0000</pubDate> <dc:creator>Michael Nachbaur</dc:creator> <category><![CDATA[Objective-C]]></category> <category><![CDATA[apple]]></category> <category><![CDATA[Back To Basics]]></category> <category><![CDATA[development]]></category> <category><![CDATA[iphone]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[tutorial]]></category> <guid isPermaLink="false">http://nachbaur.com/?p=626</guid> <description><![CDATA[Following up on my previous post in this series, I&#8217;m going to continue talking about beginner topics that I and many other developers take for granted. So for this entry in my &#8220;Back To Basics&#8221; series I&#8217;d like to talk about UITableViews, and how to simply and easily construct one without convoluted or confusing code. [...]]]></description> <content:encoded><![CDATA[<div
class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fback-to-basics-simple-uitableviews"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fback-to-basics-simple-uitableviews&amp;source=NachoMan&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6239b17e17b21092b11716b59a2de343&amp;b=2" height="61" width="50" /><br
/> </a></div><p>Following up on my previous post in this series, I&#8217;m going to continue talking about beginner topics that I and many other developers take for granted. So for this entry in my &#8220;Back To Basics&#8221; series I&#8217;d like to talk about UITableViews, and how to simply and easily construct one without convoluted or confusing code.</p><p>This topic in particular is something I&#8217;ve struggled over in the past and never managed to find a clear example for how to get started. Certainly there&#8217;s a lot of examples to show how to construct a table view, how to create a datasource for it, and the basics for how to construct cells. But hardly anyone tells you how to easily and conveniently construct a menu of options without going down a maze of twisty passages.</p><p>So today I&#8217;ll show you how you can use simple &#8220;typedef&#8221; structures to describe and control a simple menu of options.</p><h1><span
id="more-626"></span>Basics of UITableView datasources</h1><p>Before we get started I wanted to go over the UITableViews themselves. Essentially they&#8217;re broken down into three parts:</p><ol><li>The tableview itself;</li><li>The datasource which supplies the tableview with information about the sections and rows that should be shown in the tableview;</li><li>The delegate which responds to user interactions, such as selecting an individual cell.</li></ol><p>There are many reasons why they&#8217;re broken down into those parts, but the big reason is this: performance.</p><p>Table views are great because of the sheer speed at which you can scroll through one, even on a tiny device such as an iPhone. It&#8217;s trivial to even zoom through a table containing 10,000 rows, and this is because the table only ever constructs views for the cells that happen to be visible at a given moment. If only 10 rows can be visible at a time, that&#8217;s a much smaller amount of memory and CPU needed to construct and paint those views on the screen.</p><p>The other performance benefit you get is the views for individual cells are reused, meaning you only have to (theoretically) construct them once, and all subsequent cells simply change the values for each cell.</p><p>Due to all of that, the datasource is interrogated by the table, asking questions like this:</p><ul><li>How many sections are in the table?</li><li>How many rows are in section X?</li><li>What&#8217;s the title of section X?</li><li>Give me a UITableViewCell for row Y in section X</li></ul><p>And so on. Typically your delegate and datasource is the same object, so you&#8217;ll just have a few methods that answer those questions.</p><h1>Easily displaying a menu of options</h1><p><a
href="http://nachbaur.com/wp-content/uploads/2011/04/aCookie-Settings.png" rel="lightbox[626]"><img
class="alignright size-medium wp-image-631" title="aCookie Settings" src="http://nachbaur.com/wp-content/uploads/2011/04/aCookie-Settings-159x300.png" alt="" width="159" height="300" /></a>Recently on an update to my oldest iOS application, <a
href="http://acookie.info">aCookie Fortune</a>, I wanted to show a menu of options. Some simple buttons, a multiple-choice selection, and a few toggle buttons. Nothing major, but I didn&#8217;t want to make things overly complicated. And more to the point, I wanted to build the settings menu as quickly as possible because I don&#8217;t have a lot of time in my day, especially for an app that generates as little revenue as this one does.</p><p>So when I wanted to have an easily configurable tableview that allowed me to quickly change the order of sections, rows, intermix cell types and accessory views easily, I turned to my good old friend &#8220;enum&#8221;.</p><p>You see, I use enums to control the order of sections, the order of rows, and so forth. If you&#8217;re not familiar with an enum, it&#8217;s a feature of C that lets you create an enumerated list of variables easily.</p><h2>Keeping track of sections</h2><p>In order to define the order of my sections, and the number of visible sections, all I do is declare the following:</p><pre class="brush: objc; title: ; notranslate">
enum {
	SettingsSectionSettings,
	SettingsSectionCategories,
	CountSettingsSections
};
</pre><p>This simply describes 3 variables, each with a value 0, 1 and 2. But when the tableview asks my datasource how many sections are in my table, all I have to do is this:</p><pre class="brush: objc; title: ; notranslate">
- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView {
    return CountSettingsSections;
}
</pre><p>Even though I only plan to show two sections in my table, I declare a third enum constant that is used to show how many sections will be displayed. If I later choose to add an extra section in the middle that will push the &#8220;CountSettingsSections&#8221; key down, resulting in it having a higher number. This conveniently keeps track of the number of sections without me having to maintain a separate counter.</p><h2>Number of rows per section</h2><p>Another thing I need to tell my tableview about is how many rows will be in each section. Similar to the listing of sections, the listing of rows in the first section is controlled by yet another enum listing.</p><pre class="brush: objc; title: ; notranslate">
enum {
	SettingsSectionSettingsRowInBed,
	SettingsSectionSettingsRowSharingOptions,
	CountSettingsSectionSettingsRows,
};
</pre><p>The second section, the listing of categories, will be controlled directly by an array of the available categories. So we simply return the appropriate value based on which section number the tableview is asking the datasource about.</p><pre class="brush: objc; title: ; notranslate">
- (NSInteger)tableView:(UITableView*)tableView
 numberOfRowsInSection:(NSInteger)section {
	switch (section) {
		case SettingsSectionSettings:
			return CountSettingsSectionSettingsRows;
        case SettingsSectionCategories:
            return [allCategories count];
		default:
			return 0;
	}
}
</pre><p>Notice in the tableView:numberOfRowsInSection: method we use a switch statement to test which section we&#8217;re being asked about? Conveniently enough we&#8217;re able to use the constants defined in our first enum which lists the sections we&#8217;ll use. The handy thing is that if you want to reorganize your sections, all you have to do is reorganize the associated constants in your enum and your section numbers will all update accordingly.</p><h2>Section titles</h2><p>There isn&#8217;t much difference between returning the number of rows in a section, or the titles for the sections themselves. Again notice that we&#8217;re using the section enum to evaluate which section we&#8217;re being asked about.</p><pre class="brush: objc; title: ; notranslate">
- (NSString*)tableView:(UITableView*)tableView
titleForHeaderInSection:(NSInteger)section {
	switch (section) {
		case SettingsSectionSettings:
			return NSLocalizedString(@&quot;Sharing settings&quot;, nil);
        case SettingsSectionCategories:
            return NSLocalizedString(@&quot;Fortune categories&quot;, nil);
		default:
			return nil;
	}
}
</pre><p
style="padding-left: 30px;">Note: You may notice that I&#8217;m not simply returning the plain strings, but am instead making them localizable. Do yourself a favour and just do that. Trust me.</p><h2>Cell contents</h2><p>Rendering the cell contents is fairly straight-forward, but since there&#8217;s typically more code involved in populating your cells I prefer to break those out into separate methods.</p><pre class="brush: objc; title: ; notranslate">
- (UITableViewCell *)tableView:(UITableView*)tableView
         cellForRowAtIndexPath:(NSIndexPath*)indexPath {
    static NSString *CellIdentifier = @&quot;CellDefault&quot;;
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
                                       reuseIdentifier:CellIdentifier] autorelease];
    }
	switch (indexPath.section) {
		case SettingsSectionSettings:
			[self configureSettingsCell:cell atRow:indexPath.row];
			break;
		case SettingsSectionCategories:
			[self configureCategoriesCell:cell atRow:indexPath.row];
			break;
		default:
			break;
	}
    return cell;
}
</pre><p>This block of code sets up a common cell, potentially reusing it for performance reasons, and then uses our section enum to determine which section the row we&#8217;re being asked to provide lives in.  Then depending on section we invoke a different method, supplying the row number that we need to return.</p><h1>Wrapping up</h1><p>It&#8217;s really that simple. You can create fairly sophisticated interfaces, or part of an interface, using nothing but enums and switch statements. For more involved interfaces you&#8217;ll want to mature into using Core Data or your own private data structures to provide your table views with information. But even in complicated applications there are instances where &#8220;Simple is better&#8221;.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nachbaur?a=NRzesIoPaFM:6oYHHf0xncg:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=bcOpcFrp8Mo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=NRzesIoPaFM:6oYHHf0xncg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=NRzesIoPaFM:6oYHHf0xncg:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=NRzesIoPaFM:6oYHHf0xncg:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nachbaur?i=NRzesIoPaFM:6oYHHf0xncg:V_sGLiPBpWU" border="0"></img></a>
</div>]]></content:encoded> <wfw:commentRss>http://nachbaur.com/blog/back-to-basics-simple-uitableviews/feed</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Back To Basics: Positioning UIViews</title><link>http://nachbaur.com/blog/basics-positioning-uiviews</link> <comments>http://nachbaur.com/blog/basics-positioning-uiviews#comments</comments> <pubDate>Fri, 22 Apr 2011 16:30:52 +0000</pubDate> <dc:creator>Michael Nachbaur</dc:creator> <category><![CDATA[Objective-C]]></category> <category><![CDATA[apple]]></category> <category><![CDATA[Back To Basics]]></category> <category><![CDATA[development]]></category> <category><![CDATA[iphone]]></category> <category><![CDATA[tutorial]]></category> <guid isPermaLink="false">http://nachbaur.com/?p=601</guid> <description><![CDATA[These days I&#8217;ve been working on some fairly advanced iOS development techniques on my various projects: I&#8217;ve taught myself (badly) about Core Audio, I&#8217;m learning OpenGL, I&#8217;m developing a series of applications using Core Data, asynchronous parsing of JSON from a streaming HTTP connection, etc. It&#8217;s extremely fun and easy once you understand the basics. What I [...]]]></description> <content:encoded><![CDATA[<div
class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fbasics-positioning-uiviews"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fbasics-positioning-uiviews&amp;source=NachoMan&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6239b17e17b21092b11716b59a2de343&amp;b=2" height="61" width="50" /><br
/> </a></div><p>These days I&#8217;ve been working on some fairly advanced iOS development techniques on my various projects: I&#8217;ve taught myself (badly) about Core Audio, I&#8217;m learning OpenGL, I&#8217;m developing a series of applications using Core Data, asynchronous parsing of JSON from a streaming HTTP connection, etc. It&#8217;s extremely fun and easy once you understand the basics.</p><p>What I tend to forget however is that you have to crawl before you can walk, and many people still struggle with some of the simpler techniques that I&#8217;ve learned that may not be so obvious, even when reading books or tutorials on Objective-C programming.</p><p>Since my previous series of articles on Core Animation (<a
title="Animating Interfaces with Core Animation: Part 1" href="http://nachbaur.com/blog/core-animation-part-1">Part 1</a>, <a
title="Animating Interfaces with Core Animation: Part 2" href="http://nachbaur.com/blog/core-animation-part-2">Part 2</a>, <a
title="Animating Interfaces with Core Animation: Part 3" href="http://nachbaur.com/blog/core-animation-part-3">Part 3</a>, <a
title="Animating Interfaces with Core Animation: Part 4" href="http://nachbaur.com/blog/core-animation-part-4">Part 4</a>) were so well received, I thought I&#8217;d do another series of articles titled &#8220;Back To Basics&#8221;.</p><p>So without further ado, I give you the first part in my series: Positioning UIViews.</p><h1><span
id="more-601"></span>One size does not fit all</h1><p>First please forgive me for the horrible pun in this title. Originally I meant that there are several different ways to resize and position views in UIKit, but the pun about sizes was a bonus. The point is that there are several properties UIView and UIView subclasses have that can influence their size and position, and none of them are wrong. However there are circumstances where one is better or more convenient to use than the other.</p><h2>view.frame</h2><p>The most common method people seem to use for positioning their views is through the &#8220;frame&#8221; property. For those of you unfamiliar with it, this is used to set the X,Y position of the top-left corner, and the Width/Height of the view. Many people use this without realizing it, because some views are created like so:</p><pre class="brush: objc; title: ; notranslate">
CGRect fr = CGRectMake(x, y, w, h);
UIView *view = [[UIView alloc] initWithFrame:fr];
</pre><p>While this is a powerful method to layout interfaces, it can get pretty tedious if you&#8217;re arranging several views that need to be positioned relative to each other. Consider a case where you want to align a row of buttons and distribute them evenly across the screen.</p><pre class="brush: objc; title: ; notranslate">
NSArray *allButtons; // Add UIButton objects here
int btnNum = 0;
int numBtns = [allButtons count];
for (UIButton *button in allButtons) {
   CGFloat w, h, x, y;
   w = button.frame.size.width;
   h = button.frame.size.height;
   x = self.view.frame.size.width / numBtns * btnNum;
   y = self.view.frame.size.height / 2 - h / 2;
   button.frame = CGRectMake(x, y, w, h);
   [self.view addSubview:button];
   btnNum++;
}
</pre><p>That is a lot of extra code that looks fairly messy. If you have a few instances of that, your code can get pretty cluttered.</p><h2>view.center</h2><p>The &#8220;center&#8221; property represents the X,Y coordinate for the center-point of your view. I know a lot of you will say &#8220;Well, duh!&#8221; but what you may not realize is that it&#8217;s a read/write property that is automatically tied to the &#8220;frame&#8221; property. So changing the frame for your view will automatically update your &#8220;center&#8221; property, and vice-versa.</p><p>I prefer setting the center property when aligning or arranging multiple views relative to each other because:</p><ol><li>You don&#8217;t risk accidentally changing the size of the views;</li><li>You don&#8217;t have to constantly divide by 2 to align views;</li><li>The code is much more concise.</li></ol><p>This property is especially useful when moving views using animations.</p><pre class="brush: objc; title: ; notranslate">
[UIView beginAnimations:@&quot;BounceAnim&quot; context:nil];
[UIView setAnimationRepeatCount:1];
[UIView setAnimationRepeatAutoreverses:YES];
myView.center = CGPointMake(myView.center.x,
                            myView.center.y + 10);
[UIView commitAnimations];
</pre><p>This simple bit of code lets you animate a view so that it bounces once. By using the &#8220;center&#8221; property we can trust that we&#8217;re simply moving the view around, instead of having to worry about maintaining its size.</p><h2>view.bounds</h2><p>Similar to the &#8220;center&#8221; property, the &#8220;bounds&#8221; property is related to the &#8220;frame&#8221; property. When you alter the bounds, it changes the size of the view relative to its center point. This is really convenient if you adjust the center and bounds independently. For example, you can set the bounds property to a CGRect region with an origin of (0,0) to set its size, and can then adjust the center coordinate to position it in the screen.</p><pre class="brush: objc; title: ; notranslate">
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.center = CGPointMake(x, y);
view.bounds = CGRectMake(0, 0, w, h);
</pre><p>The example code above shows us creating a brand new UIView instance, and changing its center and bounds properties independently. Even though we&#8217;ll be setting those properties after, when we call &#8220;initWithFrame:&#8221; we still have to supply a valid CGRect value.  In this case we use the constant &#8220;CGRectZero&#8221; which essentially means a frame with all values set to 0.</p><p>Managing your views like this is convenient when you either don&#8217;t know what size the view should be yet, or you don&#8217;t know where on the screen it should be. Or, frankly, it might make your code prettier to separate the construction and positioning of your views.</p><h2>view.transform</h2><p>As you may have seen in my previous series on Core Animation, Apple provides a very sophisticated animation framework for your interface. What many people don&#8217;t realize is that every UIView object in UIKit is backed by a CALayer, which is where the actual drawing operations happen (there&#8217;s more to it than this simple explanation, but for now it&#8217;ll do).</p><p>By setting the &#8220;transform&#8221; property of a view to a CGAffineTransform you can alter the position of the view&#8217;s layer without having to explicitly move its position. Translation, rotation and even scaling or skewing your view are all possible easily with this property.</p><p>This is useful when you want to perform subtle movements such as rotations, or you want to scale your object in or out. For example, you may want a button to &#8220;throb&#8221; by animating its scale.  Or you may want your view to spin, even in 3D.  These are all examples of what you&#8217;d use this property for.</p><h2>view.autoresizingMask</h2><p>This property is often neglected by beginner iOS programmers and is by far one of the most useful for laying out your interfaces. Consider the situation where you want your view to resize when the device is rotated between portrait and landscape orientations. The novice programmer will detect the screen rotation and will explicitly set the &#8220;frame&#8221; property of all their views to fit the new screen size. This is the WRONG way to manage your interface.</p><div
id="attachment_651" class="wp-caption alignright" style="width: 269px"><a
href="http://nachbaur.com/wp-content/uploads/2011/04/Autoresizing-Options.png" rel="lightbox[601]"><img
class="size-full wp-image-651" title="Autoresizing Options" src="http://nachbaur.com/wp-content/uploads/2011/04/Autoresizing-Options.png" alt="" width="259" height="96" /></a><p
class="wp-caption-text">Visual guide to where each UIResizing option is used</p></div><p>Instead you can use the &#8220;autoresizingMask&#8221; property to describe how you want your view to adapt to orientation changes. Your options (shortened for brevity) are:</p><ul><li>None</li><li>FlexibleWidth</li><li>FlexibleHeight</li><li>FlexibleLeftMargin</li><li>FlexibleRightMargin</li><li>FlexibleTopMargin</li><li>FlexibleBottomMargin</li></ul><p>Consider the example of a toolbar at the bottom of your screen. If you want to have the toolbar stretch to fill the available width, but still remain snug against the bottom of the window, you can say:</p><pre class="brush: objc; title: ; notranslate">
myView.autoresizingMask = (UIViewAutoresizingFlexibleWidth |
			   UIViewAutoresizingFlexibleTopMargin);
</pre><p>Using a bitwise &#8220;OR&#8221; (the &#8220;|&#8221; pipe character) you combine multiple options together into a single value that tells UIKit how you want your view to adapt to changes to the screen, and even to changes in your view&#8217;s superview.</p><p>Another example is an interface that has the standard round &#8220;i&#8221; button in the bottom-right corner of the screen.</p><pre class="brush: objc; title: ; notranslate">
myView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
			   UIViewAutoresizingFlexibleTopMargin);
</pre><p>If you play with those values you can get around the need to explicitly position or resize your views in almost all cases.</p><h1>When in doubt, use a NIB</h1><p>If you&#8217;re just getting started, or even if you&#8217;re a veteran iOS developer, you may want to simply layout your interfaces in Interface Builder rather than positioning your views manually. The performance difference is negligible, and there&#8217;s even ways in iOS 4 and above that can cache NIBs for greater performance. And there&#8217;s nothing that says you can&#8217;t rough-in your interfaces in Interface Builder, and then customize or fine-tune it after your view has loaded.</p><p>The most important thing above all else is to just play around with your application and see what works for you. There is no single &#8220;silver bullet&#8221; to laying out your interfaces. Every case is different, and use the method that is suited to your scenario.</p><p>When in doubt, if you find you have a ton of cluttered and error-prone code for laying out your interfaces, chances are you&#8217;re just simply doing it wrong. Try something else and do what works.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nachbaur?a=QG8JlGWODdw:3ajh2s9sw6I:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=bcOpcFrp8Mo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=QG8JlGWODdw:3ajh2s9sw6I:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=QG8JlGWODdw:3ajh2s9sw6I:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=QG8JlGWODdw:3ajh2s9sw6I:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nachbaur?i=QG8JlGWODdw:3ajh2s9sw6I:V_sGLiPBpWU" border="0"></img></a>
</div>]]></content:encoded> <wfw:commentRss>http://nachbaur.com/blog/basics-positioning-uiviews/feed</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Smarter and More Reusable Core Data</title><link>http://nachbaur.com/blog/smarter-core-data</link> <comments>http://nachbaur.com/blog/smarter-core-data#comments</comments> <pubDate>Tue, 19 Apr 2011 17:30:55 +0000</pubDate> <dc:creator>Michael Nachbaur</dc:creator> <category><![CDATA[Objective-C]]></category> <category><![CDATA[Core Data]]></category> <category><![CDATA[development]]></category> <category><![CDATA[howto]]></category> <category><![CDATA[iOS]]></category> <category><![CDATA[iphone]]></category> <guid isPermaLink="false">http://nachbaur.com/?p=552</guid> <description><![CDATA[Like most developers, I look to Apple&#8217;s default application templates to get up-to-speed on what would appear as being the Right Way™ of developing apps on iOS. In practice however what you need to realize is Apple&#8217;s templates are meant to be the easiest introduction to a set of tools that can be fairly complicated [...]]]></description> <content:encoded><![CDATA[<div
class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fsmarter-core-data"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fsmarter-core-data&amp;source=NachoMan&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6239b17e17b21092b11716b59a2de343&amp;b=2" height="61" width="50" /><br
/> </a></div><p>Like most developers, I look to Apple&#8217;s default application templates to get up-to-speed on what would appear as being the Right Way™ of developing apps on iOS. In practice however what you need to realize is Apple&#8217;s templates are meant to be the easiest introduction to a set of tools that can be fairly complicated for beginners to understand.  Core Data is one of those areas. The problem is when you try to grow your application you&#8217;ve built on top of Apple&#8217;s sample template. You&#8217;ll experience some annoying growing pains, and will need to give your code a thorough washing and a fresh coat of wax to be able to mature your application.</p><p>In my code I&#8217;ve learned to share and reuse my classes with other applications I&#8217;m writing by encapsulating a lot of the boilerplate into reusable classes, as well as wrapping my whole Core Data model in a reusable static library. This wasn&#8217;t the most intuitive thing to get right, but now that it&#8217;s done it was really worth the effort. Let me show you how it&#8217;s done.</p><h1><span
id="more-552"></span></h1><p
style="padding-left: 30px;">Note: All code samples here will be for iOS4 and above and have been formatted to fit this blog post. For the sake of brevity I use blocks to make the Singleton examples easier; this is possible in iOS3.x, but it&#8217;s much more verbose.</p><h1>Default Core Data templates get it wrong</h1><p>Before I dive into any details I wanted to start with a bold statement:</p><p
style="padding-left: 30px;"><em>Apple&#8217;s sample Core Data templates suck.</em></p><p>That isn&#8217;t to say that it isn&#8217;t valuable for Core Data beginners to get started, but it isn&#8217;t a good idea to use them verbatim as an optimal approach for designing an application around Core Data. This is due to the following reasons:</p><h3>Application Delegate overloading</h3><p>Your <em>UIApplicationDelegate</em> class should be there for one thing only: responding to application&#8217;s state changes. Overloading it to manage your Core Data stack is the wrong place to do things.</p><p>There are certain database-related operations that should be called from within your application delegate, such as performing a &#8220;save&#8221; when the application is about to terminate, but those are fairly minor cases that shouldn&#8217;t drive the entire design of your application.</p><h3>Managed Object Model versioning</h3><p>The way the <em>NSManagedObjectModel</em> is constructed in Apple&#8217;s templates assumes you only have one version of your object model. You&#8217;ll have to change this code around when you add another version later in the life of your application. You might as well start on the right foot and assume your application will mature and eventually grow into a second version of its object model.</p><p>The easiest way to create an <em>NSManagedObjectModel</em>, and the way it works in Apple&#8217;s templates, is with the following call:</p><pre class="brush: objc; title: ; notranslate">
[NSManagedObjectModel modelByMergingModels:nil];
</pre><p>This essentially tells Core Data to take all available object models included with your application&#8217;s <em>[NSBundle mainBundle]</em> and merges them together into one contiguous view. This blows up in your face however if you have multiple versions of the same object model, or if your managed object model lives somewhere other than your main bundle.</p><p>Instead you can construct your managed object model like so:</p><pre class="brush: objc; title: ; notranslate">
NSManagedObjectModel *objModel;
NSString *modelPath;
NSURL *modelURL;
modelPath = [bundle pathForResource:@&quot;MyModel&quot;
						     ofType:@&quot;momd&quot;];
modelURL = [NSURL fileURLWithPath:modelPath];
objModel = [[NSManagedObjectModel alloc]
			initWithContentsOfURL:modelURL];
</pre><p>This allows you to explicitly load the current version of your object model, potentially even in a separate bundle. Rarely will you need to merge multiple object models together, and if you do there are ways around that while still being able to explicitly point Core Data at the latest versions of them all.</p><h3>Cumbersome Managed Object Context passing</h3><p>The standard Core Data template assumes your NSManagedObjectContext will be passed from view-controller to view-controller manually. This is extremely cumbersome and is prone to error. It&#8217;s much easier to provide a centralized mechanism for getting at an object context.</p><p>I tend to create a central singleton that implements my Core Data stack, which provides a convenient property for accessing the main object context.  This allows me to do something like the following:</p><pre class="brush: objc; title: ; notranslate">
NSFetchRequest *request;
// Configure the request
NSManagedObjectContext *context;
context = [DatabaseManager sharedInstance].mainObjectContext;
results = [context executeFetchRequest:request
								 error:nil];
</pre><p>Without having to pass the object context around explicitly you can gain access to your Core Data model wherever you need to.</p><p>Additionally, since NSManagedObjectContext objects aren&#8217;t thread-safe (and you should really have one context per running thread) you can create a convenience method for creating new object contexts without needing to reference your specific object model or persistent store every time.</p><h3>SQLite file storage security</h3><p>The default location for saving your SQLite database is in the Application Documents directory. This becomes a problem if you want to share documents your application creates with your user or to other applications (using <a
href="http://developer.apple.com/library/ios/documentation/general/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW20">UIFileSharingEnabled</a>). These files should be saved in the &lt;Application&gt;/Library directory so they can be backed up, but not shared with the user.</p><p>Additionally the default implementation doesn&#8217;t enable encryption of your SQLite database file, which is simple enough to do and can be vital for the protection of your database content.  The iPhone 3GS and above has hardware-level encryption and supports varying levels of security. A single call enables extremely robust <a
href="http://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/RuntimeEnvironment/RuntimeEnvironment.html#//apple_ref/doc/uid/TP40007072-CH2-SW6">file protection features</a> for files stored on disk, but only provides extra security if you ask for it.</p><h1>Your MOM is in a Static Library!</h1><p>All developers are inherently lazy and don&#8217;t want to do any unnecessary work. This is why we try to reuse as much of our code as possible. We do this by creating common classes that we can share not only between our own projects, but between each other. There are times that sharing individual files becomes a burden though, and you&#8217;d like to create some sort of reusable static library that can easily be linked into your project. I go so far as to create a separate static library target in my iOS applications, and anything not directly related to my application is created in this library.</p><p>Recently I tried to take this same approach with the Core Data implementation for a project of mine, and this is where I started to run into murky waters. The implementation classes for my various Core Data entities could easily be compiled into a static library, as well as the singleton class I use to manage my Core Data stack (persistent store, managed object model, etc). However this is all meaningless unless you have the Managed Object Model for your Core Data implementation, and accessing that from within a static library isn&#8217;t all that intuitive. There are ways to work around this however, though you have to make some tweaks to make it work.</p><p>The important thing to know about Core Data is that the Managed Object Model file (with a .mom extension which explains my &#8220;Your Mom&#8221; joke above) is created at compile-time by Xcode. This however isn&#8217;t source code, and can&#8217;t be directly stored in a static library. Additionally the default method for accessing your .mom file assumes it lives in your main bundle.</p><p>The simplest approach for working around this is to include a resource bundle along with your static library. By dragging your .xcdatamodeld directory into the &#8220;Compile Sources&#8221; section of your bundle, or set your custom bundle to be the target of your Core Data model when adding it to your project.</p><p><a
href="http://nachbaur.com/wp-content/uploads/2011/04/Screen-shot-2011-04-18-at-12.36.45-PM.png" rel="lightbox[552]"><img
class="alignnone size-full wp-image-591" title="Core Data Model added to bundle" src="http://nachbaur.com/wp-content/uploads/2011/04/Screen-shot-2011-04-18-at-12.36.45-PM.png" alt="" width="494" height="172" /></a>Once you have your bundle, you simply change your code that constructs your <em>NSManagedObjectModel</em> object to look in the new bundle instead.</p><pre class="brush: objc; title: ; notranslate">
NSString *bundlePath, *modelPath;
NSBundle *bundle;
NSURL *bundleURL;
NSManagedObjectModel *objModel;
bundlePath = [[NSBundle mainBundle]
					pathForResource:@&quot;MyLibrary&quot;
							 ofType:@&quot;bundle&quot;];
bundle = [NSBundle bundleWithPath:bundlePath];
modelPath = [bundle pathForResource:@&quot;MyModel&quot;
						     ofType:@&quot;momd&quot;];
modelURL = [NSURL fileURLWithPath:modelPath];
objModel = [[NSManagedObjectModel alloc]
			initWithContentsOfURL:modelURL];
</pre><h1>Sample Implementation</h1><p>When working on an update to <a
href="http://click.linksynergy.com/fs-bin/stat?id=W1iBxVdeYFY&amp;offerid=146261&amp;type=3&amp;subid=0&amp;tmpid=1826&amp;RD_PARM1=http%253A%252F%252Fitunes.apple.com%252Fus%252Fapp%252Fmydrum-pad%252Fid364787310%253Fmt%253D8%2526uo%253D4%2526partnerId%253D30">myDrumPad</a> I encountered many of the problems I describe above, especially since I needed to migrate my user&#8217;s databases to a new version of the object model. In addition to the updated database I also wanted to share my audio engine with another music-related app I&#8217;m designing, so my goals for this updated included:</p><ol><li>Migrate the datamodel to a new version.</li><li><del>Unit test the migration of data from the old to the new version.</del></li><li>Move the datamodel into a static library.</li><li>Minimize the amount of boilerplate code that needed to reside in the application delegate class.</li><li>Allow these classes to be reused.</li></ol><p>While I never got unit testing data migrations working, I did manage to accomplish my other problems.  In fact the Singleton class I created, DataManager, has already been reused in 4 other projects. So to get you started on the right foot, here&#8217;s an example of how you can start where Apple&#8217;s templates leave off. Simply add this singleton to an Xcode project, optionally create your own static library target and bundle, and tie all the ends together to create your own application.</p><p><script src="https://gist.github.com/922496.js"></script></p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nachbaur?a=E9Hc_ZSni2M:eOqLna3b85g:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=bcOpcFrp8Mo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=E9Hc_ZSni2M:eOqLna3b85g:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=E9Hc_ZSni2M:eOqLna3b85g:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=E9Hc_ZSni2M:eOqLna3b85g:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nachbaur?i=E9Hc_ZSni2M:eOqLna3b85g:V_sGLiPBpWU" border="0"></img></a>
</div>]]></content:encoded> <wfw:commentRss>http://nachbaur.com/blog/smarter-core-data/feed</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>Building iOS apps for Over-The-Air AdHoc distribution</title><link>http://nachbaur.com/blog/building-ios-apps-for-over-the-air-adhoc-distribution</link> <comments>http://nachbaur.com/blog/building-ios-apps-for-over-the-air-adhoc-distribution#comments</comments> <pubDate>Fri, 25 Mar 2011 02:11:12 +0000</pubDate> <dc:creator>Michael Nachbaur</dc:creator> <category><![CDATA[Continuous Integration]]></category> <category><![CDATA[continuous integration]]></category> <category><![CDATA[development]]></category> <category><![CDATA[howto]]></category> <category><![CDATA[Hudson]]></category> <category><![CDATA[HudsonCI]]></category> <category><![CDATA[iphone]]></category> <category><![CDATA[Jenkins]]></category> <category><![CDATA[JenkinsCI]]></category> <category><![CDATA[Objective-C]]></category> <category><![CDATA[testing]]></category> <guid isPermaLink="false">http://nachbaur.com/?p=522</guid> <description><![CDATA[I&#8217;ve written about building iOS applications with Hudson Jenkins, but until recently there hasn&#8217;t been a convenient way of getting those applications to your testers. Of course the most important part of your build output will be the app bundle you send to Apple&#8217;s iTunes Connect web interface, but throughout your development cycle you&#8217;ll want [...]]]></description> <content:encoded><![CDATA[<div
class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fbuilding-ios-apps-for-over-the-air-adhoc-distribution"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fbuilding-ios-apps-for-over-the-air-adhoc-distribution&amp;source=NachoMan&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6239b17e17b21092b11716b59a2de343&amp;b=2" height="61" width="50" /><br
/> </a></div><p>I&#8217;ve written about building iOS applications with <del>Hudson</del> Jenkins, but until recently there hasn&#8217;t been a convenient way of getting those applications to your testers. Of course the most important part of your build output will be the app bundle you send to Apple&#8217;s iTunes Connect web interface, but throughout your development cycle you&#8217;ll want to test your app.  Sure you could build and deploy a debug build straight to your own personal device, but you get the most benefit from having other people beta test your app.</p><p>With recent releases of Xcode and the iOS SDK, Apple improved their AdHoc distribution support with two main enhancements:</p><ol><li>Mobile provisioning files can now be embedded in the App&#8217;s IPA itself, meaning you don&#8217;t have to maintain and update separate .mobileprovision files separately;</li><li>A specially-formated manifest Plist file can be created that, when linked to properly, allows test devices to install new versions of your AdHoc app without needing to plug into a computer to sync the app using iTunes.</li></ol><p>These improvements are huge, but require some changes to your build scripts and your Continuous Integration environment.  I&#8217;d like to show you how to do this in your own installations, and show you some options for how to distribute your apps to your testers.</p><h1><span
id="more-522"></span>Building IPAs properly</h1><p>In the past, if you wanted to create an AdHoc distributable binary, you could either zip up the MyAppName.app bundle directory and mobile provisioning files separately, or you could attempt to create an IPA manually to fake-out iTunes. Getting this right was difficult however since the contents of the app directory are signed, and any changes (e.g. trying to include an embedded mobileprovision or iTunesArtwork file) would break the codesign.</p><p>With recent iOS SDK releases Apple added a &#8220;Build And Archive&#8221; menu that builds an IPA and archives it for later use. This is fairly nifty if you are a one-man shop and don&#8217;t practice Continuous Integration, but for the rest of us this just won&#8217;t cut it. However, some adventurous people dug through Xcode&#8217;s command-line build output to see just what was happening when the &#8220;Build And Archive&#8221; command was generating the IPA, and here&#8217;s what they found:</p><pre class="brush: bash; title: ; notranslate">
xcrun -sdk iphoneos PackageApplication \
    &quot;path/to/build/MyApp.app&quot; \
    -o &quot;output/path/to/MyApp.ipa&quot; \
    --sign &quot;iPhone Distribution: My Company&quot; \
    --embed &quot;path/to/something.mobileprovision&quot;
</pre><p>If you run that on the command-line, lo&#8217; and behold, you can generate properly-signed IPAs to your heart&#8217;s content. But there&#8217;s more! The interesting thing about this command is that it takes both the codesign name and certificate file as arguments while generating your IPA.  There&#8217;s a subtlety to this that many people haven&#8217;t stumbled upon.  Here it goes:</p><p
style="padding-left: 30px;"><strong>No matter what provisioning profile you use within your Xcode project file to build your apps, you can re-sign them later in your Continuous Integration environment!</strong></p><p>This is a powerful point that you can really take advantage of while setting up your build scripts. As mobile provisioning files change, you only need to ensure you perform the final IPA creation with the proper profile.</p><p>Adding a statement above to your build script is fairly straight-forward.  Here is a snippet of code I use in my own build scripts:</p><pre class="brush: bash; title: ; notranslate">
. &quot;$WORKSPACE/autobuild/build.config&quot;
for config in $CONFIGURATIONS; do
    provfile=$(eval echo \$`echo ProvisionFile$config`)
    codesign=$(eval echo \$`echo Codesign$config`)
    cert=&quot;$WORKSPACE/autobuild/$provfile&quot;
    fileprefix=&quot;$JOB_NAME-$BUILD_NUMBER-$config&quot;;
    ipaname=&quot;$fileprefix.ipa&quot;
    xcodebuild -activetarget -configuration $config build || failed build;
    app_path=$(ls -d build/$config-iphoneos/*.app)
    xcrun -sdk iphoneos PackageApplication \
        &quot;$app_path&quot; -o &quot;$OUTPUT/$ipaname&quot; \
        --sign &quot;$codesign&quot; --embed &quot;$cert&quot;
done
</pre><p>I then place some simple configuration into the &#8220;build.config&#8221; file, that looks like so:</p><pre class="brush: bash; title: ; notranslate">
CONFIGURATIONS=&quot;Release Distribution&quot;
ProvisionFileDistribution=AdHocProfile.mobileprovision
CodesignDistribution=&quot;iPhone Distribution: Decaf Ninja Software&quot;
ProvisionFileRelease=AppStoreProfile.mobileprovision
CodesignRelease=&quot;iPhone Distribution: Decaf Ninja Software&quot;
OTAURL=&quot;http://path/to/my/beta/site&quot;
OTASmallIcon=appstore/Icon-57.png
OTALargeIcon=appstore/Icon-512.png
</pre><p>This is used by the script to determine, at runtime and on a per-artifact basis, which codesign and mobile provision file should be used.  This means that if your provisioning profile changes (if you add or remove devices from an AdHoc profile, for example) you only have to check the new provisioning file into your SCM, submit to Jenkins, and wait for a new build. (Note: The settings starting with &#8220;OTA&#8221; will be used in the next section)</p><p>The great thing I discovered is that Apple&#8217;s iTunes Connect web interface accepts properly-signed IPA files as your final app submission, as long as they&#8217;re signed with your App Store mobile provisioning profile.  This means if you build an IPA for both AdHoc and App Store configurations, that&#8217;s all you need.</p><h1>Over-The-Air Distribution</h1><p>Once you have an IPA generated with an embedded mobile provision profile, you can start distributing your apps to beta testers much easier. In my experience it&#8217;s difficult to find beta testers who will diligently put your app through its paces thoroughly enough to truly test your application&#8217;s limits. It makes matters even harder when you require users to: a) download an IPA, b) maybe download a new mobile provision profile, c) drag them into iTunes (in the right order), and d) sync their phone.  You&#8217;ll be lucky at that point if they actually have the time to launch your app.</p><p>There are a few 3rd-party solutions (such as <a
href="http://www.testflightapp.com/" target="_blank">TestFlight</a> or <a
href="https://github.com/TheRealKerni/Hockey#readme" target="_blank">Hockey</a>) that handle the nitty-gritty of getting Over-The-Air installs working to manage your beta testers and to push updates out to them, but most of the features they provide can be built yourself simply enough just by adding a little bit of creativity to your Jenkins build scripts. I&#8217;m going to work backwards, since that might be easier to follow along with.</p><h2>Send email notifications to your testers</h2><div
id="attachment_533" class="wp-caption alignright" style="width: 310px"><img
class="size-medium wp-image-533" title="Sample build result email" src="http://nachbaur.com/wp-content/uploads/2011/03/Screen-shot-2011-03-24-at-6-300x196.png" alt="" width="300" height="196" /><p
class="wp-caption-text">Sample &quot;Build Success&quot; email that beta testers receive</p></div><p>The screenshot to the right shows a sample email that my beta testers and I receive when a new build is successfully compiled. I use the <a
href="http://wiki.jenkins-ci.org/display/JENKINS/Email-ext+plugin" target="_blank">Jenkins Email-ext plugin</a> to customize my build result emails, and enable HTML output so that I can include custom links in it.  Using this plugin allows you to easily send separate messages on success, failure, etc, and provides a number of variables/tags that can provide additional context to your testers. For example, I use the &#8220;$CHANGES_SINCE_LAST_SUCCESS&#8221; tag to show my testers what&#8217;s changed since the last build, using my SCM commit log messages.</p><p>Apple uses a special URL scheme to indicate that an app install should be performed.  In the email screenshot, you&#8217;ll see that I have a link titled &#8220;Install beta build #32&#8243;. This is link to the following URL:</p><p
style="padding-left: 30px;">itms-services://?action=download-manifest&amp;url=http://url/to/app-manifest.plist</p><div
id="attachment_536" class="wp-caption alignleft" style="width: 210px"><img
class="size-medium wp-image-536" title="OTA app install prompt" src="http://nachbaur.com/wp-content/uploads/2011/03/photo-200x300.png" alt="" width="200" height="300" /><p
class="wp-caption-text">Clicking an itms-services:// URL results in this prompt</p></div><p>Clicking that link from an iOS device will tell the OS to download the application update manifest and, if it&#8217;s properly formulated, will prompt the user if they want to install the app.</p><p>Assuming the manifest is valid and the user taps &#8220;Install&#8221;, it behaves exactly as if the user purchased the app from the App Store. The device switches back to the home screen, and begins downloading the application.</p><p>Note: If your user&#8217;s device UDID isn&#8217;t included in the embedded mobile provision profile, the user will get a vague error about being unable to install the application.</p><h2>Generating the update manifest</h2><p>All of this assumes you&#8217;ve generated your update manifest to begin with. The format is pretty verbose, and has a few hard requirements for the information you need to supply. But honestly these are files you should have available to begin with. They include:</p><ul><li>Your company name</li><li>The name of the application</li><li>The version number that you want to report for this app</li><li>Your 57&#215;57 app icon</li><li>Your 512&#215;512 app icon</li></ul><p>There is some other information you can optionally supply, but that is the minimum you need. All of those files need to be available on a web server the user will have access to. So if your Jenkins server is password protected, you might want to archive those files elsewhere.  For my installation I use the <a
href="http://wiki.jenkins-ci.org/display/JENKINS/SCP+plugin" target="_blank">Jenkins SCP plugin</a> to archive the relevant files to a public &#8220;Beta&#8221; section of my website and reference the files from my app manifest.</p><p>I generate my app manifest from my build scripts, which looks something like this:</p><pre class="brush: bash; title: ; notranslate">
mkdir $OUTPUT/$fileprefix
cp $WORKSPACE/$OTASmallIcon $OUTPUT/$fileprefix/Icon-57.png
cp $WORKSPACE/$OTALargeIcon $OUTPUT/$fileprefix/Icon-512.png
info_plist=$(ls *Info.plist | sed -e 's/\.plist//')
bundle_version=$(defaults read $WORKSPACE/$info_plist CFBundleShortVersionString)
bundle_id=$(defaults read $WORKSPACE/$info_plist CFBundleIdentifier)
cat &lt;&lt; EOF &gt; $OUTPUT/$otaname
&lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;
&lt;plist version=&quot;1.0&quot;&gt;
&lt;dict&gt;
   &lt;key&gt;items&lt;/key&gt;
   &lt;array&gt;
       &lt;dict&gt;
           &lt;key&gt;assets&lt;/key&gt;
           &lt;array&gt;
               &lt;dict&gt;
                   &lt;key&gt;kind&lt;/key&gt;
                   &lt;string&gt;software-package&lt;/string&gt;
                   &lt;key&gt;url&lt;/key&gt;
                   &lt;string&gt;$OTAURL/$ipaname&lt;/string&gt;
               &lt;/dict&gt;
               &lt;dict&gt;
                   &lt;key&gt;kind&lt;/key&gt;
                   &lt;string&gt;display-image&lt;/string&gt;
                   &lt;key&gt;needs-shine&lt;/key&gt;
                   &lt;true/&gt;
                   &lt;key&gt;url&lt;/key&gt;
                   &lt;string&gt;$OTAURL/output/$fileprefix/Icon-57.png&lt;/string&gt;
               &lt;/dict&gt;
               &lt;dict&gt;
                   &lt;key&gt;kind&lt;/key&gt;
                   &lt;string&gt;full-size-image&lt;/string&gt;
                   &lt;key&gt;needs-shine&lt;/key&gt;
                   &lt;true/&gt;
                   &lt;key&gt;url&lt;/key&gt;
                   &lt;string&gt;$OTAURL/output/$fileprefix/Icon-512.png&lt;/string&gt;
               &lt;/dict&gt;
           &lt;/array&gt;
           &lt;key&gt;metadata&lt;/key&gt;
           &lt;dict&gt;
               &lt;key&gt;bundle-identifier&lt;/key&gt;
               &lt;string&gt;$bundle_id&lt;/string&gt;
               &lt;key&gt;bundle-version&lt;/key&gt;
               &lt;string&gt;$bundle_version #$BUILD_NUMBER&lt;/string&gt;
               &lt;key&gt;kind&lt;/key&gt;
               &lt;string&gt;software&lt;/string&gt;
               &lt;key&gt;title&lt;/key&gt;
               &lt;string&gt;$OTATitle&lt;/string&gt;
               &lt;key&gt;subtitle&lt;/key&gt;
               &lt;string&gt;$OTASubtitle&lt;/string&gt;
           &lt;/dict&gt;
       &lt;/dict&gt;
   &lt;/array&gt;
&lt;/dict&gt;
&lt;/plist&gt;
EOF
</pre><p>The contents of the &#8220;output&#8221; directory are subsequently SCP&#8217;d to my beta server, and this manifest file is referenced in my Jenkins build success email.</p><p>The last step is to maintain an email mailing list of your beta testers and configure your Jenkins build job to notify that list when a successful build is finished. Your testers are then notified the moment any new changes are available, and with a single tap they can download and update to the latest build from anywhere. And your testers can see, based on your SCM changelog, what features may have changed and areas where they might need to focus their test efforts.</p><p>If you have any questions about this technique, please don&#8217;t hesitate to leave comments below. I use this for my personal iOS application builds, as well as at work, and we&#8217;ve had great success with it, especially since it doesn&#8217;t require the installation or configuration of any extra 3rd-party software.</p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nachbaur?a=J4Ox-c9Drzg:obb0eXrXRo4:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=bcOpcFrp8Mo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=J4Ox-c9Drzg:obb0eXrXRo4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=J4Ox-c9Drzg:obb0eXrXRo4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=J4Ox-c9Drzg:obb0eXrXRo4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nachbaur?i=J4Ox-c9Drzg:obb0eXrXRo4:V_sGLiPBpWU" border="0"></img></a>
</div>]]></content:encoded> <wfw:commentRss>http://nachbaur.com/blog/building-ios-apps-for-over-the-air-adhoc-distribution/feed</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Animating Interfaces with Core Animation: Part 4</title><link>http://nachbaur.com/blog/core-animation-part-4</link> <comments>http://nachbaur.com/blog/core-animation-part-4#comments</comments> <pubDate>Sat, 08 Jan 2011 02:09:03 +0000</pubDate> <dc:creator>Michael Nachbaur</dc:creator> <category><![CDATA[Objective-C]]></category> <category><![CDATA[animation]]></category> <category><![CDATA[apple]]></category> <category><![CDATA[Core Animation]]></category> <category><![CDATA[development]]></category> <category><![CDATA[howto]]></category> <category><![CDATA[iphone]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[tutorial]]></category> <guid isPermaLink="false">http://nachbaur.com/?p=495</guid> <description><![CDATA[This is the fourth in a series of posts I&#8217;m writing on animating iOS interfaces using Core Animation. In the first post I created a planetary orbit demo using nested CALayer objects. The second post showed how to dress up a UI by animating an image. The third post shows how you can trigger animations [...]]]></description> <content:encoded><![CDATA[<div
class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a
href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fcore-animation-part-4"><br
/> <img
src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fnachbaur.com%2Fblog%2Fcore-animation-part-4&amp;source=NachoMan&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6239b17e17b21092b11716b59a2de343&amp;b=2" height="61" width="50" /><br
/> </a></div><p><img
class="size-full wp-image-462 alignleft" title="Core Animation" src="http://nachbaur.com/wp-content/uploads/2011/01/core-animation-logo-sm-1.png" alt="" width="137" height="137" />This is the fourth in a series of posts I&#8217;m writing on animating iOS interfaces using Core Animation. In the <a
href="http://nachbaur.com/blog/core-animation-part-1">first post</a> I created a planetary orbit demo using nested CALayer objects. The <a
href="http://nachbaur.com/blog/core-animation-part-2">second post</a> showed how to dress up a UI by animating an image.  The <a
href="http://nachbaur.com/blog/core-animation-part-3">third post</a> shows how you can trigger animations in response to button actions.</p><p>This post will show how you can create the beginnings of a full game using Core Animation combined with CAShapeLayer and UIBezierPath objects.</p><p><a
href="http://nachbaur.com/blog/core-animation-part-4">Read on to see more</a></p><h2><span
id="more-495"></span></h2><h2>Race Track sample</h2><div
id="attachment_464" class="wp-caption alignright" style="width: 170px"><a
href="http://www.youtube.com/watch?v=WsSYCtl3I-s"><img
class="size-medium wp-image-464 " title="CALayerAnimTest-5" src="http://nachbaur.com/wp-content/uploads/2011/01/CALayerAnimTest-5-200x300.png" alt="" width="160" height="240" /></a><p
class="wp-caption-text">Race Track demo</p></div><p>This is perhaps my favorite sample, if only because it not only looks neat but shows how you can build an actual game using nothing but Core Animation. This sample shows how you can construct a car race track on the screen using CAShapeLayer objects, and can then animate an image of a car along that track.  This sample&#8217;s code is broken down into five main blocks:</p><ol><li>Defining the path the car should follow;</li><li>Drawing the black line that defines the track;</li><li>Drawing the white dashed center-line of the track;</li><li>Creating the layer defining the car;</li><li>Animating the car along the path.</li></ol><p>Luckily there are some handy routines for defining paths in UIKit. Core Animation deals with paths as CGPathRef objects, but luckily there is the UIBezierPath class that simplifies the process of drawing and creating a path object.</p><pre class="brush: objc; title: ; notranslate">
UIBezierPath *trackPath = [UIBezierPath bezierPath];
[trackPath moveToPoint:CGPointMake(160, 25)];
// ... Path drawing operations ...
</pre><p>I&#8217;ve omitted the actual path drawing code because it&#8217;s pretty verbose, but you can <a
href="http://nachbaur.com/wp-content/uploads/2011/01/CALayerAnimTest.zip">download the source code</a> and sift through it yourself. Once the path has been created, you can use it as many times as you like. First we create a layer defining the black shape of the track.</p><pre class="brush: objc; title: ; notranslate">
CAShapeLayer *racetrack = [CAShapeLayer layer];
racetrack.path = trackPath.CGPath;
racetrack.strokeColor = [UIColor blackColor].CGColor;
racetrack.fillColor = [UIColor clearColor].CGColor;
racetrack.lineWidth = 30.0;
[self.view.layer addSublayer:racetrack];
</pre><p>The CAShapeLayer class isn&#8217;t used often enough I find; it is extremely powerful, and reduces the amount of processing the device has to do. Core Animation is fairly low-level, so instead of assigning the UIBezierPath object directly, you use the CGPath accessor that conveniently creates the low-level struct that it can understand. We specify the colors that we want the outline (the &#8220;Stroke&#8221; of the path) and the filled area to be, also using low-level CGColor objects.</p><p>We also specify a fairly wide width of 30 points and then add this layer to our main view&#8217;s CALayer object. An important thing to note is that the stroke color fills in on either side of the path, so the coordinates our path describes has 15 points of black on either side of it.</p><pre class="brush: objc; title: ; notranslate">
CAShapeLayer *centerline = [CAShapeLayer layer];
centerline.path = trackPath.CGPath;
centerline.strokeColor = [UIColor whiteColor].CGColor;
centerline.fillColor = [UIColor clearColor].CGColor;
centerline.lineWidth = 2.0;
centerline.lineDashPattern = [NSArray arrayWithObjects:
                              [NSNumber numberWithInt:6],
                              [NSNumber numberWithInt:2],
                              nil];
[self.view.layer addSublayer:centerline];
</pre><p>For the center-line of the racetrack, we create another CAShapeLayer object, filling out its properties similarly to the previous layer. In this case however we&#8217;re using a white stroke color, we&#8217;re using a much smaller line width, and we also specify a &#8220;Line Dash Pattern&#8221;.</p><p>This pattern describes where we want the path to be stroked, and where we want it to skip drawing the outline. You specify it in groupings of two, so for every 6 points of space along the line, there will be 2 points of blank space. This gives us a very nice dashed pattern.</p><p>One thing you may want to take note of is that we&#8217;re using the same UIBezierPath object to create the second layer. You can reuse that path as many times as you like.</p><pre class="brush: objc; title: ; notranslate">
CALayer *car = [CALayer layer];
car.bounds = CGRectMake(0, 0, 44.0, 20.0);
car.position = CGPointMake(160, 25);
car.contents = (id)([UIImage imageNamed:@&quot;carmodel.png&quot;].CGImage);
[self.view.layer addSublayer:car];
</pre><p>Next we create a regular CALayer for the image of our car. Notice how we assign the image to the layer&#8217;s contents? By using the CGImage property of our UIImage, it passes the content directly to the layer in a way it can understand, greatly reducing the amount of boilerplate code we need.</p><p>We also make sure to add the layer at the exact point where the path starts, so that the car lines up with the track.</p><pre class="brush: objc; title: ; notranslate">
CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@&quot;position&quot;];
anim.path = trackPath.CGPath;
anim.rotationMode = kCAAnimationRotateAuto;
anim.repeatCount = HUGE_VALF;
anim.duration = 8.0;
[car addAnimation:anim forKey:@&quot;race&quot;];
</pre><p>Finally we create a CAKeyframeAnimation object on the &#8220;position&#8221; property. You might remember from my previous post about <a
href="http://nachbaur.com/blog/core-animation-part-3">creating button action animations</a> that a keyframe animation allows you to perform an animation along a path. In this case we&#8217;re creating a much more complicated path, but we&#8217;re using the exact same path used to create our CAShapeLayer objects above.</p><p>As shown in previous examples, we set the repeat count to infinite and a fairly long duration. But the important property is the rotationMode. By setting this to one of two potential values, the CAKeyframeAnimation object will automatically rotate the target layer along the path for you. If you&#8217;ve ever seen the game <a
href="http://click.linksynergy.com/fs-bin/click?id=W1iBxVdeYFY&amp;offerid=146261.313014213&amp;type=2&amp;subid=0">Harbor Master</a> where you direct little boats along a path to their harbor? Or <a
href="http://click.linksynergy.com/fs-bin/click?id=W1iBxVdeYFY&amp;offerid=146261.363727129&amp;type=2&amp;subid=0">Flight Control HD</a> where you direct planes to their airports. You can reproduce these same effects using simple CAKeyframeAnimation objects.</p><p>Finally, when the animation is added to the car, you see the effect shown in the video below.</p><p><object
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="385" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param
name="allowFullScreen" value="true" /><param
name="allowscriptaccess" value="always" /><param
name="src" value="http://www.youtube.com/v/WsSYCtl3I-s?fs=1&amp;hl=en_US" /><param
name="allowfullscreen" value="true" /><embed
type="application/x-shockwave-flash" width="480" height="385" src="http://www.youtube.com/v/WsSYCtl3I-s?fs=1&amp;hl=en_US" allowscriptaccess="always" allowfullscreen="true"></embed></object></p><p>I have plans to write more posts on Core Animation in the future, but for now this is all I&#8217;ve got. Feel free to download the sample project and pick through the code yourself. And don&#8217;t forget to read the previous samples showing <a
href="http://nachbaur.com/blog/core-animation-part-1">Orbiting Planets</a>, <a
href="http://nachbaur.com/blog/core-animation-part-2">Floating Clouds</a> and <a
href="http://nachbaur.com/blog/core-animation-part-3">Button Actions</a>.</p><p><a
href="http://nachbaur.com/wp-content/uploads/2011/01/CALayerAnimTest.zip">CALayerAnimTest.zip – Xcode Project</a></p> <div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/nachbaur?a=6ZzNG6w_NXc:5FBvgNseGAw:bcOpcFrp8Mo"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=bcOpcFrp8Mo" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=6ZzNG6w_NXc:5FBvgNseGAw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=6ZzNG6w_NXc:5FBvgNseGAw:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/nachbaur?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/nachbaur?a=6ZzNG6w_NXc:5FBvgNseGAw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/nachbaur?i=6ZzNG6w_NXc:5FBvgNseGAw:V_sGLiPBpWU" border="0"></img></a>
</div>]]></content:encoded> <wfw:commentRss>http://nachbaur.com/blog/core-animation-part-4/feed</wfw:commentRss> <slash:comments>2</slash:comments> </item> </channel> </rss>

