<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><description /><title>amro's blog</title><generator>Tumblr (3.0; @amro)</generator><link>http://amro.co/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/amdev" /><feedburner:info uri="amdev" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://tumblr.superfeedr.com/" /><item><title>Using GCD to Wait on Many Tasks</title><description>&lt;p&gt;I recently needed a way to perform an unknown number of asynchronous http requests and wait until they were all done before proceeding. dispatch_groups are a neat feature of Grand Central Dispatch (GCD) that made this easy to do.&lt;/p&gt;
&lt;p&gt;There are a couple of ways to use dispatch_groups but the basic idea is the same: create a dispatch_group, give it some tasks, and wait for it to finish those tasks.&lt;/p&gt;
&lt;p&gt;First, let’s create a group:&lt;/p&gt;
&lt;pre&gt;dispatch_group_t group = dispatch_group_create();&lt;/pre&gt;
&lt;p&gt;There are two ways to add tasks to our dispatch_group. You can either call dispatch_group_async with the group, a dispatch_queue and block to run or manually call dispatch_group_enter.&lt;/p&gt;
&lt;p&gt;Calling dispatch_group_async looks something like this:&lt;/p&gt;
&lt;pre&gt;dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // Do stuff on a global background queue here
});&lt;/pre&gt;
&lt;p&gt;Or you can manage tasks manually by calling dispatch_group_enter and dispatch_group_leave in pairs:&lt;/p&gt;
&lt;pre&gt;dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // Do stuff on a global background queue here
    dispatch_group_leave(group);
});&lt;/pre&gt;
&lt;p&gt;Using dispatch_group_enter/dispatch_group_leave is handy when you’re using libraries that provide asynchronous operation (e.g. AFNetworking).&lt;/p&gt;
&lt;p&gt;The last thing to do is wait for all of the tasks to finish. The preferred way to do this is to use dispatch_group_notify:&lt;/p&gt;
&lt;pre&gt;dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    // Do stuff after all tasks are finished
});&lt;/pre&gt;
&lt;p&gt;dispatch_group_notify is nice because it does not block the thread it’s called from. If you have a reason to block the current thread, use dispatch_group_wait instead:&lt;/p&gt;
&lt;pre&gt;dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
// Do stuff after all tasks are finished&lt;/pre&gt;
&lt;p&gt;A full example looks like this:&lt;/p&gt;
&lt;pre&gt;dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // Do stuff on a global background queue here
});

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // Do more stuff on a global background queue here
});

dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    // Do stuff after all tasks are finished
});&lt;/pre&gt;
&lt;p&gt;One important note about dispatch objects: If your project&amp;#8217;s deployment target is less than 6.0, you need to manage memory with dispatch_retain and dispatch_release for any dispatch objects you create (groups, queues, semaphores). ARC takes care of managing memory for dispatch objects when your deployment target is 6.0+ (10.8+ for OS X).&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/3mMLp4eyGUU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/3mMLp4eyGUU/48248949039</link><guid isPermaLink="false">http://amro.co/post/48248949039</guid><pubDate>Wed, 17 Apr 2013 22:28:00 -0400</pubDate><feedburner:origLink>http://amro.co/post/48248949039</feedburner:origLink></item><item><title>Installing Ruby 1.9.3 on Ubuntu from Source</title><description>&lt;div class="posterous_autopost"&gt;&lt;div style=""&gt;Just a note for myself since most of the tutorials seem to leave out libyaml or something.&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote type="cite"&gt;&lt;div style=""&gt;sudo apt-get install gcc g++ build-essential libssl-dev libreadline5-dev zlib1g libyaml-dev zlib1g-dev linux-headers-generic libsqlite3-dev&lt;/div&gt;&lt;div style=""&gt;wget &lt;a href="ftp://ftp.ruby-lang.org//pub/ruby/1.9/ruby-1.9.3-p194.tar.gz"&gt;&lt;a href="ftp://ftp.ruby-lang.org//pub/ruby/1.9/ruby-1.9.3-p194.tar.gz"&gt;ftp://ftp.ruby-lang.org//pub/ruby/1.9/ruby-1.9.3-p194.tar.gz&lt;/a&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;div style=""&gt;tar -xvzf ruby-1.9.3-p194.tar.gz&lt;/div&gt;&lt;div style=""&gt;cd ruby-1.9.3-p194/ &amp;amp;&amp;amp; ./configure &amp;#8212;prefix=/usr/local &amp;amp;&amp;amp; make &amp;amp;&amp;amp; sudo make install&lt;/div&gt;&lt;/blockquote&gt;      &lt;p style="font-size: 10px;"&gt;  &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;   from &lt;a href="http://amro.co/installing-ruby-193-on-ubuntu-from-source"&gt;amro&amp;#8217;s blog&lt;/a&gt;  &lt;/p&gt;  &lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/mSBHy-d1eKA" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/mSBHy-d1eKA/21649508896</link><guid isPermaLink="false">http://amro.co/post/21649508896</guid><pubDate>Mon, 23 Apr 2012 11:46:25 -0400</pubDate><feedburner:origLink>http://amro.co/post/21649508896</feedburner:origLink></item><item><title>How to Retain Your Employees</title><description>&lt;div class="posterous_autopost"&gt;Genuinely give a shit. That&amp;#8217;s the TL;DR but I&amp;#8217;ll elaborate. High turnover, especially at startups, is often the result of burn out. Here are my thoughts on preventing burnout.&lt;div&gt;Here&amp;#8217;s the thing, your employees care about your business. Even the lazy ones. But they don&amp;#8217;t want to fight fires all the time. Set the expectation that they should be intense while they&amp;#8217;re at work and have a life afterward[1]. Instead, set reasonable goals. Figure out what&amp;#8217;s most important and give them reasons to &lt;i&gt;want&lt;/i&gt; to work hard for you. What incentives? Money. Food. Feedback[2]. Sure, any of those, and probably lots of other things. &lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;Employees don&amp;#8217;t want to feel like &amp;#8220;resources.&amp;#8221; They want to feel human and do their part to make the cogs turn. Training employees will cost you in the long run so give current employees good reasons to stick around. Don&amp;#8217;t be stingy. Give employees enough money to make them feel valued. That means good raises, bonuses, and so on [3]. While money isn&amp;#8217;t everything, the perception of forward movement goes a long way.&lt;/div&gt;&lt;div&gt;Food is great because it&amp;#8217;s a great way to make people feel cared for without spending tons of money, especially during crunch time. At my day job, they buy us lunch when it rains or when new people join. Sometimes it&amp;#8217;s fancy food and other times it&amp;#8217;s pizza. But it&amp;#8217;s &lt;i&gt;always&lt;/i&gt; appreciated.&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;Feedback is free. Let employees know what you think of their work. If they&amp;#8217;re doing a great job then praise their work. If they&amp;#8217;re struggling then coach[4] them and help them improve. That&amp;#8217;s often easier than finding new employees to replace the ones you fire.&lt;/div&gt;&lt;div&gt;It&amp;#8217;s not your job to make your employees happy but it is your job to provide a great work environment, set expectations, and encourage employees to be intense at work without burning out.&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;[1] Sometimes work outside of typical hours is required. That&amp;#8217;s fine. What&amp;#8217;s not fine is for that to be the norm.&lt;/div&gt;&lt;div&gt;[2] You should also give critical feedback when your employees screw up. Employees need mentorship as much as they need praise.&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 11px;"&gt;[3] Giving extra money isn&amp;#8217;t always possible. Profitable companies (or companies with tons of VC dough) can do a better job at this. And obviously it should be a sound business decision (as defined by the resources you have at your disposal).&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 11px;"&gt;[4] Note that coaching and negativity are not the same thing. Coaching means telling them what they&amp;#8217;re doing right and pointing out where they can improve. Be constructive and critical. Don&amp;#8217;t be negative.&lt;/span&gt;&lt;/div&gt;      &lt;p style="font-size: 10px;"&gt;  &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;   from &lt;a href="http://amro.co/how-to-retain-your-employees"&gt;amro&amp;#8217;s blog&lt;/a&gt;  &lt;/p&gt;  &lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/jcmq_ClQlFs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/jcmq_ClQlFs/19551681780</link><guid isPermaLink="false">http://amro.co/post/19551681780</guid><pubDate>Sun, 18 Mar 2012 22:00:52 -0400</pubDate><feedburner:origLink>http://amro.co/post/19551681780</feedburner:origLink></item><item><title>Nest</title><description>&lt;div class="posterous_autopost"&gt;I bought a &lt;a href="http://www.nest.com/"&gt;nest thermostat&lt;/a&gt; a while back. I wanted it because of one particular feature: the ability to set the temperature in my home from my iPhone and iPad (or an Android device, web browser). Installation was a piece of cake &amp;#8212; a couple of screws and four wires. Setup was simple and the web and mobile apps are well done. Plus it promises to save one money and is software upgradable (wee!). It&amp;#8217;s an incredible little device.&lt;div&gt;Fast forward to a few days ago, when the nest reported that it couldn&amp;#8217;t detect the fan wire. It also read the current temperature in the house a few degrees higher than actual (confirmed with two other thermometers). We had just installed a whole house humidifier, through which the fan wire runs, so I thought fan wire issue might be related to that. Nope. Then the nest dropped off my wireless network and gave a low battery warning. This is odd because my nest has been working without issue for weeks. I tried the obvious (charging via usb, resetting to factory settings, etc.) but nothing seemed to help. My house was now around 64 degrees fahrenheit (the nest claimed 84!) late on Sunday. Hardware stores, where one might buy a temporary thermostat, are closed.&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;So I called support. I was on hold for longer than I liked (perhaps 20 minutes?), then a guy named David picked up. David was exactly the kind of guy you want on the other side of a telephone call in a situation like this. I described the symptoms and he immediately knew what was up &amp;#8212; a bad update (v1.1.2) had been downloaded by my nest and couldn&amp;#8217;t be installed. The nest was repeatedly trying to install this update, which ran the battery down and caused my problem. David was able to look at detailed logging to see that my nest had indeed downloaded said bad build, and essentially issued a command for my nest to download a new fixed version of the same build.&lt;/div&gt;&lt;div&gt;At this point, I charged the nest via usb once more and put it back on the base an hour later. I set it to heat my home, made sure it was connected to my network, and left it alone. A few minutes later all was well. The temperature nest was reading was closer to normal and entirely normal by morning). So not only did they have someone there to take my call late on a Sunday night, but they also had enough data to know exactly what my problem was *and* push an update to fix it the same night. Should this have happened at all? No. Did they resolve my issue promptly? Very much so. Nest has excellent support.&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;&lt;span style="font-size: 11px;"&gt;An aside &amp;#8212; the nest is a mass storage device. It shows up as a drive with 40MB free space and has a single visible file &amp;#8212; a plist file containing the serial number and some other mundane info. The plist is curious (it definitely shows the nest&amp;#8217;s Apple roots, so to speak).&lt;/span&gt;&lt;/div&gt;      &lt;p style="font-size: 10px;"&gt;  &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;   from &lt;a href="http://amro.co/nest"&gt;amro&amp;#8217;s blog&lt;/a&gt; | &lt;a href="http://amro.co/nest#comment"&gt;&lt;span style="font-size: 11px"&gt;Comment&amp;#160;»&lt;/span&gt;&lt;/a&gt;  &lt;/p&gt;  &lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/FzlhvIvWMuI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/FzlhvIvWMuI/16850770842</link><guid isPermaLink="false">http://amro.co/post/16850770842</guid><pubDate>Tue, 31 Jan 2012 22:16:04 -0500</pubDate><feedburner:origLink>http://amro.co/post/16850770842</feedburner:origLink></item><item><title>Uh oh. The boy just Climbed out of his crib for the first time.</title><description>&lt;p&gt;Uh oh. The boy just Climbed out of his crib for the first time.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/gzR3uEBQa5c" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/gzR3uEBQa5c/15195850226</link><guid isPermaLink="false">http://amro.co/post/15195850226</guid><pubDate>Mon, 02 Jan 2012 14:49:38 -0500</pubDate><feedburner:origLink>http://amro.co/post/15195850226</feedburner:origLink></item><item><title>Photo</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_lwdsbcS5BR1qz9b44o1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/IoQ1KP67-nU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/IoQ1KP67-nU/14387003764</link><guid isPermaLink="false">http://amro.co/post/14387003764</guid><pubDate>Sat, 17 Dec 2011 22:57:11 -0500</pubDate><feedburner:origLink>http://amro.co/post/14387003764</feedburner:origLink></item><item><title>Springboard Style Wiggles</title><description>&lt;div class="posterous_autopost"&gt;&lt;div&gt;So you figured out how to setup a &lt;a href="http://developer.apple.com/library/IOs/#documentation/UIKit/Reference/UILongPressGestureRecognizer_Class/Reference/Reference.html"&gt;UILongPressGestureRecognizer&lt;/a&gt; and now you want to make a view &amp;#8220;wiggle&amp;#8221; back and forth similar to the iOS Springboard app. This is actually pretty simple with Core Animation.&lt;/div&gt;&lt;div&gt;First, setup the view you want to wiggle. The code below assumes it&amp;#8217;s called &amp;#8220;view.&amp;#8221; I&amp;#8217;ve found that setting kWiggleAnimationAngle to 0.04 works well.&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;In your gesture recognizer&amp;#8217;s handler:&lt;/div&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;&lt;div&gt;//Start at negative kWiggleAnimationAngle so we animate to positive kWiggleAnimationAngle&lt;/div&gt;&lt;div&gt;view.layer.transform = CATransform3DMakeRotation(-kWiggleAnimationAngle, 0, 0, 1.0);&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;//Setup a transform that will rotate our view to positive kWiggleAnimationAngle&lt;/div&gt;&lt;div&gt;CATransform3D transform = CATransform3DMakeRotation(kWiggleAnimationAngle, 0, 0, 1.0);&lt;/div&gt;&lt;div&gt;//Setup our animation with the transform&lt;/div&gt;&lt;div&gt;CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@&amp;#8221;transform&amp;#8221;];&lt;/div&gt;&lt;div&gt;animation.toValue = [NSValue valueWithCATransform3D:transform];&lt;/div&gt;&lt;div&gt;animation.repeatCount = HUGE_VALF;&lt;/div&gt;&lt;div&gt;animation.duration = 0.1;&lt;/div&gt;&lt;div&gt;animation.autoreverses = YES;&lt;/div&gt;&lt;div&gt;[view.layer addAnimation:animation forKey:@&amp;#8221;wiggle&amp;#8221;];&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;We&amp;#8217;re also setting a few important properties:&lt;/div&gt;&lt;div&gt;- setting repeatCount to HUGE_VALF tells the animation to play indefinitely&lt;/div&gt;&lt;div&gt;- duration is the length of the animation (in one direction)&lt;/div&gt;&lt;div&gt;- autoreverses tells Core Animation to automatically play the animation in reverse once it&amp;#8217;s finished&lt;/div&gt;&lt;div&gt;Finally we add the animation to our view&amp;#8217;s layer and that&amp;#8217;s that. Well, sort of, when we&amp;#8217;re ready to stop the animation we need to do the following:&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"&gt;&lt;div&gt;//Remove the animation from our view&lt;/div&gt;&lt;div&gt;[view.layer removeAnimationForKey:@&amp;#8221;wiggle&amp;#8221;];&lt;/div&gt;&lt;div&gt;//Rotate the view back to its default position&lt;/div&gt;&lt;div&gt;view.layer.transform = CATransform3DMakeRotation(0.0, 0, 0, 1.0);&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;Resources: &lt;a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreAnimation_guide/Introduction/Introduction.html"&gt;Apple&amp;#8217;s Core Animation Programming Guide&lt;/a&gt;, &lt;a href="http://developer.apple.com/videos/wwdc/2011/"&gt;WWDC 2011 Videos&lt;/a&gt;, &lt;a href="http://stackoverflow.com/questions/3703922/how-do-you-create-a-wiggle-animation-similar-to-iphone-deletion-animation/3704540#3704540"&gt;Almost There Stackoverflow Post&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Notes: I generally dislike in-app Springboards but sometimes they fit the bill.&lt;/div&gt;      &lt;p style="font-size: 10px;"&gt;  &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;   from &lt;a href="http://amro.co/springboard-style-wiggles"&gt;amro&amp;#8217;s blog&lt;/a&gt; | &lt;a href="http://amro.co/springboard-style-wiggles#comment"&gt;&lt;span style="font-size: 11px"&gt;Comment&amp;#160;»&lt;/span&gt;&lt;/a&gt;  &lt;/p&gt;  &lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/Bw5lDlgCE4s" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/Bw5lDlgCE4s/14195929580</link><guid isPermaLink="false">http://amro.co/post/14195929580</guid><pubDate>Tue, 13 Dec 2011 21:23:35 -0500</pubDate><feedburner:origLink>http://amro.co/post/14195929580</feedburner:origLink></item><item><title>The case for a real ‘Apple TV’? (Taken with...</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_ln03dkJ9Hn1qz9b44o1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;The case for a real ‘Apple TV’? (Taken with &lt;a href="http://instagr.am"&gt;instagram&lt;/a&gt;)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/BUlVKg7g0WA" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/BUlVKg7g0WA/6663275280</link><guid isPermaLink="false">http://amro.co/post/6663275280</guid><pubDate>Sat, 18 Jun 2011 15:27:21 -0400</pubDate><feedburner:origLink>http://amro.co/post/6663275280</feedburner:origLink></item><item><title>Little man wearing his Star Wars shirt. 16 months old today....</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_lmzsraxDSW1qz9b44o1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Little man wearing his Star Wars shirt. 16 months old today. (Taken with &lt;a href="http://instagr.am"&gt;instagram&lt;/a&gt;)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/KulUvORgF-w" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/KulUvORgF-w/6656915714</link><guid isPermaLink="false">http://amro.co/post/6656915714</guid><pubDate>Sat, 18 Jun 2011 11:37:58 -0400</pubDate><feedburner:origLink>http://amro.co/post/6656915714</feedburner:origLink></item><item><title>Watching Buzz Aldrin speak. Last WWDC session. (Taken with...</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_lmlbnz8hwK1qz9b44o1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Watching Buzz Aldrin speak. Last WWDC session. (Taken with &lt;a href="http://instagr.am"&gt;instagram&lt;/a&gt;)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/2lzIq5MEqk0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/2lzIq5MEqk0/6393211422</link><guid isPermaLink="false">http://amro.co/post/6393211422</guid><pubDate>Fri, 10 Jun 2011 16:02:24 -0400</pubDate><feedburner:origLink>http://amro.co/post/6393211422</feedburner:origLink></item><item><title>Securing application data #wwdc (Taken with instagram)</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_lmj5g8u0S01qz9b44o1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Securing application data #wwdc (Taken with &lt;a href="http://instagr.am"&gt;instagram&lt;/a&gt;)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/37GWN_9Q5Nc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/37GWN_9Q5Nc/6355238076</link><guid isPermaLink="false">http://amro.co/post/6355238076</guid><pubDate>Thu, 09 Jun 2011 11:52:57 -0400</pubDate><category>wwdc</category><feedburner:origLink>http://amro.co/post/6355238076</feedburner:origLink></item><item><title>WWDC Keynote. (Taken with instagram)</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_lmibd01ILC1qz9b44o1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;WWDC Keynote. (Taken with &lt;a href="http://instagr.am"&gt;instagram&lt;/a&gt;)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/mE1f1dzTwz0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/mE1f1dzTwz0/6344749697</link><guid isPermaLink="false">http://amro.co/post/6344749697</guid><pubDate>Thu, 09 Jun 2011 01:03:01 -0400</pubDate><feedburner:origLink>http://amro.co/post/6344749697</feedburner:origLink></item><item><title>Two iOS Libraries That Make Life Easier</title><description>&lt;p&gt;&lt;div class="posterous_autopost"&gt; &lt;div&gt;&lt;span&gt;1) &lt;a href="https://github.com/mdales/asi-http-request"&gt;ASIHTTPRequest&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;2) &lt;a href="https://github.com/rs/SDWebImage"&gt;SDWebImage&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Bonus: &lt;a href="http://stackoverflow.com"&gt;stackoverflow&lt;/a&gt;, &lt;a href="http://developer.apple.com/videos/wwdc/2010/"&gt;WWDC session videos&lt;/a&gt;, and &lt;a href="http://cocoawithlove.com/"&gt;Cocoa with Love&lt;/a&gt; are all excellent resources.&lt;/div&gt;       &lt;p style="font-size: 10px;"&gt;  &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;   from &lt;a href="http://amro.co/two-ios-libraries-that-make-life-easier"&gt;amro&amp;#8217;s blog&lt;/a&gt; | &lt;a href="http://amro.co/two-ios-libraries-that-make-life-easier#comment"&gt;&lt;span style="font-size: 11px"&gt;Comment&amp;#160;»&lt;/span&gt;&lt;/a&gt;  &lt;/p&gt;  &lt;/div&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/SiN0JHXYZZo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/SiN0JHXYZZo/6130378810</link><guid isPermaLink="false">http://amro.co/post/6130378810</guid><pubDate>Thu, 02 Jun 2011 23:04:31 -0400</pubDate><feedburner:origLink>http://amro.co/post/6130378810</feedburner:origLink></item><item><title>Stupid Simple Async HTTP Client for Android</title><description>&lt;p&gt;&lt;div class="posterous_autopost"&gt; &lt;span&gt;&lt;a href="https://github.com/loopj/android-async-http"&gt;android-async-http&lt;/a&gt;.&lt;/span&gt;       &lt;p style="font-size: 10px;"&gt;  &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;   from &lt;a href="http://amro.co/stupid-simple-async-http-client-for-android"&gt;amro&amp;#8217;s blog&lt;/a&gt; | &lt;a href="http://amro.co/stupid-simple-async-http-client-for-android#comment"&gt;&lt;span style="font-size: 11px"&gt;Comment&amp;#160;»&lt;/span&gt;&lt;/a&gt;  &lt;/p&gt;  &lt;/div&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/iC_IZ8SBh_E" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/iC_IZ8SBh_E/6130008105</link><guid isPermaLink="false">http://amro.co/post/6130008105</guid><pubDate>Thu, 02 Jun 2011 22:52:59 -0400</pubDate><feedburner:origLink>http://amro.co/post/6130008105</feedburner:origLink></item><item><title>Dynamic UITableViewCell Height</title><description>&lt;p&gt;&lt;div class="posterous_autopost"&gt; &lt;div&gt;&amp;#8230;based on string length, a given width, and font.&lt;/div&gt;&lt;div&gt; &lt;span&gt; &lt;div class="data type-objective-c"&gt;  &lt;table cellspacing="0" cellpadding="0"&gt;&lt;tr&gt;&lt;td&gt; &lt;pre class="line_numbers"&gt;&lt;span rel="#L1" id="L1"&gt;1&lt;/span&gt; &lt;span rel="#L2" id="L2"&gt;2&lt;/span&gt; &lt;span rel="#L3" id="L3"&gt;3&lt;/span&gt; &lt;span rel="#L4" id="L4"&gt;4&lt;/span&gt; &lt;span rel="#L5" id="L5"&gt;5&lt;/span&gt; &lt;span rel="#L6" id="L6"&gt;6&lt;/span&gt; &lt;/pre&gt; &lt;/td&gt; &lt;td width="100%"&gt;   &lt;div class="highlight"&gt;&lt;pre&gt;&lt;/pre&gt;&lt;div class="line" id="LC1"&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CGFloat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nl"&gt;tableView:&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UITableView&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;tableView&lt;/span&gt; &lt;span class="nl"&gt;heightForRowAtIndexPath:&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NSIndexPath&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;indexPath&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC2"&gt;    &lt;span class="n"&gt;NSString&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="nl"&gt;objectAtIndex:&lt;/span&gt;&lt;span class="n"&gt;indexPath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC3"&gt;    &lt;span class="n"&gt;CGSize&lt;/span&gt; &lt;span class="n"&gt;suggestedSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="nl"&gt;sizeWithFont:&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;UIFont&lt;/span&gt; &lt;span class="nl"&gt;systemFontOfSize:&lt;/span&gt;&lt;span class="mf"&gt;15.0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nl"&gt;constrainedToSize:&lt;/span&gt;&lt;span class="n"&gt;CGSizeMake&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;224.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FLT_MAX&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nl"&gt;lineBreakMode:&lt;/span&gt;&lt;span class="n"&gt;UILineBreakModeWordWrap&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC4"&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;suggestedSize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// add 40px for padding?&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC5"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC6"&gt;&lt;br/&gt;&lt;/div&gt;&lt;/div&gt;   &lt;/td&gt; &lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br/&gt;&lt;/span&gt; &lt;/div&gt;       &lt;p style="font-size: 10px;"&gt;  &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;   from &lt;a href="http://amro.co/dynamic-uitableviewcell-height"&gt;amro&amp;#8217;s blog&lt;/a&gt; | &lt;a href="http://amro.co/dynamic-uitableviewcell-height#comment"&gt;&lt;span style="font-size: 11px"&gt;Comment&amp;#160;»&lt;/span&gt;&lt;/a&gt;  &lt;/p&gt;  &lt;/div&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/yBQv3IYSIYU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/yBQv3IYSIYU/4808667247</link><guid isPermaLink="false">http://amro.co/post/4808667247</guid><pubDate>Thu, 21 Apr 2011 12:24:32 -0400</pubDate><feedburner:origLink>http://amro.co/post/4808667247</feedburner:origLink></item><item><title>iOS SDK and Garbage Collection</title><description>&lt;p&gt;&lt;div class="posterous_autopost"&gt;  &lt;span&gt;Sure, garbage collection would be nice. The lack of automated garbage collection on iOS does not increase development time by a &lt;/span&gt;&lt;a href="http://techcrunch.com/2011/04/16/what-app-developers-want"&gt;factor of two&lt;/a&gt;&lt;span&gt;. Something else is wrong and it has much to do with an error in the floor to keyboard interface.&lt;/span&gt;        &lt;p style="font-size: 10px;"&gt;  &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;   from &lt;a href="http://amro.co/ios-sdk-and-garbage-collection"&gt;amro&amp;#8217;s blog&lt;/a&gt; | &lt;a href="http://amro.co/ios-sdk-and-garbage-collection#comment"&gt;&lt;span style="font-size: 11px"&gt;Comment&amp;#160;»&lt;/span&gt;&lt;/a&gt;  &lt;/p&gt;  &lt;/div&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/YpeEGoiEc2k" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/YpeEGoiEc2k/4698321941</link><guid isPermaLink="false">http://amro.co/post/4698321941</guid><pubDate>Sun, 17 Apr 2011 16:48:44 -0400</pubDate><feedburner:origLink>http://amro.co/post/4698321941</feedburner:origLink></item><item><title>Fix for Black Corners On Grouped UITableView</title><description>&lt;div class="posterous_autopost"&gt;&lt;div class="p_embed p_image_embed"&gt; &lt;a href="http://posterous.com/getfile/files.posterous.com/amro/zXm8YlgfTJeYXW95hq4KQCJytTXFdCYImihZbKscm25JnjHj1hmtztuPLZQZ/TEMP-Image_1_3.png"&gt;&lt;img alt="Temp-image_1_3" height="109" src="http://posterous.com/getfile/files.posterous.com/amro/GkJ0odcRxPQcNYWxqQjcMHtAI4CSpa7tDzqgUaswgLNrbAI0hKhA3nApbZRd/TEMP-Image_1_3.png.scaled.500.jpg" width="500"/&gt;&lt;/a&gt; &lt;/div&gt; &lt;div&gt; &lt;div&gt; &lt;div&gt; &lt;div&gt;I recently ran into a problem with black corners on a grouped style UITableView. I figured out that it happens when one sets the background color of the table to clearColor in Interface Builder. The solution is to set the background color programmatically instead. #bug&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;&lt;img style="height: 110px;"/&gt;&lt;/div&gt; &lt;/div&gt;&lt;span&gt;&lt;br/&gt;&lt;/span&gt; &lt;/div&gt; &lt;/div&gt;      &lt;p style="font-size: 10px;"&gt;  &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;   from &lt;a href="http://amro.co/fix-for-black-corners-on-grouped-uitableview"&gt;amro&amp;#8217;s blog&lt;/a&gt; | &lt;a href="http://amro.co/fix-for-black-corners-on-grouped-uitableview#comment"&gt;&lt;span style="font-size: 11px"&gt;Comment&amp;#160;»&lt;/span&gt;&lt;/a&gt;  &lt;/p&gt;  &lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/b7AN8QHEukg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/b7AN8QHEukg/4428379140</link><guid isPermaLink="false">http://amro.co/post/4428379140</guid><pubDate>Fri, 08 Apr 2011 00:28:37 -0400</pubDate><feedburner:origLink>http://amro.co/post/4428379140</feedburner:origLink></item><item><title>C2DM 0.1.5</title><description>&lt;p&gt;&lt;div class="posterous_autopost"&gt; &lt;div&gt;&lt;span&gt;A while back I put out a gem to help ruby devs send push notifications to Android devices. I just released version C2DM 0.1.5, which mainly adds support for multiple key-value pairs in the notification payload and simplifies usage. &lt;/span&gt;The interface did change so you&amp;#8217;ll want to check out the &lt;a href="http://github.com/amro/c2dm"&gt;README&lt;/a&gt;. This release also fixes minor bugs and there&amp;#8217;s a bit of code cleanup thanks to &lt;a href="http://github.com/veader"&gt;Veader&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;span&gt;You might also want to check out &lt;a href="http://groupme.com"&gt;GroupMe&amp;#8217;s&lt;/a&gt; &lt;a href="https://github.com/groupme/c2dm"&gt;fork&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;       &lt;p style="font-size: 10px;"&gt;  &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;   from &lt;a href="http://amro.co/c2dm-015"&gt;amdev&amp;#8217;s blog&lt;/a&gt; | &lt;a href="http://amro.co/c2dm-015#comment"&gt;&lt;span style="font-size: 11px"&gt;Comment&amp;#160;»&lt;/span&gt;&lt;/a&gt;  &lt;/p&gt;  &lt;/div&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/xAubfImmjfA" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/xAubfImmjfA/4258511140</link><guid isPermaLink="false">http://amro.co/post/4258511140</guid><pubDate>Fri, 01 Apr 2011 14:30:31 -0400</pubDate><feedburner:origLink>http://amro.co/post/4258511140</feedburner:origLink></item><item><title>Another Way to Improve App Store Reviews</title><description>&lt;div class="posterous_autopost"&gt;A few days ago I suggested using Appirater to boost App Store review quality. It&amp;#8217;s also important to provide in app help as it gives users a place to find quick answers and request assistance before giving up and leaving a poor review.  We prominently display a &amp;#8220;Help&amp;#8221; button at the top of BillMinder&amp;#8217;s Settings tab. It&amp;#8217;s clearly easier to find than something hidden at the bottom of a table. Tapping the Help button brings up an alert sheet, which lets users choose to view the FAQ or email support. &lt;p&gt;&lt;/p&gt; Adding an in-app FAQ page means users always have common answers available to them. We load BillMinder&amp;#8217;s FAQ in a web view so we can change the content without pushing another build. This is great since it can be tailored to trending questions received via support emails. The obvious drawback to using a web view is it requires an internet connection. That&amp;#8217;s a trade-off we&amp;#8217;re willing to make. We also ensure the FAQ page matches the app&amp;#8217;s style to make the experience a little more pleasant.  In the event that a user doesn&amp;#8217;t read the FAQ (ha! ;) or find the information they need, they can request assistance via email from within BillMinder. This is handy since it makes it easier to ask for help than leave a 1 star review. It also aids the indie dev giving support since they remembered to add important information, like OS and app versions, to the bottom of the email. &lt;p&gt;&lt;/p&gt; As always, YMMV but these things work well for us.&lt;div class="p_embed p_image_embed"&gt; &lt;a href="http://posterous.com/getfile/files.posterous.com/amro/OFP4uYwP3qd3o2U0ykOfT5GAA2w8QH3CDexa3e7zDyTdSYIjFO4c7LagrJgL/1.png"&gt;&lt;img alt="1" height="750" src="http://posterous.com/getfile/files.posterous.com/amro/JaXr0lnyDjmlc897dkbYsBsTIGzxfB7zqpI57tUmEbTlMpjBoEaXOLC9DIuA/1.png.scaled.500.jpg" width="500"/&gt;&lt;/a&gt; &lt;a href="http://posterous.com/getfile/files.posterous.com/amro/19g24AkUhuuRpXyXWLTCn1w2Ue1keggWqEwN531yf3xhzBMsOyaJD06QFJsU/2.png"&gt;&lt;img alt="2" height="750" src="http://posterous.com/getfile/files.posterous.com/amro/t7ILr6ACgBVxqOytjDqf7O6ZZGijldEALlIJwZimMyzR6lFnYsrpp2Hx243e/2.png.scaled.500.jpg" width="500"/&gt;&lt;/a&gt; &lt;a href="http://posterous.com/getfile/files.posterous.com/amro/GDVJXXQ7ekmKxwa5PBKexndhLLIqDGtr9m1o72UxCqJFHbC1qgeNuC7yS5xb/3.png"&gt;&lt;img alt="3" height="750" src="http://posterous.com/getfile/files.posterous.com/amro/EaD2EkZPKfYvjvdS678sCBSu6JSTxnZ92ekuC0SfTnnysNZHS4NQzXBtDBpk/3.png.scaled.500.jpg" width="500"/&gt;&lt;/a&gt; &lt;div class="p_see_full_gallery"&gt;&lt;a href="http://amro.co/another-way-to-improve-app-store-reviews"&gt;See the full gallery on Posterous&lt;/a&gt;&lt;/div&gt; &lt;/div&gt;       &lt;p style="font-size: 10px;"&gt;  &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;   from &lt;a href="http://amro.co/another-way-to-improve-app-store-reviews"&gt;amdev&amp;#8217;s blog&lt;/a&gt; | &lt;a href="http://amro.co/another-way-to-improve-app-store-reviews#comment"&gt;&lt;span style="font-size: 11px"&gt;Comment&amp;#160;»&lt;/span&gt;&lt;/a&gt;  &lt;/p&gt;  &lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/WKVbudA0G-o" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/WKVbudA0G-o/3754351713</link><guid isPermaLink="false">http://amro.co/post/3754351713</guid><pubDate>Thu, 10 Mar 2011 00:36:27 -0500</pubDate><feedburner:origLink>http://amro.co/post/3754351713</feedburner:origLink></item><item><title>How To Get 4 to 5 Stars On The App Store</title><description>&lt;div class="posterous_autopost"&gt;&lt;div class="p_embed p_image_embed"&gt; &lt;img alt="Review_graph" height="144" src="http://posterous.com/getfile/files.posterous.com/amro/tkHyAEcJOKPtWShnQdys2HzVFn33L8UKagucOHjAOMUKsCVX3bIg3tuFaSWH/review_graph.png" width="433"/&gt;&lt;/div&gt; &lt;p&gt;The reality is some developers pay for downloads and reviews to get higher rankings on the App Store. It&amp;#8217;s tough for Apple to do much about it since the sales look legitimate. It&amp;#8217;s easy to be frustrated by this sort of thing but there are two things you can do to beat it (ymmv, of course): &lt;/p&gt; 1) Release a good app &lt;br/&gt;2) Use Appirater &lt;p&gt;&lt;/p&gt; Appirater asks your users to review your app after some conditions are met. This seems simple but generally the folks who give feedback are the ones who are upset. When you ask repeat, often happy, users of your app to review it, you get some decent percentage of folks who are pleased to essentially /up vote/. #WINNER  We added Appirater to the latest version of BillMinder 3. Here is the current version&amp;#8217;s review graph:      &lt;p style="font-size: 10px;"&gt;  &lt;a href="http://posterous.com"&gt;Posted via email&lt;/a&gt;   from &lt;a href="http://amro.co/how-to-get-4-to-5-stars-on-the-app-store"&gt;amdev&amp;#8217;s blog&lt;/a&gt; | &lt;a href="http://amro.co/how-to-get-4-to-5-stars-on-the-app-store#comment"&gt;&lt;span style="font-size: 11px"&gt;Comment&amp;#160;»&lt;/span&gt;&lt;/a&gt;  &lt;/p&gt;  &lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/amdev/~4/Vn0qwa-AgBo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/amdev/~3/Vn0qwa-AgBo/3690661231</link><guid isPermaLink="false">http://amro.co/post/3690661231</guid><pubDate>Sun, 06 Mar 2011 23:32:16 -0500</pubDate><feedburner:origLink>http://amro.co/post/3690661231</feedburner:origLink></item></channel></rss>
