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

<channel>
	<title>Bynomial Code</title>
	<atom:link href="http://bynomial.com/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://bynomial.com/blog</link>
	<description>Tips and thoughts for iOS coders.</description>
	<lastBuildDate>Wed, 31 Aug 2011 21:11:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>iOS Jobs and Candidates</title>
		<link>http://bynomial.com/blog/?p=150</link>
		<comments>http://bynomial.com/blog/?p=150#comments</comments>
		<pubDate>Mon, 18 Jul 2011 21:28:57 +0000</pubDate>
		<dc:creator>Tyler</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bynomial.com/blog/?p=150</guid>
		<description><![CDATA[The goal of this post is to help connect some good iOS coders with contracts/jobs. I&#8217;ve been hearing a lot of interest in iOS development work from startups looking for either a consultant or a full-time employee. At the same time I do not know very many iOS developers who are available to work (including [...]]]></description>
			<content:encoded><![CDATA[<p>The goal of this post is to help connect some good iOS coders with contracts/jobs.</p>
<p>I&#8217;ve been hearing a lot of interest in iOS development work from startups looking for either a consultant or a full-time employee.  At the same time I do <em>not</em> know very many iOS developers who are available to work (including me, currently).</p>
<p>If you&#8217;re an iOS developer interested in getting a contract or job, you can contact me by leaving a comment to this post.  I will not make any of these comments public, so no one will see them but me.  I&#8217;m basically using the comment system as a messaging system here.  To be clear: <strong>no one will see your comment but me</strong> (for this post only).  Please include some evidence of your skill as an iOS coder, and your email address so I can reply.  I won&#8217;t share any of this information with anyone else unless I explicitly ask you first (and get your approval, of course!).</p>
<p>If you&#8217;re a startup looking to hire people, you can also contact me the same way.  Be aware that there is much more demand than supply right now, so I can&#8217;t promise anything.</p>
]]></content:encoded>
			<wfw:commentRss>http://bynomial.com/blog/?feed=rss2&#038;p=150</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Storing passwords in an app</title>
		<link>http://bynomial.com/blog/?p=148</link>
		<comments>http://bynomial.com/blog/?p=148#comments</comments>
		<pubDate>Fri, 15 Jul 2011 23:15:30 +0000</pubDate>
		<dc:creator>Tyler</dc:creator>
				<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://bynomial.com/blog/?p=148</guid>
		<description><![CDATA[I recently covered the topic of sending unfakeable messages from your app to a server, which requires the use of a private key &#8211; basically a password that users can&#8217;t access. In this case, and many others, you might want to include private data (such as a private key) in your app in a way [...]]]></description>
			<content:encoded><![CDATA[<p>I <a href="http://bynomial.com/blog/?p=141">recently covered</a> the topic of sending unfakeable messages from your app to a server, which requires the use of a private key &#8211; basically a password that users can&#8217;t access.  In this case, and many others, you might want to include private data (such as a private key) in your app in a way that hackers can&#8217;t find it.  The most obvious way to store a password string is as a string literal.  But this is a bad idea, since anyone who purchases your app (or obtains it by more nefarious means) has access to the binary, and extracting string literals from a binary is pretty easy.</p>
<h2>The problem</h2>
<p>I&#8217;ll mention the bad news up front, which is that there is no really good solution to this problem.  In security, it&#8217;s basically a war between hackers and researchers.  (I like to think of these guys as two sides of research, but I&#8217;m not sure if others would agree.)  When it comes to this specific problem, the hackers are winning.  Or, to be more fair to researchers, the setup of the problem is so skewed in favor of hackers that it may be essentially impossible to defend against them completely.</p>
<p>Why do the hackers win this one?</p>
<p>A hacker can get your binary, and can run your binary.  A clever hacker can disassemble, inspect, and even modify your code, although they don&#8217;t have access to the source, so it&#8217;s harder.</p>
<p>But, no matter how you implement things, your code will be sending some string to the server, and it has to compute the authentication code (the HMAC).  In order to compute the HMAC, it has to pass around a private key.  All the hacker has to do is locate the point in code when you send out the network request, and work backwards from there to find the origin of the HMAC, and from there find your private key and hash function.  Once they locate these, they can execute your hash function with your private key to sign any message they like.  They win.</p>
<p>However, going to all this work is a real pain, and requires a rare skill set for the hacker.  So there are some very practical methods you can use, which I&#8217;ll list below, which will make life harder, and probably completely deter, many would-be hackers.</p>
<h2>Good solutions we can&#8217;t use</h2>
<p>Before saying what we can do in iOS, in my research for this post I learned about two techniques to help solve this problem in other contexts.  I like these ideas because in these cases the researchers are winning, and I think each of these is a very interesting idea.</p>
<h3>Non-iOS solution 1: Trusted platform module</h3>
<p>A trusted platform module (TPM) is a small piece of hardware that can be included with a device to provide certain security functionality.  The main feature we would care about is device integrity.  Basically, a TPM keeps a hash computed from the system device setup and OS/low-level software.  If any of those are altered (such as an iPhone being jailbroken), the TPM will detect it.  So a platform can be created where no apps can run without approval from the TPM.  In this context, it becomes much more difficult for a hacker to extract anything from your code, because they can&#8217;t run it.  If someone were implementing this system, they might as well protect against users copying binaries, which would also disallow disassembly.</p>
<p>However, iOS devices do not have these protections.</p>
<h3>Non-iOS solution 2: Secure password verification</h3>
<p>This is a very cool idea.  You can write a function <code class="codecolorer objc default"><span class="objc"><span style="color: #a61390;">BOOL</span> PasswordIsCorrect<span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>password<span style="color: #002200;">&#41;</span></span></code> that will correctly return <code class="codecolorer objc default"><span class="objc"><span style="color: #a61390;">YES</span></span></code> or <code class="codecolorer objc default"><span class="objc"><span style="color: #a61390;">NO</span></span></code> depending on if the input string matches a secret password.  This much is easy.  The cool part is that you can write this function in a way that keeps the password secret, <i>even if a hacker has the source code for the function</i>.</p>
<p>How can this work?  Like this:</p>
<div class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #a61390;">BOOL</span> PasswordIsCorrect<span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>candidatePassword<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span><br />
&nbsp; <span style="color: #11740a; font-style: italic;">// These values are constants pre-computed by the programmer.</span><br />
&nbsp; <span style="color: #11740a; font-style: italic;">// If you use this, make sure your p is much larger.</span><br />
&nbsp; <span style="color: #a61390;">const</span> <span style="color: #a61390;">long</span> <span style="color: #a61390;">long</span> <span style="color: #a61390;">int</span> encryptedPasswordInt <span style="color: #002200;">=</span> <span style="color: #2400d9;">82303</span>;<br />
&nbsp; <span style="color: #a61390;">const</span> <span style="color: #a61390;">long</span> <span style="color: #a61390;">long</span> <span style="color: #a61390;">int</span> r <span style="color: #002200;">=</span> <span style="color: #2400d9;">19392</span>;<br />
&nbsp; <span style="color: #a61390;">const</span> <span style="color: #a61390;">long</span> <span style="color: #a61390;">long</span> <span style="color: #a61390;">int</span> p <span style="color: #002200;">=</span> <span style="color: #2400d9;">89237</span>;<br />
&nbsp; <span style="color: #a61390;">long</span> <span style="color: #a61390;">long</span> <span style="color: #a61390;">int</span> candidatePasswordInt <span style="color: #002200;">=</span> IntRepresentationOfString<span style="color: #002200;">&#40;</span>password<span style="color: #002200;">&#41;</span>;<br />
&nbsp; <span style="color: #a61390;">long</span> <span style="color: #a61390;">long</span> <span style="color: #a61390;">int</span> encryptedCandidatePasswordInt <span style="color: #002200;">=</span> PowerModN<span style="color: #002200;">&#40;</span>r, candidatePasswordInt, p<span style="color: #002200;">&#41;</span>;<br />
&nbsp; <span style="color: #a61390;">return</span> encryptedCandidatePasswordInt <span style="color: #002200;">==</span> encryptedPasswordInt;<br />
<span style="color: #002200;">&#125;</span></div></div>
<p>The background is to choose any large prime for p, then any value r < p, and then compute <code class="codecolorer objc default"><span class="objc">encryptedPasswordInt <span style="color: #002200;">=</span> PowerModN<span style="color: #002200;">&#40;</span>r, realPasswordInt, p<span style="color: #002200;">&#41;</span></span></code>.  To use more standard mathematical notation, we&#8217;re doing something like:</p>
<p>y = r<sup>x</sup> (mod n)  &nbsp;&nbsp;<i>(x is secret, done ahead of time)</i><br />
z = r<sup>q</sup> (mod n)  &nbsp;&nbsp;<i>(q is user-provided password)</i><br />
y == z ?</p>
<p>They will be equal iff the password was correct.  Here, x is the real password int, and q is the user-provided candidate password int.  y is called encryptedPasswordInt, and z is called encryptedCandidatePasswordInt in the code.</p>
<p>This is considered secure because the <a href="http://en.wikipedia.org/wiki/Discrete_logarithm">discrete logarithm</a> problem is considered hard.  I say &#8220;considered&#8221; because it hasn&#8217;t been proven either way.  For example, it would be great if someone could prove there did not exist a polynomial-time algorithm to solve the discrete logarithm.  Of course, it would also be great if I were a billionaire with a yacht and I could solve the Riemann hypothesis in my sleep.  Actually I don&#8217;t really care about yachts that much.  That&#8217;s more of a &#8220;nice-to-have&#8221; one.</p>
<p>So, that technique works and has a bunch of research behind it.  For example, check out <a href="http://www.wisdom.weizmann.ac.il/~naor/COURSE/TOPICS/scribe_notes_lec2.pdf">these lecture notes</a> or just search for &#8220;<a href="http://www.google.com/search?q=obfuscating+point+functions">obfuscating point functions</a>.&#8221;</p>
<p>Now for some methods you can actually use.  Sorry it took me so long; I thought these detours were very interesting.</p>
<h2>Method 1: Encrypt your private string</h2>
<p>The first thing you should do is encrypt your private key string.  At this point some readers will be thinking &#8220;Oh hey I know this great routine I can write called <a href="http://en.wikipedia.org/wiki/Rot13">rot13</a>.  I love rot13.&#8221;</p>
<p>Do not use rot13.</p>
<p>Every time you use rot13, a kitten explodes.  Rot13 is not an encryption method.  It is a way to tell other programmers that you are a security newbie.  It&#8217;s ok to be a newbie, unless of course you&#8217;re in charge of security at my bank.</p>
<p>In general, most encryption techniques that are easy to think of have been broken.  If you want to be safe, use a community-accepted technique like <a href="http://stackoverflow.com/questions/1400246/aes-encryption-for-an-nsstring-on-the-iphone">AES</a>.  iOS comes with some powerful, though poorly-documented, security libraries that you can take advantage of here.</p>
<h2>Method 2: Obfuscate your strings, independent of encryption</h2>
<p>Now, you have your encrypted password, and you need to decrypt it at runtime.  So you also have a decryption key.  How have we really improved the situation?  A hacker can still figure things out from just your string literals.  Well, now he has to guess which two strings are the keys, and which decryption technique to apply, which is already much more work.</p>
<p>You can make things even harder by:</p>
<ul>
<li>Using English phrases as the decryption key for your private key.  This way, if a hacker sees a list of extracted string literals, it&#8217;s harder for them to guess which one is your decryption key.
<li>Store a series of short, separate string literals in your code, and combine them in a random order to get your decryption key.  This makes it even harder to guess your decryption key from a list of string literals.
</ul>
<h2>Method 3: Obfuscate security symbol names</h2>
<p>Next up, hackers can often extract symbols from your binary.  Things like class names may be available to them.  If you have a class named <code class="codecolorer objc default"><span class="objc">PrivateKeyHelper</span></code>, you&#8217;re advertising to them where to look in your code.  You can keep your code readable but place misleading symbols in your code by clever use of #define&#8217;s in your header files.  For example, near the top of PrivateKeyHelper.h, do this:</p>
<div class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #6e371a;">#define PrivateKeyHelper ComponentNode</span></div></div>
<p>Your code will look the same, but the linker will never see the symbol PrivateKeyHelper, only ComponentNode (or any other boring non-security symbol you choose).  Do this for all function/method and class names that reek of security.</p>
<h2>Method 4: Write your own key decryption function</h2>
<p>The above method works whenever you have all the source, but fails when you&#8217;re using a library you didn&#8217;t build, including any third-party security library.  There are a few very common decryption functions you are likely to use.  A clever and determined hacker could look for calls from your code to these common functions.  To fight against this, you could write your own decryption function.  Again, don&#8217;t use rot13 (remember the kittens?), but something more serious.</p>
<h2>Method 5: Use function pointers to make security calls</h2>
<p>If hackers can follow a deterministic control flow through your code, they can still find your decryption function by working carefully backwards from your network request.  But you can fight even this.  If you don&#8217;t call your functions directly, but rather use a function pointer, then it will be harder for a hacker looking at disassembled code to follow the control flow.  If you do this, try to fool the compiler into thinking that multiple values may be used for the function pointer, so it doesn&#8217;t optimize away the obscurity.</p>
<h2>Method 0: Don&#8217;t worry</h2>
<p>Lastly, and most importantly, <i>all</i> of this post could very easily fall into the category of &#8220;premature optimization.&#8221;  Unless you have a lot of users or a lot of user money already invested in your app, I think this stuff should be a low priority.  Why?  Because the majority of apps only have a small number of users, and it&#8217;s unlikely that anyone is going to put in serious effort toward hacking your app.  Of course, your priorities are up to you, but I thought I would mention this in lieu of Knuth&#8217;s warning about the root of all evil.</p>
<p><i>(Thanks to Susan Hohenberger Waters for some help with this topic!)</i></p>
]]></content:encoded>
			<wfw:commentRss>http://bynomial.com/blog/?feed=rss2&#038;p=148</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The best talk at WWDC 11</title>
		<link>http://bynomial.com/blog/?p=147</link>
		<comments>http://bynomial.com/blog/?p=147#comments</comments>
		<pubDate>Thu, 30 Jun 2011 09:09:27 +0000</pubDate>
		<dc:creator>Tyler</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bynomial.com/blog/?p=147</guid>
		<description><![CDATA[I was happy to see that Apple had recently posted all the session videos from WWDC online, available for free to Apple developers. It&#8217;s great that they do this, because a lot of us *cough* aren&#8217;t able to attend for one reason or another, but we still want to know what&#8217;s going on. One talk [...]]]></description>
			<content:encoded><![CDATA[<p>I was happy to see that Apple had recently posted all the session videos from WWDC online, available for free to Apple developers.  It&#8217;s great that they do this, because a lot of us *cough* aren&#8217;t able to attend for one reason or another, but we still want to know what&#8217;s going on.</p>
<p>One talk in particular stood out, and there&#8217;s no question in my mind that this is single best talk at this year&#8217;s WWDC.  It&#8217;s called <strong>Writing Easy-to-change Code</strong>: Your Second Most Important Goal as a Developer by Ken Kocienda.  If you have an Apple ID to login, then you can watch the video from <a href="https://developer.apple.com/videos/wwdc/2011/">this page</a>.  To get this out of the way, the most important goal is to ship products, and that&#8217;s not what the talk is about.  The talk is a motley collection of simple, great ideas that outline a powerful philosophy of programming.</p>
<h2>Why this Talk is Good</h2>
<p>The thing about this talk is, if a younger version of me watched it, I wouldn&#8217;t have been that impressed.  Why?  Because everything Ken says is common sense.  You hear the idea, and you say to yourself, &#8220;well yea DUH of course.&#8221;</p>
<p>So I want to defend why this talk is actually very good.  Because there are a <i>ton</i> of programming ideas that <i>sound</i> good, and seem to make sense &#8211; but in the end, only a few of them stand the test of time.  I can now say I&#8217;m becoming an older programmer, having been at it for over 25 years now.  I&#8217;ve been doing this a long time, and I&#8217;ve had some time to very seriously test out a number of philosophies.</p>
<p>And the points that Ken makes are both time-tested truths, and at the core of what is good about good code.</p>
<p>The title of the talk is &#8220;easy-to-change code.&#8221;  And if you think about it, this one simple moniker really captures the main idea behind so much of the evolution of programming.  We want code to be readable, maintainable, debuggable, feature-addable.  If code is easy-to-change, all of these other properties need to be there as well (e.g. if your code isn&#8217;t readable, I would not call it easy-to-change).  Moving from non-object coding to object-oriented thinking; using an actor model for parallel processing; adopting standards for interfaces on many levels; test-driven development: <i>all</i> of these ideas are essentially designed to help us make code easier to work with / easier to change.  So this is an example of one simple idea being at the center of a lot of useful ideas, and, although you might not see it directly in the talk, a lot of the ideas presented are at the core of a set of other, related ideas that naturally would follow if you sat down to ponder all the consequences.</p>
<p>If I write any more, this post will be longer than Ken&#8217;s talk.  I have to add the qualification that I disagree with maybe 5% of what he says, but I&#8217;m probably wrong about that 5% <img src='http://bynomial.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />   Go check it out!</p>
]]></content:encoded>
			<wfw:commentRss>http://bynomial.com/blog/?feed=rss2&#038;p=147</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Pulse Eng Blog: New Speed Analysis Tool</title>
		<link>http://bynomial.com/blog/?p=145</link>
		<comments>http://bynomial.com/blog/?p=145#comments</comments>
		<pubDate>Mon, 27 Jun 2011 23:27:16 +0000</pubDate>
		<dc:creator>Tyler</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bynomial.com/blog/?p=145</guid>
		<description><![CDATA[I just added a new tool to the moriarty library for app speed analysis. I wrote this tool while working at Pulse, so the post is on the Pulse Eng blog. Check it out. Some background: A few months ago I had the opportunity to contribute to the Pulse news reader app. This is a [...]]]></description>
			<content:encoded><![CDATA[<p>I just added a new tool to <a href="https://github.com/tylerneylon/moriarty">the moriarty library</a> for app speed analysis.  I wrote this tool while working at Pulse, so the post is on the <a href="http://eng.pulse.me/line-by-line-speed-analysis-for-ios-apps/">Pulse Eng blog</a>.  Check it out.</p>
<p>Some background: A few months ago I had the opportunity to contribute to the Pulse news reader app.  This is a great app for reading news, blogs, facebook updates, and twitter in one place.  Among other honors, the Pulse team just received an Apple design award at WWDC 2011 &#8212; these guys know what they&#8217;re doing.  The particular tool being released allows you to easily get line-by-line, nanosecond-resolution timing data for your code.  As usual, it&#8217;s an open source tool under the Apache 2 license.  <a href="http://eng.pulse.me/line-by-line-speed-analysis-for-ios-apps/">Here&#8217;s the post</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://bynomial.com/blog/?feed=rss2&#038;p=145</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Working with ssh</title>
		<link>http://bynomial.com/blog/?p=142</link>
		<comments>http://bynomial.com/blog/?p=142#comments</comments>
		<pubDate>Thu, 16 Jun 2011 21:59:51 +0000</pubDate>
		<dc:creator>Tyler</dc:creator>
				<category><![CDATA[code management]]></category>

		<guid isPermaLink="false">http://bynomial.com/blog/?p=142</guid>
		<description><![CDATA[This post contains a few quick and useful facts about using ssh from OS X&#8217;s terminal. ssh is an extraordinarily useful shell tool for logging in to, and getting a shell on a remote machine. You generally use it like this: $ ssh username@remoteserver.com At which point, you&#8217;re prompted for a password. Which brings me [...]]]></description>
			<content:encoded><![CDATA[<p>This post contains a few quick and useful facts about using ssh from OS X&#8217;s terminal.</p>
<p>ssh is an extraordinarily useful shell tool for logging in to, and getting a shell on a remote machine.  You generally use it like this:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ <span style="color: #c20cb9; font-weight: bold;">ssh</span> username<span style="color: #000000; font-weight: bold;">@</span>remoteserver.com</div></div>
<p>At which point, you&#8217;re prompted for a password.  Which brings me to my first useful tip.</p>
<h2>Skipping password entry</h2>
<p>It turns out that you don&#8217;t have to type your password every time you use ssh if you&#8217;re always talking to the same remote host.  You can do this securely by setting up a public/private key pair on your machine, and then giving your public key to the remote machine.  After setting this up, the remote machine can confirm that ssh-using party knows your private key, without you having to type anything.</p>
<p>There are two big steps to accomplish this: (1) make sure you have a public/private key pair, which may already be done for you; and then (2) let the remote machine know about your public key.</p>
<h3>Make sure you have keys</h3>
<p>You might already have a public/private key pair, in which case you can skip this step.  Check to see if you already have them:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ <span style="color: #7a0874; font-weight: bold;">cd</span> ~<span style="color: #000000; font-weight: bold;">/</span>.ssh<br />
<span style="color: #666666; font-style: italic;"># If it says &quot;no such file or directory&quot;, then you need to generate a key pair; otherwise:</span><br />
$ <span style="color: #c20cb9; font-weight: bold;">ls</span><br />
<span style="color: #666666; font-style: italic;"># If you see files named &quot;id_rsa&quot; and &quot;id_rsa.pub&quot;, you're all good.</span></div></div>
<p>If you need to generate a key pair, execute this command:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ <span style="color: #c20cb9; font-weight: bold;">ssh-keygen</span> <span style="color: #660033;">-t</span> rsa <span style="color: #660033;">-C</span> <span style="color: #ff0000;">&quot;your_email@youremail.com&quot;</span></div></div>
<p>You might need to hit enter once or twice to get that command to complete &#8211; no passphrase is fine, the default settings are fine.  Associating your email address with a key is optional, but can be useful to you or others for knowing which user is associated with this public key.</p>
<h3>Letting the remote know your public key</h3>
<p>If your remote account is set up correctly, executing this one-liner from your local .ssh directory will finish everything up for you:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ <span style="color: #c20cb9; font-weight: bold;">scp</span> id_rsa.pub <span style="color: #000000; font-weight: bold;">&lt;</span>user<span style="color: #000000; font-weight: bold;">&gt;@&lt;</span>yourhost<span style="color: #000000; font-weight: bold;">&gt;</span>:.ssh<span style="color: #000000; font-weight: bold;">/</span>authorized_keys</div></div>
<p>If you don&#8217;t see any error message after that, it succeeded!  Good work.  Buy yourself a fancy drink.  And one for me, while you&#8217;re at it, I&#8217;m thirsty here.</p>
<p>If it doesn&#8217;t work, ssh in to the remote machine, and make sure the .ssh directory exists.  If not, create it, and try to send the file again (same scp line as before).  If you&#8217;ve created the directory, and have permission to write to it, that should work.  Anytime you ssh into that machine from now on, it won&#8217;t ask you for your password.  Nice!</p>
<p><i>(<b>Edit</b>: Commenter @Adam helpfully pointed out that there&#8217;s a more official way to do this, using the <code class="codecolorer bash default"><span class="bash">ssh-copy-id</span></code> command (<a href="http://linux.die.net/man/1/ssh-copy-id">ref</a>).  Unfortunately, this command is not installed by default, but can be obtained by installing <a href="http://mxcl.github.com/homebrew/">homebrew</a> and typing <code class="codecolorer bash default"><span class="bash">brew <span style="color: #c20cb9; font-weight: bold;">install</span> ssh-copy-id</span></code>.  The scp command I give above is sort of a brutish, simplified version of that.  Thanks for the tip!)</i></p>
<h2>Dealing with a broken connection</h2>
<p>For some strange reason, if you&#8217;re using ssh and the connection is broken, it basically seems as if your terminal is frozen.  It just doesn&#8217;t respond to commands.  But there is a way out.  Just hit the enter, tilde, and period keys, in that order (tilde = shift+back-quote of course).</p>
<p>Why does that work?  You can read more about this in the <code class="codecolorer bash default"><span class="bash"><span style="color: #c20cb9; font-weight: bold;">man</span> <span style="color: #c20cb9; font-weight: bold;">ssh</span></span></code> pages, under escape characters.  Or, within ssh, hit enter, tilde, question-mark, to see a quick summary of what other meta-commands are available.</p>
<p>There&#8217;s also a way to address this problem more preemptively.  You can edit ssh&#8217;s config file, setting the ServerAliveInterval to 10, or any positive number (I recommend something close to 10, though).  This value indicates the number of seconds without hearing anything from the server before an encrypted ping is sent to check that the connection is still alive.  The default value is 0, which means no such pings are ever sent.  Here&#8217;s the details of how to set this up:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ <span style="color: #7a0874; font-weight: bold;">cd</span> ~<span style="color: #000000; font-weight: bold;">/</span>.ssh<br />
$ <span style="color: #c20cb9; font-weight: bold;">vim</span> config<br />
<span style="color: #666666; font-style: italic;"># Hit the i key to enter insert mode, and type the following line:</span><br />
ServerAliveInterval <span style="color: #000000;">10</span><br />
<span style="color: #666666; font-style: italic;"># Hit escape, then type:</span><br />
:wq<br />
<span style="color: #666666; font-style: italic;"># and hit enter, which saves the file and exits vim.</span></div></div>
<p>To read more about ssh config options, type <code class="codecolorer bash default"><span class="bash"><span style="color: #c20cb9; font-weight: bold;">man</span> ssh_config</span></code> from your bash prompt.</p>
<h2>Syncing with server code</h2>
<p>The last thing I want to mention is a bash script I use for keeping my local machine&#8217;s git repository synchronized with my server code.  If you have a lot of server code, it might make sense to use a dedicated git repository for that code.  I&#8217;m talking about a different situation &#8211; I have a lot of iOS code, and there&#8217;s about 200 lines of php code I need to run a very simple server.  In this case, I&#8217;d rather have a single git repo on my machine, and keep a copy of the php files on my server.  I use sftp to keep the files synchronized.  The above scp command that eliminates the need for passwords in ssh also works for sftp, so it becomes easier to use sftp from a bash script.</p>
<p>Here&#8217;s a copy of a script that pulls in all php files from a given remote directory, into the current directory:</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">#!/bin/bash</span><br />
sftp <span style="color: #000000; font-weight: bold;">&lt;</span>user<span style="color: #000000; font-weight: bold;">&gt;@&lt;</span>yourhost<span style="color: #000000; font-weight: bold;">&gt;</span>:<span style="color: #000000; font-weight: bold;">&lt;</span>subdir<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #cc0000; font-style: italic;">&lt;&lt;EOF<br />
get *.php<br />
bye<br />
EOF</span></div></div>
<p>I hope that&#8217;s helpful!</p>
]]></content:encoded>
			<wfw:commentRss>http://bynomial.com/blog/?feed=rss2&#038;p=142</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How to send messages safely to your server</title>
		<link>http://bynomial.com/blog/?p=141</link>
		<comments>http://bynomial.com/blog/?p=141#comments</comments>
		<pubDate>Fri, 20 May 2011 08:05:14 +0000</pubDate>
		<dc:creator>Tyler</dc:creator>
				<category><![CDATA[moriarty]]></category>
		<category><![CDATA[networking]]></category>

		<guid isPermaLink="false">http://bynomial.com/blog/?p=141</guid>
		<description><![CDATA[This post describes a general method of sending messages to a server in a way that prevents hackers from acting like your app. Specifically, I&#8217;ll tell you exactly how to add HMAC authentication to your app&#8217;s network messages. If you don&#8217;t care about the why and just want to get your hands on some working [...]]]></description>
			<content:encoded><![CDATA[<p>This post describes a general method of sending messages to a server in a way that prevents hackers from acting like your app.  Specifically, I&#8217;ll tell you exactly how to add HMAC authentication to your app&#8217;s network messages.</p>
<p>If you don&#8217;t care about the <em>why</em> and just want to get your hands on some working code, skip ahead to The Code section below.</p>
<h2>The Problem</h2>
<p>I&#8217;m building an iPad game, and my app will be sending high scores to a server.  If I built a simple REST interface for adding new high scores, it could be easy for a dedicated player to make up a fake high score.  For example, let&#8217;s suppose I send an HTTP GET request to this url to tell the server to add a new high score:</p>
<pre>http://myserver.com/newHighScore?name=Gilgamesh&#038;score=100</pre>
<p>Users can perform packet sniffing on network traffic using tools like Wireshark.  Suppose our player, Gilgamesh, really <em>really</em> wants to have the all-time high score.  If he sees this protocol, he could just open his favorite browser and type in a url like this:</p>
<pre>http://myserver.com/newHighScore?name=Gilgamesh&#038;score=3240923409</pre>
<p>At this point, there&#8217;s not much my server can do.  I can look at the user agent string, but that is also easy to fake.  I could add a sort of password as an extra parameter:</p>
<pre>http://myserver.com/newHighScore?name=Gilgamesh&#038;score=100&#038;password=supersecret</pre>
<p>but this is still easy to crack with packet sniffing.</p>
<p>So how do you prevent malicious users from sending fake messages as if they were your app?</p>
<h2>The Solution</h2>
<p>I&#8217;m glad you asked!  Because, luckily, there is a whole subfield of cryptography dedicated to this question.  If you&#8217;re curious about diving into this general subject, I suggest you start with the wikipedia page on <a href="http://en.wikipedia.org/wiki/Message_authentication_code">message authentication codes</a>.  If you just want to get your iPhone app working securely, read on:</p>
<p>The technique this code uses is called <a href="http://en.wikipedia.org/wiki/HMAC">HMAC</a>, which stands for hash-based message authentication code.</p>
<p>This is how it works: I have a message, which is a string.  I&#8217;m not going to encrypt it, but I want to send it in an unfakeable way.  To do this, I&#8217;ll compute a hash of the message, along with a private key (another string), and send that along with the message.  If you&#8217;re thinking of hash tables, then, yes, this is sort-of halfway similar, but not exactly.  I am using a <em>hash function</em> which takes a possibly-complex object and gives me a simpler object as output.  For hash tables, we want the output to be &#8220;randomly distributed&#8221; in a certain sense.  For use as an HMAC, we want a hash function to be irreversible.  The point is that, if someone knows the <em>output</em> of your hash function, it&#8217;s very hard for them to compute the <em>input</em>.</p>
<p>And there are a bunch of hash functions designed with that goal in mind.  Some of them are called MD5 (&#8220;message digest 5&#8243;), SHA1 (&#8220;secure hash algorithm&#8221;), and SHA2, which is actually a set of hash functions.  Check out wikipedia&#8217;s <a href="http://en.wikipedia.org/wiki/MD5#Pseudocode">MD5 pseudocode</a> to get an idea of how hard it might be to reverse the output of one of these guys.  (<a href="http://partow.net/programming/hashfunctions/index.html">This page</a> is also fun.)</p>
<p>One thing I want to point out is that malicious users <em>can</em> fake a message identical to one you&#8217;re already sent.  If your API is idempotent (i.e., sending the same request twice has no additional effect), then this is fine.  Otherwise, you will want to add some new piece to the message, making it harder to fake.  For example, the client could receive an additional string from the server, called a nonce, and have to include that in the hash input.  If your nonces are always different, a malicious use could no longer fake the same message.</p>
<h2>The Code</h2>
<p>I&#8217;ve added a small NSString category to <a href="https://github.com/tylerneylon/moriarty">the moriarty library</a> to provide HMAC strings.  This is how you can use it:</p>
<div class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #6e371a;">#import &quot;NSString+HMAC.h&quot;</span><br />
<br />
<span style="color: #11740a; font-style: italic;">// Within a method in your view controller:</span><br />
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>msg <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self createMessage<span style="color: #002200;">&#93;</span>;<br />
<span style="color: #11740a; font-style: italic;">// This is where your private key goes. &nbsp;Don't just copy this one!! &nbsp;That would not be secure.</span><br />
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>key <span style="color: #002200;">=</span> <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;a9bk342nziAFD234&quot;</span>;<br />
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>hmac <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>msg hmacWithKey<span style="color: #002200;">:</span>key<span style="color: #002200;">&#93;</span>;<br />
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>urlStr <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> stringWithFormat<span style="color: #002200;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;http://%@/%@?msg=%@&amp;hmac=%@&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; domain, path, msg, hmac<span style="color: #002200;">&#93;</span>;<br />
<a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span>reply <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self pingUrl<span style="color: #002200;">:</span>urlStr<span style="color: #002200;">&#93;</span>;</div></div>
<p>If you need to send complex data, I suggest using JSON along with <a href="http://stig.github.com/json-framework/">Stig Brautaset&#8217;s JSON framework library</a>.  You can have an NSDictionary or NSArray of strings, numbers, and other arrays/dictionaries, and easily encode this as an NSString by calling <code class="codecolorer objc default"><span class="objc"><span style="color: #002200;">&#91;</span>myObj JSONRepresentation<span style="color: #002200;">&#93;</span>;</span></code>.</p>
<p>What does the server do with this?  If you&#8217;re using php, here&#8217;s how to verify the authentication:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">function</span> hmacMatchesMessage<span style="color: #009900;">&#40;</span><span style="color: #000088;">$client_hash</span><span style="color: #339933;">,</span> <span style="color: #000088;">$msg</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #000088;">$key</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'a9bk342nziAFD234'</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// Should match client's key.</span><br />
&nbsp; <span style="color: #000088;">$server_hash</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/hash_hmac"><span style="color: #990000;">hash_hmac</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sha256'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$msg</span><span style="color: #339933;">,</span> <span style="color: #000088;">$key</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #b1b100;">return</span> <a href="http://www.php.net/strcmp"><span style="color: #990000;">strcmp</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$client_hash</span><span style="color: #339933;">,</span> <span style="color: #000088;">$server_hash</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>hmacMatchesMessage<span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'hmac'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'msg'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <a href="http://www.php.net/exit"><span style="color: #990000;">exit</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #666666; font-style: italic;">// Instead of exit(), you could print an error if you're feeling friendly.</span><br />
<span style="color: #000088;">$msgObject</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/json_decode"><span style="color: #990000;">json_decode</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'msg'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">// If you sent a JSON string.</span></div></div>
<p>You can get NSString+HMAC.{h,m} by <a href="https://github.com/tylerneylon/moriarty/archives/master">downloading moriarty</a>; free to use, Apache 2 license.</p>
<p>Or, you can just copy the code from here.  As you can see in the m file, this is basically a convenience wrapper around a library that is included by default in iOS (but is difficult to learn how to use).</p>
<p>May your messages be safely authenticated!</p>
<div class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #11740a; font-style: italic;">//</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;NSString+HMAC.h</span><br />
<span style="color: #11740a; font-style: italic;">//</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;Created by Tyler Neylon on 5/19/11.</span><br />
<span style="color: #11740a; font-style: italic;">//</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;Methods for sending authenticated messages; uses SHA256.</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;See here for an overview of the purpose of these methods:</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;http://en.wikipedia.org/wiki/HMAC</span><br />
<span style="color: #11740a; font-style: italic;">//</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;Sample usage:</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp; &nbsp;NSString *msg = [self createMessage];</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp; &nbsp;NSString *key = @&quot;a9bk342nziAFD234&quot;; &nbsp;// Private key.</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp; &nbsp;NSString *hmac = [msg hmacWithKey:key];</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp; &nbsp;NSString *urlStr = [NSString stringWithFormat:</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;@&quot;http://%@/%@?msg=%@&amp;hmac=%@&quot;,</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;domain, path, msg, hmac];</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;Now send a request to urlStr; if the server knows</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;the private key, it can recompute the HMAC string, and if they</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;match, have confidence that the message originated from someone</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;else who knows the private key as well.</span><br />
<span style="color: #11740a; font-style: italic;">//</span><br />
<br />
<span style="color: #6e371a;">#import &lt;Foundation/Foundation.h&gt;</span><br />
<br />
<span style="color: #a61390;">@interface</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/"><span style="color: #400080;">NSData</span></a> <span style="color: #002200;">&#40;</span>Hexit<span style="color: #002200;">&#41;</span><br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>hexString;<br />
<br />
<span style="color: #a61390;">@end</span><br />
<br />
<span style="color: #a61390;">@interface</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">&#40;</span>HMAC<span style="color: #002200;">&#41;</span><br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>hexString;<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>hmacWithKey<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>key;<br />
<br />
<span style="color: #a61390;">@end</span></div></div>
<div class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #11740a; font-style: italic;">//</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;NSString+HMAC.m</span><br />
<span style="color: #11740a; font-style: italic;">//</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;Created by Tyler Neylon on 5/19/11.</span><br />
<span style="color: #11740a; font-style: italic;">//</span><br />
<br />
<span style="color: #6e371a;">#import &quot;NSString+HMAC.h&quot;</span><br />
<br />
<span style="color: #6e371a;">#import &lt;CommonCrypto/CommonHMAC.h&gt;</span><br />
<br />
<span style="color: #a61390;">@implementation</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/"><span style="color: #400080;">NSData</span></a> <span style="color: #002200;">&#40;</span>Hexit<span style="color: #002200;">&#41;</span><br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>hexString <span style="color: #002200;">&#123;</span><br />
&nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSMutableString_Class/"><span style="color: #400080;">NSMutableString</span></a> <span style="color: #002200;">*</span>str <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSMutableString_Class/"><span style="color: #400080;">NSMutableString</span></a> stringWithCapacity<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>self length<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;<br />
&nbsp; <span style="color: #a61390;">const</span> <span style="color: #a61390;">unsigned</span> <span style="color: #a61390;">char</span> <span style="color: #002200;">*</span>byte <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self bytes<span style="color: #002200;">&#93;</span>;<br />
&nbsp; <span style="color: #a61390;">const</span> <span style="color: #a61390;">unsigned</span> <span style="color: #a61390;">char</span> <span style="color: #002200;">*</span>endByte <span style="color: #002200;">=</span> byte <span style="color: #002200;">+</span> <span style="color: #002200;">&#91;</span>self length<span style="color: #002200;">&#93;</span>;<br />
&nbsp; <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span>; byte <span style="color: #002200;">!=</span> endByte; <span style="color: #002200;">++</span>byte<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#91;</span>str appendFormat<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;%02x&quot;</span>, <span style="color: #002200;">*</span>byte<span style="color: #002200;">&#93;</span>;<br />
&nbsp; <span style="color: #a61390;">return</span> str;<br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #a61390;">@end</span><br />
<br />
<span style="color: #a61390;">@implementation</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">&#40;</span>HMAC<span style="color: #002200;">&#41;</span><br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>hexString <span style="color: #002200;">&#123;</span><br />
&nbsp; <span style="color: #a61390;">const</span> <span style="color: #a61390;">char</span> <span style="color: #002200;">*</span>cStr <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self UTF8String<span style="color: #002200;">&#93;</span>;<br />
&nbsp; <span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/"><span style="color: #400080;">NSData</span></a> dataWithBytes<span style="color: #002200;">:</span>cStr length<span style="color: #002200;">:</span><a href="http://www.opengroup.org/onlinepubs/009695399/functions/strlen.html"><span style="color: #a61390;">strlen</span></a><span style="color: #002200;">&#40;</span>cStr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span> hexString<span style="color: #002200;">&#93;</span>;<br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>hmacWithKey<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>key <span style="color: #002200;">&#123;</span><br />
&nbsp; <span style="color: #a61390;">const</span> <span style="color: #a61390;">char</span> <span style="color: #002200;">*</span>cKey &nbsp;<span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>key cStringUsingEncoding<span style="color: #002200;">:</span>NSASCIIStringEncoding<span style="color: #002200;">&#93;</span>;<br />
&nbsp; <span style="color: #a61390;">const</span> <span style="color: #a61390;">char</span> <span style="color: #002200;">*</span>cData <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self cStringUsingEncoding<span style="color: #002200;">:</span>NSASCIIStringEncoding<span style="color: #002200;">&#93;</span>;<br />
&nbsp; <span style="color: #a61390;">unsigned</span> <span style="color: #a61390;">char</span> cHMAC<span style="color: #002200;">&#91;</span>CC_SHA256_DIGEST_LENGTH<span style="color: #002200;">&#93;</span>;<br />
&nbsp; CCHmac<span style="color: #002200;">&#40;</span>kCCHmacAlgSHA256, cKey, <a href="http://www.opengroup.org/onlinepubs/009695399/functions/strlen.html"><span style="color: #a61390;">strlen</span></a><span style="color: #002200;">&#40;</span>cKey<span style="color: #002200;">&#41;</span>, cData, <a href="http://www.opengroup.org/onlinepubs/009695399/functions/strlen.html"><span style="color: #a61390;">strlen</span></a><span style="color: #002200;">&#40;</span>cData<span style="color: #002200;">&#41;</span>, cHMAC<span style="color: #002200;">&#41;</span>;<br />
&nbsp; <span style="color: #a61390;">return</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/"><span style="color: #400080;">NSData</span></a> dataWithBytes<span style="color: #002200;">:</span>cHMAC length<span style="color: #002200;">:</span><a href="http://www.opengroup.org/onlinepubs/009695399/functions/sizeof.html"><span style="color: #a61390;">sizeof</span></a><span style="color: #002200;">&#40;</span>cHMAC<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span> hexString<span style="color: #002200;">&#93;</span>;<br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #a61390;">@end</span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://bynomial.com/blog/?feed=rss2&#038;p=141</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Keeping ViewController files small</title>
		<link>http://bynomial.com/blog/?p=139</link>
		<comments>http://bynomial.com/blog/?p=139#comments</comments>
		<pubDate>Tue, 10 May 2011 01:01:44 +0000</pubDate>
		<dc:creator>Tyler</dc:creator>
				<category><![CDATA[Categories and helper classes]]></category>
		<category><![CDATA[Class design]]></category>
		<category><![CDATA[clean coding]]></category>
		<category><![CDATA[General coding]]></category>
		<category><![CDATA[Patterns guides and best practices]]></category>

		<guid isPermaLink="false">http://bynomial.com/blog/?p=139</guid>
		<description><![CDATA[If you&#8217;re working on a complex iOS app, it&#8217;s very easy to create a UIViewController subclass with a huge amount of code. One of the many code guidelines I learned at Google was the simple idea of keeping functions and files small. For example, I would recommend trying to keep the vast majority of your [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re working on a complex iOS app, it&#8217;s very easy to create a UIViewController subclass with a huge amount of code.  One of the many code guidelines I learned at Google was the simple idea of keeping functions and files small.  For example, I would recommend trying to keep the vast majority of your functions around 40 lines or less, and trying to keep all of your files under 1000 lines.  This post presents a technique that can help you achieve smaller file size.</p>
<h2>Why small source files are good</h2>
<p>Here are two principles to code by:</p>
<ol>
<li>Your code should be simple to users, and</li>
<li>Everyone, including you, is a user.</li>
</ol>
<p>I could write a whole post about these ideas, but let me just summarize by saying that anyone working on your codebase, including future you, cares a lot about how simple things are.  When each individual idea in your codebase is succinct and transparent, things are easy to modify and update, and bugs are harder to create and easier to squash.</p>
<p>File size is not a perfect predictor for code simplicity, but it&#8217;s a darn good heuristic.</p>
<h2>Use categories on your own classes</h2>
<p>Instead of having one header and one implementation (h,m) file for your UIViewController subclass, I suggest splitting the main pieces of functionality out into their own files, as categories of your class.</p>
<p>For example, suppose we&#8217;re writing a tetris clone for the iPad.  (Don&#8217;t actually do that, btw.  You might get sued.)  Let&#8217;s have a primary view controller called TetrisViewController.  It would be easy for this file to become huge, so we can split different aspects of gameplay into separate pieces, such as this:</p>
<ul>
<li>TetrisViewController.{h,m}</li>
<li>TetrisViewController+Tutorial.{h,m} </li>
<li>TetrisViewController+Animations.{h,m} </li>
<li>TetrisViewController+Network.{h,m} </li>
</ul>
<p>Since the class is officially declared in TetrisViewController.h, this is where all the instance variables are declared.  Any code specific to tutorials, animations, or network play goes in its respective category file.  The goal is to partially encapsulate that functionality in its own file, while logically speaking, those methods will have full access to all the variables of the class.  A good rule of thumb is to group methods together when you are likely to be editing them together; you want to minimize the need for file-switching while programming.</p>
<h2>Template code</h2>
<p>Let me fill in the details of how these files might actually look.</p>
<div class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #11740a; font-style: italic;">// TetrisViewController+Animations.h</span><br />
<br />
<span style="color: #6e371a;">#import &quot;TetrisViewController.h&quot;</span><br />
<br />
<span style="color: #a61390;">@interface</span> TetrisViewController <span style="color: #002200;">&#40;</span>Animations<span style="color: #002200;">&#41;</span><br />
<br />
<span style="color: #11740a; font-style: italic;">// Public method names start with the category name.</span><br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>animationsOnCompletionOfRows<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/"><span style="color: #400080;">NSArray</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>rows;<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>animationsOnLevelDone;<br />
<br />
<span style="color: #a61390;">@end</span></div></div>
<div class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #11740a; font-style: italic;">// TetrisViewController+Animations.m</span><br />
<br />
<span style="color: #6e371a;">#import &quot;TetrisViewController+Animations.h&quot;</span><br />
<br />
<span style="color: #11740a; font-style: italic;">// Declare any private methods.</span><br />
<span style="color: #a61390;">@interface</span> TetrisViewController <span style="color: #002200;">&#40;</span>AnimationsPrivate<span style="color: #002200;">&#41;</span><br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>animationsForSingleRow<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span>rowIndex;<br />
<br />
<span style="color: #a61390;">@end</span><br />
<br />
<span style="color: #a61390;">@implementation</span> TetrisViewController <span style="color: #002200;">&#40;</span>Animations<span style="color: #002200;">&#41;</span><br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>animationsOnCompletionOfRows<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/"><span style="color: #400080;">NSArray</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>rows <span style="color: #002200;">&#123;</span><br />
&nbsp; <span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span>rowNumber <span style="color: #a61390;">in</span> rows<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #002200;">&#91;</span>self animationsForSingleRow<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>rowNumber intValue<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;<br />
&nbsp; <span style="color: #002200;">&#125;</span><br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>animationsOnLevelDone <span style="color: #002200;">&#123;</span><br />
&nbsp; <span style="color: #11740a; font-style: italic;">// Execute level done animation.</span><br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #6e371a;">#pragma mark private methods</span><br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>animationsForSingleRow<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span>rowIndex <span style="color: #002200;">&#123;</span><br />
&nbsp; <span style="color: #11740a; font-style: italic;">// Execute single-row animation.</span><br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #a61390;">@end</span></div></div>
<p>Within the category implementation, you&#8217;re free to call any public method on the original view controller, and any methods (including category-private ones) within the category.  Note that you can&#8217;t call private methods of the original class from the category, at least not without a compiler warning.  In practice, I&#8217;ve found that this is not a problem.  If the categories are separate enough ideas, the methods you need to call from a category will most often naturally be public methods.  In some cases where this was not true, I found it made sense to make a previously-private method public to solve this.  The small number of times when I did this have all made sense in retrospect, in the sense that the newly-public methods did not break encapsulation.</p>
<p>The header file of the original class doesn&#8217;t need to know anything about the category files.  The implementation file needs to import them so you can call them.  I find it useful to think of these as sort of hooks into the original class.  Ideally, you only add about one line of code to the original class per public category method.  In other words, you want your code impact on your main m file to be very small when you add a category like this.</p>
<p>Here&#8217;s an example of how your main implementation might look:</p>
<div class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #11740a; font-style: italic;">// TetrisViewController.m</span><br />
<br />
<span style="color: #11740a; font-style: italic;">// Import the main header first, to be sensitive to any uncaught dependencies in the header.</span><br />
<span style="color: #6e371a;">#import &quot;TetrisViewController.h&quot;</span><br />
<br />
<span style="color: #11740a; font-style: italic;">// Import the category headers next, again trying to catch any header dependencies.</span><br />
<span style="color: #6e371a;">#import &quot;TetrisViewController+Animations.h&quot;</span><br />
<span style="color: #6e371a;">#import &quot;TetrisViewController+Network.h&quot;</span><br />
<span style="color: #6e371a;">#import &quot;TetrisViewController+Tutorial.h&quot;</span><br />
<br />
<span style="color: #11740a; font-style: italic;">// Import other headers, declare private methods, etc.</span><br />
<br />
<span style="color: #11740a; font-style: italic;">// Then methods, which might include something like this:</span><br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>someRowsCompleted <span style="color: #002200;">&#123;</span><br />
&nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/"><span style="color: #400080;">NSArray</span></a> <span style="color: #002200;">*</span>rowsDone <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self getRowsDone<span style="color: #002200;">&#93;</span>;<br />
&nbsp; <span style="color: #002200;">&#91;</span>self incrementScoreBasedOnRows<span style="color: #002200;">:</span>rowsDone<span style="color: #002200;">&#93;</span>;<br />
&nbsp; <span style="color: #002200;">&#91;</span>self animationsOnCompletionOfRows<span style="color: #002200;">:</span>rowsDone<span style="color: #002200;">&#93;</span>;<br />
<span style="color: #002200;">&#125;</span></div></div>
<p>One last thing: it&#8217;s definitely more work to retroactively pull out categories from a huge view controller, so I highly recommend trying to split out categories as you code, as opposed to after you&#8217;ve got huge files.  I hope that&#8217;s helpful!</p>
]]></content:encoded>
			<wfw:commentRss>http://bynomial.com/blog/?feed=rss2&#038;p=139</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Fast low-level arrays</title>
		<link>http://bynomial.com/blog/?p=137</link>
		<comments>http://bynomial.com/blog/?p=137#comments</comments>
		<pubDate>Sun, 24 Apr 2011 08:06:21 +0000</pubDate>
		<dc:creator>Tyler</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bynomial.com/blog/?p=137</guid>
		<description><![CDATA[Some apps need fast processing involving variable-length arrays. NSMutableArray is pretty efficient and easy-to-use, but it requires a lot of Objective-C overhead. In this post, I introduce CArray, a low-level, superfast framework for variable-length arrays. CArray is useful when: You&#8217;re working with C data types &#8212; pointers or primitive types or structs thereof; speed is [...]]]></description>
			<content:encoded><![CDATA[<p>Some apps need fast processing involving variable-length arrays.  NSMutableArray is pretty efficient and easy-to-use, but it requires a lot of Objective-C overhead.  In this post, I introduce CArray, a low-level, superfast framework for variable-length arrays.</p>
<p>CArray is useful when:</p>
<ol>
<li> You&#8217;re working with C data types &mdash; pointers or primitive types or structs thereof;
<li> speed is a problem; and
<li> you don&#8217;t want to use cocos2d or a similar library.
</ol>
<p>CArray can play nicely with NSObject pointers, but it isn&#8217;t designed to hold strong pointers (i.e. it won&#8217;t call retain on them for you).</p>
<h2>Speed</h2>
<p>Suppose you&#8217;re willing to work with C, C++, or Objective-C, all of which play nicely with iOS. Which of the following function calls is fastest?</p>
<div class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">cPlusPlusArray.addElement<span style="color: #002200;">&#40;</span>newElt<span style="color: #002200;">&#41;</span>; &nbsp;<span style="color: #11740a; font-style: italic;">// C++ method call</span><br />
<span style="color: #002200;">&#91;</span>objCArray addElement<span style="color: #002200;">:</span>newElt<span style="color: #002200;">&#93;</span>; &nbsp; &nbsp; &nbsp;<span style="color: #11740a; font-style: italic;">// Obj-C method call</span><br />
CArrayAddElement<span style="color: #002200;">&#40;</span>cArray, newElt<span style="color: #002200;">&#41;</span>; &nbsp; <span style="color: #11740a; font-style: italic;">// C function call</span></div></div>
<p>The C call is basically always faster than the other two.  I could write a whole blog post (easily) about the speed of these three.  It gets complicated, but the simple version is that the C++ and Obj-C calls are often comparable in speed (<a href="http://www.mikeash.com/pyblog/performance-comparisons-of-common-operations-leopard-edition.html">reference</a>), and the C call could be anywhere from 20% faster to twice as fast (<a href="http://hbfs.wordpress.com/2008/12/30/the-true-cost-of-calls/">reference, see the comments</a>).</p>
<p>Sometimes you may be working with mostly-dumb (i.e. needing very little encapsulation) pieces of data, such as floats or CGPoints (which are structs, not NSObjects).  If you use NSArrays, you need to wrap these types in NSNumbers or NSValues.  Just the wrapping and unwrapping takes time, in addition to the method call overhead vs straight C function calls.  In this situation, CArray is faster by eliminating the overhead.</p>
<h2>The root of all evil</h2>
<p>Now is a great time to mention one of my favorite Donald Knuth quotes:</p>
<blockquote><p>Premature optimization is the root of all evil.</p></blockquote>
<p>I&#8217;ve seen a lot of code, and in at least 99.99% of it, the work it takes to replace object-oriented calls by straight C calls would have destroyed readability and maintainability without touching noticeable app speed.  Almost all the time, it&#8217;s just not worth it.  Every once in a while, when Friday the 13th falls on an equinox during a leap year, it&#8217;s worth it.  <em>That&#8217;s</em> when you consider something like CArray.</p>
<p>You&#8217;ve been warned.</p>
<h2>How to use CArray</h2>
<div class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #a61390;">int</span> capacity <span style="color: #002200;">=</span> <span style="color: #2400d9;">16</span>;<br />
CArray <span style="color: #002200;">*</span>intArray <span style="color: #002200;">=</span> CArrayNew<span style="color: #002200;">&#40;</span>capacity, <a href="http://www.opengroup.org/onlinepubs/009695399/functions/sizeof.html"><span style="color: #a61390;">sizeof</span></a><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;<br />
<span style="color: #a61390;">int</span> aPrime <span style="color: #002200;">=</span> <span style="color: #2400d9;">2</span>;<br />
<span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> i <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>; i &lt; <span style="color: #2400d9;">10</span>; <span style="color: #002200;">++</span>i<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span><br />
&nbsp; CArrayAddElement<span style="color: #002200;">&#40;</span>intArray, <span style="color: #002200;">&amp;</span>aPrime<span style="color: #002200;">&#41;</span>;<br />
&nbsp; aPrime <span style="color: #002200;">=</span> NextPrimeAfter<span style="color: #002200;">&#40;</span>aPrime<span style="color: #002200;">&#41;</span>;<br />
<span style="color: #002200;">&#125;</span><br />
CArrayFor<span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> <span style="color: #002200;">*</span>, intPtr, intArray<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span><br />
&nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #a61390;">printf</span></a><span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">&quot;%d<span style="color: #2400d9;">\n</span>&quot;</span>, <span style="color: #002200;">*</span>intPtr<span style="color: #002200;">&#41;</span>;<br />
<span style="color: #002200;">&#125;</span><br />
CArrayDelete<span style="color: #002200;">&#40;</span>intArray<span style="color: #002200;">&#41;</span>; &nbsp;<span style="color: #11740a; font-style: italic;">// new &lt;-&gt; delete pair as bookends</span></div></div>
<p>CArray can also work nicely with pointers.  For example, we can give an array a releaser function that it calls on elements as they are removed.</p>
<div class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #a61390;">void</span> IntRelease<span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span> <span style="color: #002200;">*</span>vp<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span><br />
&nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/free.html"><span style="color: #a61390;">free</span></a><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>vp<span style="color: #002200;">&#41;</span>;<br />
<span style="color: #002200;">&#125;</span><br />
<br />
CArray <span style="color: #002200;">*</span>ptrArray <span style="color: #002200;">=</span> CArrayNew<span style="color: #002200;">&#40;</span>capacity, <a href="http://www.opengroup.org/onlinepubs/009695399/functions/sizeof.html"><span style="color: #a61390;">sizeof</span></a><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;<br />
ptrArray<span style="color: #002200;">-</span>&gt;releaser <span style="color: #002200;">=</span> <span style="color: #002200;">&amp;</span>IntRelease;<br />
<span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> i <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>; i &lt; <span style="color: #2400d9;">100</span>; <span style="color: #002200;">++</span>i<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span><br />
&nbsp; <span style="color: #a61390;">int</span> <span style="color: #002200;">*</span>iPtr <span style="color: #002200;">=</span> <a href="http://www.opengroup.org/onlinepubs/009695399/functions/malloc.html"><span style="color: #a61390;">malloc</span></a><span style="color: #002200;">&#40;</span><a href="http://www.opengroup.org/onlinepubs/009695399/functions/sizeof.html"><span style="color: #a61390;">sizeof</span></a><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; <span style="color: #002200;">*</span>iPtr <span style="color: #002200;">=</span> <a href="http://www.opengroup.org/onlinepubs/009695399/functions/rand.html"><span style="color: #a61390;">rand</span></a><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span>;<br />
&nbsp; <span style="color: #11740a; font-style: italic;">// Array grows in capacity as needed.</span><br />
&nbsp; CArrayAddElement<span style="color: #002200;">&#40;</span>ptrArray, <span style="color: #002200;">&amp;</span>iPtr<span style="color: #002200;">&#41;</span>;<br />
<span style="color: #002200;">&#125;</span><br />
<span style="color: #11740a; font-style: italic;">// Params are for custom sorting; default is memcmp order.</span><br />
CArraySort<span style="color: #002200;">&#40;</span>ptrArray, <span style="color: #a61390;">NULL</span>, <span style="color: #a61390;">NULL</span><span style="color: #002200;">&#41;</span>;<br />
<span style="color: #a61390;">int</span> <span style="color: #002200;">**</span>iPtrInArray <span style="color: #002200;">=</span> CArrayFind<span style="color: #002200;">&#40;</span>ptrArray, anotherIntPtr<span style="color: #002200;">&#41;</span>;<br />
<span style="color: #11740a; font-style: italic;">// Either iPtrInArray == NULL (not found), or *iPtrInArray == anotherIntPtr (found).</span><br />
CArrayRemoveDuplicates<span style="color: #002200;">&#40;</span>ptrArray, <span style="color: #a61390;">NULL</span>, <span style="color: #a61390;">NULL</span><span style="color: #002200;">&#41;</span>;<br />
<span style="color: #11740a; font-style: italic;">// Get the 10th int.</span><br />
<span style="color: #a61390;">int</span> i <span style="color: #002200;">=</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">int</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>CArrayElement<span style="color: #002200;">&#40;</span>ptrArray, <span style="color: #2400d9;">10</span><span style="color: #002200;">&#41;</span>;<br />
<span style="color: #11740a; font-style: italic;">// Remove the 5th element; calls free on it from our releaser.</span><br />
CArrayRemoveElement<span style="color: #002200;">&#40;</span>ptrArray, CArrayElement<span style="color: #002200;">&#40;</span>ptrArray, <span style="color: #2400d9;">5</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;<br />
<span style="color: #11740a; font-style: italic;">// Done with array; deallocate it; calls free on each element for us.</span><br />
<span style="color: #11740a; font-style: italic;">// The calls to free are opt-in; we set this up by setting ptrArray-&gt;releaser above.</span><br />
CArrayDelete<span style="color: #002200;">&#40;</span>ptrArray<span style="color: #002200;">&#41;</span>;</div></div>
<p>Even though CArray is so low-level, it&#8217;s fairly powerful.  It&#8217;s also easy to memory manage if you follow the conventions that every CArrayNew is paired with a corresponding CArrayDelete; or CArrayInit paired with CArrayRelease if you want to handle the memory allocation yourself.</p>
<h2>Getting CArray</h2>
<p>CArray is now part of the moriarty library.  Open source, Apache 2 license; free for use in personal or commercial products, including for redistribution (see <a href="http://www.apache.org/licenses/LICENSE-2.0.html">the actual license</a> for details).</p>
<p>To get the code just click on &#8220;Downloads&#8221; from <a href="https://github.com/tylerneylon/moriarty">moriarty&#8217;s github page</a>.  Unzip the downloaded file, and copy over CArray.{h,m} into your Xcode project.</p>
<h2>PS</h2>
<p>Long after writing this code, I learned that cocos2d already has something extremely similar.  I basically rewrote ccArray from cocos2d.  (Honestly, I&#8217;m sure things just like this have existed since the beginning of C.  It&#8217;s a ridiculously common use case.)  Now, there is some contention about the speed of ccArray in cocos2d.  For example, <a href="http://www.learn-cocos2d.com/2010/09/array-performance-comparison-carray-ccarray-nsarray-nsmutablearray/">this post</a> argues that it&#8217;s unfair to count the NSNumber wrapping time against NSMutableArray.  Well, technically that&#8217;s true.  But if you have some time-critical code dealing with arrays of floats, the CArray approach is going to be much faster than the NSMutableArray approach overall (<a href="http://memo.tv/nsarray_vs_c_array_performance_comparison">reference</a>).  So, in the end, I think the wrapping &#038; unwrapping time <em>is</em> important, although maybe some people won&#8217;t want to think of that as part of NSMutableArray&#8217;s performance.</p>
<p>There&#8217;s also questions of NSMutableArray&#8217;s cleverness.  I don&#8217;t know the implementation details, but based on others&#8217; performance measurements, NSMutableArray does intelligent things under the hood.  I don&#8217;t know what it does.  For some operations, like inserting a new first element to the array repeatedly, NSMutableArray is much faster than CArray.  But, if you&#8217;re in a position where you need something faster than NSMutableArray, then you need to understand the time complexity of each CArray operation so you can use it optimally &mdash; meaning, avoid slow thing like inserting elements at the beginning.</p>
<p>I added this last bit just to basically cover my butt and say &#8220;hey guys, I know about cocos2d&#8217;s array stuff.  Yep, it&#8217;s similar.&#8221;  Also CArray has fast custom sorting, duplicate-elimination, and binary search (which I don&#8217;t think ccArray has right now).  Holla.</p>
]]></content:encoded>
			<wfw:commentRss>http://bynomial.com/blog/?feed=rss2&#038;p=137</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Repeating an animation at changing speeds</title>
		<link>http://bynomial.com/blog/?p=134</link>
		<comments>http://bynomial.com/blog/?p=134#comments</comments>
		<pubDate>Wed, 13 Apr 2011 07:23:32 +0000</pubDate>
		<dc:creator>Tyler</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bynomial.com/blog/?p=134</guid>
		<description><![CDATA[I recently came across the following problem: I wanted to handle a repeated animation that would continuously change its speed over time. In particular, I&#8217;m building a game with a flashing square, and I want it to flash more quickly if the player is getting closer to dying. Conceptually, this is very easy, and it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>I recently came across the following problem: I wanted to handle a repeated animation that would continuously change its speed over time.  In particular, I&#8217;m building a game with a flashing square, and I want it to flash more quickly if the player is getting closer to dying.  Conceptually, this is very easy, and it&#8217;s tempting to use the <code class="codecolorer objc default"><span class="objc">speed</span></code> property of CALayer or CAAnimation to help &#8212; but don&#8217;t use that!  It&#8217;s not that easy.</p>
<h2>The problem</h2>
<p>The problem is that <code class="codecolorer objc default"><span class="objc">speed</span></code> is meant to be manipulated outside of animations &#8211; you set it up <em>before</em> you start the animation, not during.  If you try to change the speed of a CAAnimation while it&#8217;s happening, your app will barf (in the debug logs).  If you change the speed of your CALayer, your app won&#8217;t barf, but your animation will jump.  I think what&#8217;s happening is analogous to the reason the functions sin(x) and sin(2x) will be different-speed versions of each other, yet if you suddenly switch from one to the other, you can easily get a discontinuity (aka a jump):</p>
<p><img class="alignnone size-full wp-image-135" title="Screen shot 2011-04-12 at 11.45.17 PM" src="http://bynomial.com/blog/wp-content/uploads/2011/04/Screen-shot-2011-04-12-at-11.45.17-PM.png" alt="" width="698" height="227" /></p>
<h2>A solution</h2>
<p>I spent a while thinking about ways to address this.  I was very tempted to figure out how far into the animation the view was, then mess with other CAMediaTiming properties to place the speed-changed animation at the right offset to continue seamlessly (basically match up the phase shifts of sin(x) and sin(2x) to eliminate the jump).  I think this approach can be done.  But!!  Fearless readers, do not tread down that path.  Bitter, bitter experience has taught me many a time, the priceless adage:</p>
<blockquote><p>Simple code is better.</p></blockquote>
<p>Messing with phase shifts is never simple.  So, I opted instead to forego Core Animation&#8217;s repeatCount mechanism, and simply restart the animation after each cycle.  This way, if I want to alter the speed, I can very easily do it between cycles.  Technically, the speed won&#8217;t change the instant you want it to, but if the cycles are short, the user won&#8217;t notice the difference.</p>
<p>And, to follow another of my favorite adages (tongue in cheek here):</p>
<blockquote><p>Why write 10 lines of code, when you can write 30 in a more reusable fashion, and a blog post too?</p></blockquote>
<p>So of course I made a reusable class to handle this situation for anyone facing the same challenge.</p>
<p>It&#8217;s called <code class="codecolorer objc default"><span class="objc">DynamicRepeatAnimation</span></code>; you use it like this:</p>
<div class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setupDefaultState <span style="color: #002200;">&#123;</span><br />
&nbsp; <span style="color: #11740a; font-style: italic;">// Set up the original view state (A).</span><br />
&nbsp; label.center <span style="color: #002200;">=</span> CGPointMake<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">160</span>, <span style="color: #2400d9;">420</span><span style="color: #002200;">&#41;</span>;<br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setupAlternateState <span style="color: #002200;">&#123;</span><br />
&nbsp; <span style="color: #11740a; font-style: italic;">// Set up the other view state (B).</span><br />
&nbsp; label.center <span style="color: #002200;">=</span> CGPointMake<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">160</span>, <span style="color: #2400d9;">100</span><span style="color: #002200;">&#41;</span>;<br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>startAnimating <span style="color: #002200;">&#123;</span><br />
&nbsp; self.animation <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>DynamicRepeatAnimation animationWithDelegate<span style="color: #002200;">:</span>self<span style="color: #002200;">&#93;</span>;<br />
&nbsp; animation.oneCycleDuration <span style="color: #002200;">=</span> <span style="color: #2400d9;">2.0</span>; &nbsp;<span style="color: #11740a; font-style: italic;">// in seconds</span><br />
&nbsp; <span style="color: #002200;">&#91;</span>animation start<span style="color: #002200;">&#93;</span>; &nbsp;<span style="color: #11740a; font-style: italic;">// Starts repeating A &lt;-&gt; B</span><br />
&nbsp; <span style="color: #11740a; font-style: italic;">// ... later ...</span><br />
&nbsp; animation.oneCycleDuration <span style="color: #002200;">=</span> <span style="color: #2400d9;">0.5</span>; &nbsp;<span style="color: #11740a; font-style: italic;">// smooth transition ensues!</span><br />
<span style="color: #002200;">&#125;</span></div></div>
<h2>The code</h2>
<p>This code is more specific than a lot of what&#8217;s in the moriarty library, so I decided to just leave this class attached to this post, and not cross-listed anywhere else.  Open source, Apache 2 license.  Here&#8217;s the source:</p>
<li> <a href="http://bynomial.com/blogfiles/DynamicRepeatAnimation.h">DynamicRepeatAnimation.h</a></li>
<li> <a href="http://bynomial.com/blogfiles/DynamicRepeatAnimation.m">DynamicRepeatAnimation.m</a></li>
<li> <a href="http://bynomial.com/blogfiles/DynamicRepeatAnimation.zip">Dynamic Repeat Animation sample Xcode project</a></li>
<p>And, for the curious, a code listing:</p>
<div class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #11740a; font-style: italic;">//</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;DynamicRepeatAnimation.h</span><br />
<span style="color: #11740a; font-style: italic;">//</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;Created by Tyler Neylon on 4/12/11.</span><br />
<span style="color: #11740a; font-style: italic;">//</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;A class to manage a repeated animation that</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;may change speed over time.</span><br />
<span style="color: #11740a; font-style: italic;">//</span><br />
<br />
<span style="color: #6e371a;">#import</span><br />
<br />
<span style="color: #a61390;">@protocol</span> DynamicRepeatDelegate<br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setupDefaultState;<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>setupAlternateState;<br />
<br />
<span style="color: #a61390;">@end</span><br />
<br />
<span style="color: #a61390;">@interface</span> DynamicRepeatAnimation <span style="color: #002200;">:</span> <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/"><span style="color: #400080;">NSObject</span></a> <span style="color: #002200;">&#123;</span><br />
&nbsp;<span style="color: #a61390;">@private</span><br />
&nbsp; <span style="color: #11740a; font-style: italic;">// weak</span><br />
&nbsp; <span style="color: #a61390;">id</span> delegate;<br />
<br />
&nbsp; <span style="color: #a61390;">BOOL</span> isAnimating;<br />
&nbsp; NSTimeInterval oneCycleDuration;<br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic<span style="color: #002200;">&#41;</span> NSTimeInterval oneCycleDuration;<br />
<br />
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span>DynamicRepeatAnimation <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>animationWithDelegate<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>delegate;<br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>start;<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>stop;<br />
<br />
<span style="color: #a61390;">@end</span></div></div>
<div class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #11740a; font-style: italic;">//</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;DynamicRepeatAnimation.m</span><br />
<span style="color: #11740a; font-style: italic;">//</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;Created by Tyler Neylon on 4/12/11.</span><br />
<span style="color: #11740a; font-style: italic;">//</span><br />
<br />
<span style="color: #6e371a;">#import &quot;DynamicRepeatAnimation.h&quot;</span><br />
<br />
<span style="color: #a61390;">@interface</span> DynamicRepeatAnimation <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#41;</span><br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>startOneCycle;<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>animationDidStop<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>animationID finished<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>finished context<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>context;<br />
<br />
<span style="color: #a61390;">@end</span><br />
<br />
<span style="color: #a61390;">@implementation</span> DynamicRepeatAnimation<br />
<br />
<span style="color: #a61390;">@synthesize</span> oneCycleDuration;<br />
<br />
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span>DynamicRepeatAnimation <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>animationWithDelegate<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">id</span><span style="color: #002200;">&#41;</span>delegate <span style="color: #002200;">&#123;</span><br />
&nbsp; DynamicRepeatAnimation <span style="color: #002200;">*</span>animation <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>DynamicRepeatAnimation new<span style="color: #002200;">&#93;</span> autorelease<span style="color: #002200;">&#93;</span>;<br />
&nbsp; animation<span style="color: #002200;">-&amp;</span>gt;delegate <span style="color: #002200;">=</span> delegate;<br />
&nbsp; animation<span style="color: #002200;">-&amp;</span>gt;oneCycleDuration <span style="color: #002200;">=</span> <span style="color: #2400d9;">1.0</span>;<br />
&nbsp; <span style="color: #a61390;">return</span> animation;<br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>start <span style="color: #002200;">&#123;</span><br />
&nbsp; <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span>isAnimating<span style="color: #002200;">&#41;</span> <span style="color: #a61390;">return</span>;<br />
&nbsp; isAnimating <span style="color: #002200;">=</span> <span style="color: #a61390;">YES</span>;<br />
&nbsp; <span style="color: #002200;">&#91;</span>self startOneCycle<span style="color: #002200;">&#93;</span>;<br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>stop <span style="color: #002200;">&#123;</span><br />
&nbsp; isAnimating <span style="color: #002200;">=</span> <span style="color: #a61390;">NO</span>;<br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #6e371a;">#pragma mark private methods</span><br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>startOneCycle <span style="color: #002200;">&#123;</span><br />
&nbsp; <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span>isAnimating || oneCycleDuration <span style="color: #002200;">==</span> <span style="color: #2400d9;">0.0</span><span style="color: #002200;">&#41;</span> <span style="color: #a61390;">return</span>;<br />
<br />
&nbsp; <span style="color: #002200;">&#91;</span>delegate setupDefaultState<span style="color: #002200;">&#93;</span>;<br />
&nbsp; <span style="color: #002200;">&#91;</span>UIView beginAnimations<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;dynamicRepeatAnimation&quot;</span> context<span style="color: #002200;">:</span><span style="color: #a61390;">NULL</span><span style="color: #002200;">&#93;</span>;<br />
&nbsp; <span style="color: #002200;">&#91;</span>UIView setAnimationRepeatAutoreverses<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;<br />
&nbsp; <span style="color: #002200;">&#91;</span>UIView setAnimationDuration<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>oneCycleDuration <span style="color: #002200;">/</span> <span style="color: #2400d9;">2.0</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;<br />
&nbsp; <span style="color: #002200;">&#91;</span>UIView setAnimationDelegate<span style="color: #002200;">:</span>self<span style="color: #002200;">&#93;</span>;<br />
&nbsp; <span style="color: #002200;">&#91;</span>UIView setAnimationDidStopSelector<span style="color: #002200;">:</span><span style="color: #a61390;">@selector</span><span style="color: #002200;">&#40;</span>animationDidStop<span style="color: #002200;">:</span>finished<span style="color: #002200;">:</span>context<span style="color: #002200;">:</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#93;</span>;<br />
&nbsp; <span style="color: #002200;">&#91;</span>delegate setupAlternateState<span style="color: #002200;">&#93;</span>;<br />
&nbsp; <span style="color: #002200;">&#91;</span>UIView commitAnimations<span style="color: #002200;">&#93;</span>;<br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>animationDidStop<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>animationID finished<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNumber_Class/"><span style="color: #400080;">NSNumber</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>finished context<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>context <span style="color: #002200;">&#123;</span><br />
&nbsp; <span style="color: #002200;">&#91;</span>self startOneCycle<span style="color: #002200;">&#93;</span>;<br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #a61390;">@end</span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://bynomial.com/blog/?feed=rss2&#038;p=134</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>LineView</title>
		<link>http://bynomial.com/blog/?p=133</link>
		<comments>http://bynomial.com/blog/?p=133#comments</comments>
		<pubDate>Tue, 05 Apr 2011 23:01:50 +0000</pubDate>
		<dc:creator>Tyler</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://bynomial.com/blog/?p=133</guid>
		<description><![CDATA[It&#8217;s surprisingly tricky just to draw a single line in iOS. Quartz has great 2D graphic support, but you need to dive down into that world and use many lines of code to draw one line. In some cases, you really just want a few well-placed lines to augment an elegant UI &#8211; this class [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s surprisingly tricky just to draw a single line in iOS.  Quartz has great 2D graphic support, but you need to dive down into that world and use many lines of code to draw one line.  In some cases, you really just want a few well-placed lines to augment an elegant UI &#8211; this class is designed to address that problem.  You can add a line to your view with two lines of code.  You can also get a transparent UIImage with just the line, which can be used in conjunction with UIImageView, image-processing functions, or image-related classed like WipeView to do more complex things with your lines.</p>
<p>This is a very easy-to-create class once you know Quartz, so there&#8217;s not much to explain.  I just thought it would be useful, so I added it to <a href="https://github.com/tylerneylon/moriarty">moriarty</a> (free to use, open source under Apache 2 license).  I think the header file explains it pretty well:</p>
<div class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #11740a; font-style: italic;">//</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;LineView.h</span><br />
<span style="color: #11740a; font-style: italic;">//</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;Created by Tyler Neylon on 4/5/11.</span><br />
<span style="color: #11740a; font-style: italic;">//</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;View to draw a single line.</span><br />
<span style="color: #11740a; font-style: italic;">//</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp;Sample usage:</span><br />
<span style="color: #11740a; font-style: italic;">//</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp; &nbsp;CGPoint a = CGPointMake(10, 10);</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp; &nbsp;CGPoint b = CGPointMake(50, 100);</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp; &nbsp;LineView *lineView = [LineView lineFromPoint:a toPoint:b];</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp; &nbsp;lineView.color = [UIColor blueColor];</span><br />
<span style="color: #11740a; font-style: italic;">// &nbsp; &nbsp;[self.view addSubview:lineView];</span><br />
<span style="color: #11740a; font-style: italic;">//</span><br />
<br />
<span style="color: #6e371a;">#import &lt;Foundation/Foundation.h&gt;</span><br />
<br />
<br />
<span style="color: #a61390;">@interface</span> LineView <span style="color: #002200;">:</span> UIView <span style="color: #002200;">&#123;</span><br />
&nbsp;<span style="color: #a61390;">@private</span><br />
&nbsp; <span style="color: #11740a; font-style: italic;">// strong</span><br />
&nbsp; UIColor <span style="color: #002200;">*</span>color;<br />
&nbsp; <br />
&nbsp; CGFloat lineWidth;<br />
&nbsp; CGPoint a;<br />
&nbsp; CGPoint b;<br />
<span style="color: #002200;">&#125;</span><br />
<br />
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic, retain<span style="color: #002200;">&#41;</span> UIColor <span style="color: #002200;">*</span>color;<br />
<span style="color: #a61390;">@property</span> <span style="color: #002200;">&#40;</span>nonatomic<span style="color: #002200;">&#41;</span> CGFloat lineWidth;<br />
<br />
<span style="color: #002200;">+</span> <span style="color: #002200;">&#40;</span>LineView <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>lineFromPoint<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGPoint<span style="color: #002200;">&#41;</span>a toPoint<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>CGPoint<span style="color: #002200;">&#41;</span>b;<br />
<br />
<span style="color: #11740a; font-style: italic;">// The image will be transparent except for the line, and</span><br />
<span style="color: #11740a; font-style: italic;">// have padding around the line. &nbsp;It will be sized so that,</span><br />
<span style="color: #11740a; font-style: italic;">// when placed with frameOrigin = (0,0), the line will have</span><br />
<span style="color: #11740a; font-style: italic;">// the coordinates given in the constructor.</span><br />
<span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>UIImage <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>getImage;<br />
<br />
<span style="color: #a61390;">@end</span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://bynomial.com/blog/?feed=rss2&#038;p=133</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

