<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Sean Carpenter]]></title>
  <link href="https://blog.seancarpenter.net/atom.xml" rel="self"/>
  <link href="https://blog.seancarpenter.net/"/>
  <updated>2018-09-12T21:10:31-04:00</updated>
  <id>https://blog.seancarpenter.net/</id>
  <author>
    <name><![CDATA[Sean Carpenter]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Ro To Sleep - A New Roku Sleep Timer]]></title>
    <link href="https://blog.seancarpenter.net/2015/12/21/ro-to-sleep-a-new-roku-sleep-timer/"/>
    <updated>2015-12-21T16:25:00-05:00</updated>
    <id>https://blog.seancarpenter.net/2015/12/21/ro-to-sleep-a-new-roku-sleep-timer</id>
    <content type="html"><![CDATA[<p>About <a href="http://blog.seancarpenter.net/2013/12/18/romote-now-with-a-sleep-timer/">two years ago</a>, I had an idea to add a sleep timer to the <a href="https://www.roku.com">Roku</a> remote control iOS app that I had written, Romote.</p>

<!-- more -->


<p>Since then, the sleep timer functionality has been used thousands of times by hundreds of people. During that same time, the <a href="https://itunes.apple.com/us/app/roku/id482066631?mt=8&amp;at=10l5G3&amp;ct=blog">Roku remote control</a> provided by Roku has increased in usefulness adding some of the features I found most useful in Romote.</p>

<p>Considering those facts, I decided to take the Roku sleep timer functionality from Romote and make it a stand alone app:</p>

<div class="centered screenshots">
    <a href="https://itunes.apple.com/us/app/ro-to-sleep-roku-streaming/id1067642181?ls=1&amp;mt=8&amp;at=10l5G3&amp;ct=blog" class="plain-image">
        <img src="http://pictures.seancarpenter.net/blog/ro_to_sleep.png" width="180" height="180" title="Ro To Sleep" alt="Ro To Sleep">
    </a>
</div>


<p><a href="https://itunes.apple.com/us/app/ro-to-sleep-roku-streaming/id1067642181?ls=1&amp;mt=8&amp;at=10l5G3&amp;ct=blog">Ro To Sleep</a> adds the same great sleep timer capability to your Roku with a simple interface that lets you get your timer set without any fuss. On devices that support it, Ro To Sleep lets you set a timer right from your home screen using 3D Touch.</p>

<p>Ro To Sleep is free to use up to 5 times - you can make sure the sleep timer meets your needs before having to commit any money. After that, a one-time in app purchase unlocks unlimited use of the sleep timer. Use of the timer has the same caveats as the Romote timer:</p>

<ol class="indented-list">
    <li>You must have an internet connection for the sleep timer to work.</li>
    <li>Ro To Sleep can&#8217;t control your TV. This means that Ro To Sleep will stop playback on the Roku but your TV will remain on. If you want to also turn off your TV, you&#8217;ll have to use whatever timer capability is built in to the TV.</li>
</ol>


<p>For anyone that has purchased Romote, the timer built-in timer capability will continue to work for at least the next 6 months, but Romote itself won&#8217;t continue to be developed.</p>

<p>Head on over to <a href="https://itunes.apple.com/us/app/ro-to-sleep-roku-streaming/id1067642181?ls=1&amp;mt=8&amp;at=10l5G3&amp;ct=blog">the iTunes store</a> and get your copy of Ro To Sleep and enjoy falling asleep knowing that your Roku won&#8217;t be playing all night.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[iOS Push Notifications with Amazon SNS]]></title>
    <link href="https://blog.seancarpenter.net/2014/07/15/ios-push-notifications-with-amazon-sns/"/>
    <updated>2014-07-15T17:33:00-04:00</updated>
    <id>https://blog.seancarpenter.net/2014/07/15/ios-push-notifications-with-amazon-sns</id>
    <content type="html"><![CDATA[<p><a href="http://aws.amazon.com/sns/?nc1=h_l2_as">Amazon SNS</a> provides a cost-effective way to send push notifications to mobile devices. This is especially true for the relatively low push volume generated by something like the Roku sleep timer in <a href="http://itunes.apple.com/us/app/romote/id488604877?ls=1&amp;mt=8&amp;at=10l5G3&amp;ct=blog">Romote</a>. Using SNS for mobile push is also supported well by the Ruby <a href="https://github.com/aws/aws-sdk-ruby">aws-sdk</a>.</p>

<!-- more -->


<p>To get started using SNS, you first need to create an app in SNS to represent your application. The <a href="http://docs.aws.amazon.com/sns/latest/dg/mobile-push-send-register.html">Amazon documentation</a> is pretty easy to follow - you will need the APNS certificate and private key from Apple for setting up push to iOS devices.</p>

<h3>Registering a Device</h3>

<p>Once you have an app created, you can start registering devices with it. This is accomplished using the <a href="http://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html">CreatePlatformEndpoint</a> API and requires the device token for the iOS device. I make the registration call from the <code>application:didRegisterforRemoteNotificationsWithDeviceToken:</code> callback in my application&#8217;s delegate.</p>

<h4>Aside</h4>

<p>I proxy all of the calls to SNS through a server that I run, so devices never communicate directly with SNS. This allows me to not expose any SNS credentials in my iOS apps as well as gives me the flexibility to change the communication with SNS (or remove SNS completely) without resubmitting the iOS apps.</p>

<p>Registering a device is easy using the Ruby aws-sdk:</p>

<figure class='code'><figcaption><span>Register a Device  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">client</span> <span class="o">=</span> <span class="no">AWS</span><span class="o">::</span><span class="no">SNS</span><span class="o">.</span><span class="n">new</span><span class="o">.</span><span class="n">client</span>
</span><span class='line'><span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">create_platform_endpoint</span><span class="p">(</span>
</span><span class='line'>  <span class="n">platform_application_arn</span><span class="p">:</span> <span class="s2">&quot;application-id-from-sns&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="n">token</span><span class="p">:</span> <span class="n">params</span><span class="o">[</span><span class="ss">:deviceToken</span><span class="o">]</span>
</span><span class='line'><span class="p">)</span>
</span><span class='line'><span class="n">endpoint_arn</span> <span class="o">=</span> <span class="n">response</span><span class="o">[</span><span class="ss">:endpoint_arn</span><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>The <code>endpoint_arn</code> can then be sent back to the device to use in future push notifications (or stored for later use at the server).</p>

<h3>Sending a Push Notification</h3>

<p>Once a device is registered, you can send direct push notifications to that device. This is done using the <a href="http://docs.aws.amazon.com/sns/latest/api/API_Publish.html">Publish</a> API. The <code>Publish</code> API supports sending a different message to each supported SNS transport as well as specifying a default message; when using device-specific mobile push notifications this isn&#8217;t necessary as each device will only be using a single transport (APNS or APNS_SANDBOX is the case of iOS).</p>

<p>SNS supports specifying all of the keys that Apple expects in a push notification using transport-specific messages. This requires setting the <code>MessageStructure</code> parameter of the <code>Publish</code> call to &#8220;json&#8221; and supplying a JSON formatted object in the <code>Message</code> parameter. One thing the documentation doesn&#8217;t make clear is that these need to be JSON-encoded strings and not raw JSON. An example will make this clearer:</p>

<figure class='code'><figcaption><span>Sending a Push  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">message</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>  <span class="s2">&quot;APNS&quot;</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="s2">&quot;aps&quot;</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="s2">&quot;content-available&quot;</span> <span class="o">=&gt;</span> <span class="kp">true</span> <span class="p">},</span>
</span><span class='line'>    <span class="s2">&quot;other_data&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;some_data&quot;</span>
</span><span class='line'>  <span class="p">}</span><span class="o">.</span><span class="n">to_json</span><span class="p">,</span>
</span><span class='line'>  <span class="s2">&quot;APNS_SANDBOX&quot;</span> <span class="o">=&gt;</span> <span class="p">{</span>
</span><span class='line'>    <span class="s2">&quot;aps&quot;</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="s2">&quot;content-available&quot;</span> <span class="o">=&gt;</span> <span class="kp">true</span> <span class="p">},</span>
</span><span class='line'>    <span class="s2">&quot;other_data&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;some_data&quot;</span>
</span><span class='line'>  <span class="p">}</span><span class="o">.</span><span class="n">to_json</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="n">push_parameters</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">target_arn</span><span class="p">:</span> <span class="s2">&quot;endpoint_arn_from_registration&quot;</span>
</span><span class='line'>  <span class="n">message_structure</span><span class="p">:</span> <span class="s2">&quot;json&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="n">message</span><span class="p">:</span> <span class="n">message</span><span class="o">.</span><span class="n">to_json</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="n">client</span> <span class="o">=</span> <span class="no">AWS</span><span class="o">::</span><span class="no">SNS</span><span class="o">.</span><span class="n">new</span><span class="o">.</span><span class="n">client</span>
</span><span class='line'><span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">publish</span><span class="p">(</span><span class="n">push_parameters</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>Notice the <code>to_json</code> calls on lines 5, 9, and 14. Each transport key needs to be a JSON string inside the <code>Message</code> parameter. Additionally, the <code>Message</code> parameter itself needs to be a JSON string. Getting this wrong (by having actual JSON instead of a JSON string) leads to SNS not being able parse the <code>Message</code> parameter and generates an error of &#8220;InvalidParameter: Invalid parameter: JSON must contain an entry for &#8216;default&#8217; or &#8216;APNS_SANDBOX&#8217;&#8221;.</p>

<p>The value of the <code>other_data</code> key is available in the <code>userInfo</code> dictionary provided to the <code>application:didReceiveRemoteNotification:</code> callback in your iOS application:</p>

<figure class='code'><figcaption><span>Handling the Notification  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">application:</span><span class="p">(</span><span class="n">UIApplication</span> <span class="o">*</span><span class="p">)</span><span class="nv">application</span> <span class="nf">didReceiveRemoteNotification:</span><span class="p">(</span><span class="n">NSDictionary</span> <span class="o">*</span><span class="p">)</span><span class="nv">userInfo</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">NSString</span><span class="o">*</span> <span class="n">otherData</span> <span class="o">=</span> <span class="p">[</span><span class="n">userInfo</span> <span class="nl">objectForKey:</span><span class="s">@&quot;other_data&quot;</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Summary</h3>

<p>Using just a few straightforward calls, it&#8217;s possible to send push notifications to your iOS apps. SNS also supports other mobile platforms (including Google Cloud Messaging and Amazon Device Messaging) as well as broadcasting messages to subscribed devices (using topics) instead of targeting individual devices.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Romote: Now with a Sleep Timer]]></title>
    <link href="https://blog.seancarpenter.net/2013/12/18/romote-now-with-a-sleep-timer/"/>
    <updated>2013-12-18T13:04:00-05:00</updated>
    <id>https://blog.seancarpenter.net/2013/12/18/romote-now-with-a-sleep-timer</id>
    <content type="html"><![CDATA[<p><strong>UPDATE 12/21/2015</strong>
<a href="http://blog.seancarpenter.net/2015/12/21/ro-to-sleep-a-new-roku-sleep-timer/">I&#8217;ve released</a> a new stand-alone Roku sleep timer named <a href="https://itunes.apple.com/us/app/ro-to-sleep-roku-streaming/id1067642181?ls=1&amp;mt=8&amp;at=10l5G3&amp;ct=blog">Ro To Sleep</a>. You can read the <a href="http://blog.seancarpenter.net/2015/12/21/ro-to-sleep-a-new-roku-sleep-timer/">announcement</a> for all of the details, but the short version is that Ro To Sleep is focused on just sleep timer functionality.</p>

<p><strong>END UPDATE</strong></p>

<p>I&#8217;ve been using two <a href="http://www.roku.com">Roku</a> streaming players for just over two years now. Channels are added regularly and the addition of <a href="http://www.roku.com/channels/#!details/34376/watchespn">WatchESPN</a> recently added some sports - something that&#8217;s noticeably missing from many streaming solutions.</p>

<!-- more -->


<p>But one thing that the Roku lacks is the ability to set a timer that will cause playback to stop (a sleep timer). Falling asleep in bed while watching the Roku is something that I do a few times a week. The lack of a timer isn&#8217;t so bad if you&#8217;re watching a channel that streams episodes or movies (like <a href="http://www.roku.com/channels/#!details/2285/hulu-plus">Hulu Plus</a> and <a href="http://www.roku.com/channels/#!details/12/netflix">Netflix</a>) since the playback will eventually end when the end of the current item is reached. But for channels that play a live stream (like WatchESPN), the Roku will happily keep streaming long after you&#8217;ve fallen asleep.</p>

<p>So I decided to do something about the missing timer.</p>

<div class="centered screenshots">
    <a href="http://itunes.apple.com/us/app/romote/id488604877?ls=1&amp;mt=8&amp;at=10l5G3&amp;ct=blog" class="plain-image">
        <img src="http://pictures.seancarpenter.net/blog/romote.png" title="Romote" alt="Romote">
    </a>
</div>


<p>The latest version of <a href="http://itunes.apple.com/us/app/romote/id488604877?ls=1&amp;mt=8&amp;at=10l5G3&amp;ct=blog">Romote</a> now includes a sleep timer for your Roku! Set the timer before you fall asleep and Romote will send your Roku to the home screen (thereby stopping playback) at the time you choose. There are a few caveats:</p>

<ol class="indented-list">
    <li>You must be running iOS 7 for the sleep timer to be available.</li>
    <li>You must have an internet connection for the sleep timer to work.</li>
    <li>Romote can&#8217;t control your TV. This means that Romote will stop playback on the Roku but your TV will remain on. If you want to also turn off your TV, you&#8217;ll have to use whatever timer capability is built in to the TV.</li>
</ol>


<p>Head on over to <a href="http://itunes.apple.com/us/app/romote/id488604877?ls=1&amp;mt=8&amp;at=10l5G3&amp;ct=blog">the iTunes store</a> and get your copy of Romote and enjoy falling asleep knowing that your Roku won&#8217;t be playing all night.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[CPOSC 2013 Presentation Notes]]></title>
    <link href="https://blog.seancarpenter.net/2013/10/20/cposc-2013-presentation-notes/"/>
    <updated>2013-10-20T10:05:00-04:00</updated>
    <id>https://blog.seancarpenter.net/2013/10/20/cposc-2013-presentation-notes</id>
    <content type="html"><![CDATA[<p>Thanks to everyone who came out to see my presentation at <a href="http://cposc.org">CPOSC</a> yesterday.</p>

<!-- more -->


<p>I&#8217;ve posted a <a href="http://www.slideshare.net/stcarpenter/beyond-heroku-hosting-your-ra">copy of my slides</a> on SlideShare.  Here&#8217;s a list of resources that I&#8217;ve used in setting up nginx, Unicorn, and Capistrano.</p>

<h3>Sample Project</h3>

<p>Here&#8217;s the <a href="https://github.com/scarpenter/cposc">Github repository</a> for the small example I showed at the end of the presentation.  In the <code>sample_config_files</code> directory there are a few files that are not actually part of the Rails project but instead are config files that would be found on the server:</p>

<ul class="indented-list">
    <li>nginx_site.conf: This is an example of the nginx configuration used to proxy requests to Unicorn</li>
    <li>unicorn_init: I didn&#8217;t talk about this in the presentation, but this is an example of a file that can be placed in <code>/etc/init.d</code> and used to start Unicorn on machine startup</li>
    <li>cposc.conf: This is the project-specific configuration file used by the above <code>unicorn_init</code>.</li>
</ul>


<h3>Unicorn</h3>

<ul class="indented-list">
    <li><a href="http://unicorn.bogomips.org">Unicorn home page</a></li>
    <li><a href="http://sirupsen.com/setting-up-unicorn-with-nginx/">A blog post by Simon Hørup Eskildsen</a> on setting up Unicorn and nginx.  Good general information.</li>
    <li><a href="http://matteodepalo.github.io/blog/2013/03/07/how-i-migrated-from-heroku-to-digital-ocean-with-chef-and-capistrano/">A blog post from Matteo Depalo</a> on migrating from Heroku to Digital Ocean.  This helped inspire me to do this myself.  Matteo&#8217;s post talks about using Chef to set up your server in addition to the Unicorn/nginx/Capistrano combination.  My personal choice is to use <a href="http://www.ansibleworks.com/docs/">Ansible</a> for configuration management.
    <li><a href="https://github.com/blog/517-unicorn">Github&#8217;s post</a> about switching to Unicorn.</li>
    <li><a href="https://github.com/defunkt/unicorn/tree/master/examples">Github&#8217;s &#8220;unofficial&#8221; Unicorn source code mirror</a>. This <code>examples</code> directory has sample configuration files for Unicorn, nginx, and logrotate with lots of comments.</li>
</ul>


<h3>nginx</h3>

<ul class="indented-list">
    <li><a href="http://nginx.org">nginx home page</a></li>
    <li><a href="http://nginx.org/en/docs/">nginx config documentation</a></li>
    <li><a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html">Documentation on the upstream configuration</a> used to reverse proxy to Unicorn.</li>
</ul>


<h3>Capistrano</h3>

<p>Capistrano recently released a new version (3.0) that makes some changes to how Capistrano is configured and runs.  I&#8217;ve only used the 2.x version and that&#8217;s what I covered in my presentation.  The <a href="http://www.capistranorb.com">Capistrano website</a> has information on the new version; I&#8217;ve used the <a href="https://github.com/capistrano/capistrano/wiki/2.x-Getting-Started">Github wiki</a> when setting up version 2.x.</p>

<h3>Hosts</h3>

<p>These are the Linux hosts I mentioned during my presentation; there are certainly a lot more.</p>

<ul class="indented-list">
    <li><a href="http://aws.amazon.com">Amazon AWS</a></li>
    <li><a href="http://www.windowsazure.com">Windows Azure</a></li>
    <li><a href="https://www.digitalocean.com/?refcode=a4c745925e6a">Digital Ocean</a></li>
    <li><a href="https://www.linode.com/?r=fdd2b3b2ca8d34a683ac7b27827b59f8150464b5">Linode</a></li>
</ul>


<h3>Summary</h3>

<p>Thanks to all of the other speakers and the conference organizers for an enjoyable day.  I also had a fun lunch discussion with Scott, Stefan, Samrat, Hector, Jeff, and Nathan (sorry if I missed anyone!).</p>

<p>If you have any questions about my presentation, feel free to reach out on <a href="https://twitter.com/scarpenter">Twitter</a> or by <a href="mailto:sean@seancarpenter.net">email</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Rails SSL Route Generation with nginx and Unicorn]]></title>
    <link href="https://blog.seancarpenter.net/2013/09/02/rails-ssl-route-generation-with-nginx-and-unicorn/"/>
    <updated>2013-09-02T19:26:00-04:00</updated>
    <id>https://blog.seancarpenter.net/2013/09/02/rails-ssl-route-generation-with-nginx-and-unicorn</id>
    <content type="html"><![CDATA[<p>I recently enabled SSL for a Rails 3 site that I&#8217;m working on.  I thought it would be simple since the entire site will be served over SSL (no switching between SSL and non-SSL requests based on the page).</p>

<!-- more -->


<p>Since the entire site will be served over SSL, I configured nginx to do the SSL redirects for me:</p>

<figure class='code'><figcaption><span>nginx.conf  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='nginx'><span class='line'><span class="k">server</span> <span class="p">{</span>
</span><span class='line'>  <span class="kn">listen</span>      <span class="mi">80</span><span class="p">;</span>
</span><span class='line'>  <span class="kn">server_name</span> <span class="s">localhost</span> <span class="s">test.something.com</span><span class="p">;</span>
</span><span class='line'>  <span class="kn">return</span> <span class="mi">301</span> <span class="s">https://test.something.com</span><span class="nv">$request_uri</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now whenever a non-SSL request comes in, nginx will redirect to the same path using SSL.  My SSL server configuration is:</p>

<figure class='code'><figcaption><span>nginx.conf  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='nginx'><span class='line'><span class="k">server</span> <span class="p">{</span>
</span><span class='line'>  <span class="kn">listen</span>      <span class="mi">443</span><span class="p">;</span>
</span><span class='line'>  <span class="kn">ssl</span>         <span class="no">on</span><span class="p">;</span>
</span><span class='line'>  <span class="kn">ssl_certificate</span>     <span class="s">/path/to/crt.crt</span><span class="p">;</span>
</span><span class='line'>  <span class="kn">ssl_certificate_key</span> <span class="s">/path/to/private.key</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="kn">root</span>        <span class="s">/var/www/something/current/public</span><span class="p">;</span>
</span><span class='line'>  <span class="kn">index</span>       <span class="s">index.html</span> <span class="s">index.htm</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="kn">server_name</span> <span class="s">localhost</span> <span class="s">test.something.com</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="kn">try_files</span>   <span class="nv">$uri/index.html</span> <span class="nv">$uri.html</span> <span class="nv">$uri</span> <span class="s">@app</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="kn">location</span> <span class="s">@app</span> <span class="p">{</span>
</span><span class='line'>      <span class="kn">proxy_set_header</span>    <span class="s">X-Forwarded-For</span> <span class="nv">$proxy_add_x_forwarded_for</span><span class="p">;</span>
</span><span class='line'>      <span class="kn">proxy_set_header</span>    <span class="s">Host</span> <span class="nv">$http_host</span><span class="p">;</span>
</span><span class='line'>      <span class="kn">proxy_redirect</span>      <span class="no">off</span><span class="p">;</span>
</span><span class='line'>      <span class="kn">proxy_pass</span>          <span class="s">http://unicorn_something_server</span><span class="p">;</span> <span class="c1"># proxy to a Unicorn upstream configured earlier in the file</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is just the same configuration I previously had (before adding SSL) with the <code>listen</code> directive changed to <code>443</code> and the <code>ssl</code> directives added.</p>

<p>After making these changes and restarting nginx, everything seemed to be working correctly.  Any requests to the non-SSL site were redirected with a <code>301</code> response code as expected.</p>

<p>After a day or so I noticed that URLs being generated by Rails were not using the https scheme.  I originally noticed it with named routes like so:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># In routes.rb</span>
</span><span class='line'><span class="n">get</span> <span class="s2">&quot;dashboard&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;dashboard#index&quot;</span><span class="p">,</span> <span class="n">as</span><span class="p">:</span> <span class="s2">&quot;dashboard&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># In a controller</span>
</span><span class='line'><span class="k">def</span> <span class="nf">create</span>
</span><span class='line'>  <span class="c1"># create something</span>
</span><span class='line'>  <span class="n">redirect_to</span> <span class="n">dashboard_url</span><span class="p">,</span> <span class="n">alert</span><span class="p">:</span> <span class="s2">&quot;Creation successful&quot;</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># The generated route from redirect_to would be &quot;http://test.something.com/dashboard&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Anywhere Rails was generating a full URL, the non-SSL version was being generated.  It took me a bit to notice this since in most places I was using the <code>_path</code> version of the named routes which generates just a relative path.  So on a page that was served over SSL, those relative paths of course led to SSL pages.  I should note that the site continued to &#8220;work&#8221; since the generated non-SSL URL was then redirected to the SSL version by nginx, but I definitely did not want to continue to generate extra requests (it also caused a problem with some URLs when accessed via <a href="http://jquerymobile.com">jQuery Mobile</a>).</p>

<p>It took quite a lot of searching to finally find the answer; most of the things written about Rails and SSL are in relation to either 1) having Rails do the SSL redirection using something like <code>config.force_ssl = true</code> or 2) managing a site with some pages served over SSL and some not.  The few references I found mentioned Rails using whatever scheme was in use by the current page when generating URLs (which intuitively made sense to me since it got the host name correct).</p>

<p>I finally ended up debugging in to the Rails source to see how it makes the decision on what scheme to use when generating URLs.  After a few layers, it comes down to this code in Rack:</p>

<figure class='code'><figcaption><span>request.rb </span><a href='https://github.com/rack/rack/blob/rack-1.4/lib/rack/request.rb#L70-86'>source </a></figcaption> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">scheme</span>
</span><span class='line'>  <span class="k">if</span> <span class="vi">@env</span><span class="o">[</span><span class="s1">&#39;HTTPS&#39;</span><span class="o">]</span> <span class="o">==</span> <span class="s1">&#39;on&#39;</span>
</span><span class='line'>    <span class="s1">&#39;https&#39;</span>
</span><span class='line'>  <span class="k">elsif</span> <span class="vi">@env</span><span class="o">[</span><span class="s1">&#39;HTTP_X_FORWARDED_SSL&#39;</span><span class="o">]</span> <span class="o">==</span> <span class="s1">&#39;on&#39;</span>
</span><span class='line'>    <span class="s1">&#39;https&#39;</span>
</span><span class='line'>  <span class="k">elsif</span> <span class="vi">@env</span><span class="o">[</span><span class="s1">&#39;HTTP_X_FORWARDED_SCHEME&#39;</span><span class="o">]</span>
</span><span class='line'>    <span class="vi">@env</span><span class="o">[</span><span class="s1">&#39;HTTP_X_FORWARDED_SCHEME&#39;</span><span class="o">]</span>
</span><span class='line'>  <span class="k">elsif</span> <span class="vi">@env</span><span class="o">[</span><span class="s1">&#39;HTTP_X_FORWARDED_PROTO&#39;</span><span class="o">]</span>
</span><span class='line'>    <span class="vi">@env</span><span class="o">[</span><span class="s1">&#39;HTTP_X_FORWARDED_PROTO&#39;</span><span class="o">].</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;,&#39;</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
</span><span class='line'>  <span class="k">else</span>
</span><span class='line'>    <span class="vi">@env</span><span class="o">[</span><span class="s2">&quot;rack.url_scheme&quot;</span><span class="o">]</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="k">def</span> <span class="nf">ssl?</span>
</span><span class='line'>  <span class="n">scheme</span> <span class="o">==</span> <span class="s1">&#39;https&#39;</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Rails uses the <code>ssl?</code> method to determine what scheme to use in generated URLs.  When I debugged my site running under SSL, none of the env variables were set, causing Rails to treat the request as if it came in over regular http.</p>

<p>The solution turns out to be simple (as they often are when you can track down the root cause).  Add an extra header in the <code>location</code> configuration in nginx:</p>

<figure class='code'><figcaption><span>nginx.conf  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='nginx'><span class='line'><span class="k">location</span> <span class="s">@app</span> <span class="p">{</span>
</span><span class='line'>  <span class="kn">proxy_set_header</span>    <span class="s">X-Forwarded-For</span> <span class="nv">$proxy_add_x_forwarded_for</span><span class="p">;</span>
</span><span class='line'>  <span class="kn">proxy_set_header</span>    <span class="s">X-Forwarded-Proto</span> <span class="s">https</span><span class="p">;</span> <span class="c1"># New header for SSL</span>
</span><span class='line'>  <span class="kn">proxy_set_header</span>    <span class="s">Host</span> <span class="nv">$http_host</span><span class="p">;</span>
</span><span class='line'>  <span class="kn">proxy_redirect</span>      <span class="no">off</span><span class="p">;</span>
</span><span class='line'>  <span class="kn">proxy_pass</span>          <span class="s">http://unicorn_something_server</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>After adding that single line and restarting nginx, Rails is generating URLs using https instead of http.  In hindsight, it makes sense that Rails was not seeing the right scheme since the SSL is being terminated at nginx, but it never occurred to me that that&#8217;s what might be happening.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Transferring an iOS App]]></title>
    <link href="https://blog.seancarpenter.net/2013/06/13/transferring-an-ios-app/"/>
    <updated>2013-06-13T09:36:00-04:00</updated>
    <id>https://blog.seancarpenter.net/2013/06/13/transferring-an-ios-app</id>
    <content type="html"><![CDATA[<p>Apple recently gave developers the ability to transfer ownership of apps in the App Store.  While this certainly helps people who are selling their app to another developer, it&#8217;s immediately useful to me to solve a problem I&#8217;ve had for about a year now.</p>

<!-- more -->


<p>When I developed my first iOS application (<a href="http://itunes.apple.com/us/app/easy-pitch-counter/id463372172?ls=1&amp;mt=8&amp;partnerId=30&amp;siteID=GedyEx6hBKQ">Easy Pitch Counter</a>) I signed up for an individual iOS developer account.  Later when my wife and I started <a href="http://www.cleverarmadillo.com">our company</a>, I signed up for a company/organization iOS developer account so that we could keep company-related revenue/paperwork/etc. separate.</p>

<p>At the time, Apple didn&#8217;t allow you to transfer apps between developers, so I was stuck leaving my original two apps under my personal account while new apps went under the company account.  Now that transfer is enabled, I moved all of my apps to the company account.  The process is quite straightforward.</p>

<h2>Starting a Transfer</h2>

<p>The first step is to log in to <a href="https://itunesconnect.apple.com">iTunes Connect</a> using the account that currently houses the application to be transferred.  Head to the app details page and click the &#8220;Transfer App&#8221; button.  This brings you to a summary page that lists all of the requirements to enable app transfer as well as whether or not the current app meets them.</p>

<div class="centered screenshots">
    <img src="http://pictures.seancarpenter.net/blog/transfer_criteria.png" title="Criteria" alt="Criteria">
</div>


<p>The next thing you need is the information for the developer you&#8217;ll be transferring the app to.  The recipient&#8217;s Apple ID is the easy part, but you&#8217;ll also need the recipient&#8217;s team ID.  You can get this value by logging into the <a href="https://developer.apple.com/ios">iOS Dev Center</a> using the account that will receive the transferred application.  Then proceed to the <a href="https://developer.apple.com/membercenter/index.action">Member Center</a> and click the organization name near the top of the page.  This will display the account&#8217;s profile, where you can find the necessary team ID.</p>

<div class="centered screenshots">
    <img src="http://pictures.seancarpenter.net/blog/transfer_team_id.png" title="Team ID" alt="Team ID">
</div>


<p>After entering the recipient information, you&#8217;re presented with a transfer agreement that you must agree to.  Once you agree, the work is done for the account initiating the transfer.  The app detail page for this app will now display a banner indicating that a transfer has been initiated:</p>

<div class="centered screenshots">
    <img src="http://pictures.seancarpenter.net/blog/transfer_initiated.png" title="Transfer Initiated" alt="Transfer Initiated">
</div>


<h2>Accepting the Transfer</h2>

<p>The next steps relate to accepting the inbound transfer using the destination account in iTunes Connect.  Once you log in using the destination account, head to the &#8220;Contracts, Tax, and Banking&#8221; section to view any inbound transfers.</p>

<p>Select the pending transfer to see the incoming transfer agreement.  You&#8217;re also presented with the opportunity to update some of the app&#8217;s metadata (the items I saw were the support and marketing URLs and the app review contact info).  After filling in the metadata and accepting the agreement the actual transfer process is started.</p>

<p>Apple says it may take up to 3 hours for the transfer to complete (or up to 2 days in some cases) but both apps I transferred were completed in a matter of minutes.</p>

<p>This new ability to transfer apps may not seem like a big deal if you&#8217;re not selling any of your apps but having one active iOS developer account simplifies things for me.  In addition to the financial/paperwork aspect, having only one set of certificates/provisioning profiles/etc. is a big win for me.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Using Haml from the Command Line]]></title>
    <link href="https://blog.seancarpenter.net/2013/05/24/using-haml-from-the-command-line/"/>
    <updated>2013-05-24T17:31:00-04:00</updated>
    <id>https://blog.seancarpenter.net/2013/05/24/using-haml-from-the-command-line</id>
    <content type="html"><![CDATA[<p>Occasionally I have the need to generate some static HTML files.  They may be for a static site or just as examples of how something will look.  If the HTML is simple, I don&#8217;t mind typing it out by hand.  But if there&#8217;s more to it, the repetitiveness of HTML tags starts to get to me.  When I&#8217;m doing a <a href="http://www.rubyonrails.org">Rails</a> or <a href="http://www.sinatrarb.com">Sinatra</a> site, I use <a href="http://haml.info">Haml</a> for the HTML.  So I wanted to be able to use Haml for generating static HTML as well.</p>

<!-- more -->


<p>The main entry point to using Haml from a command line is the <a href="https://github.com/haml/haml/blob/master/lib/haml/engine.rb">Haml::Engine</a> class.  The documentation on using Haml directly like this is a little light, so I&#8217;ve created an example using it and made it available <a href="https://github.com/scarpenter/command_line_haml">on Github</a>.</p>

<p>In addition to just generating HTML from a Haml file, I also wanted to use some of the conveniences that are available when using Haml in a web setting.  For me, this meant being able to use a layout file as a &#8220;wrapper&#8221; around content and being able to use partials to pull out repeated code.</p>

<h2>Generation</h2>

<p>The <a href="https://github.com/scarpenter/command_line_haml/blob/master/generate.rb">generate.rb</a> file in my example has a fair number of comments, so I&#8217;ll just hit some of the high points here.</p>

<figure class='code'><figcaption><span>Generator class </span><a href='https://github.com/scarpenter/command_line_haml/blob/master/generate.rb#L52'>source </a></figcaption> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">layout</span> <span class="o">=</span> <span class="no">Haml</span><span class="o">::</span><span class="no">Engine</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">File</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="s2">&quot;./views/layout.haml&quot;</span><span class="p">),</span> <span class="vi">@haml_options</span><span class="p">)</span>
</span><span class='line'><span class="n">c</span> <span class="o">=</span> <span class="no">Context</span><span class="o">.</span><span class="n">new</span> <span class="vi">@example_boolean</span><span class="p">,</span> <span class="n">input_file</span><span class="p">,</span> <span class="vi">@haml_options</span>
</span><span class='line'><span class="n">output</span> <span class="o">=</span> <span class="n">layout</span><span class="o">.</span><span class="n">render</span> <span class="n">c</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">body</span> <span class="o">=</span> <span class="no">Haml</span><span class="o">::</span><span class="no">Engine</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">File</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="s2">&quot;./views/</span><span class="si">#{</span><span class="n">input_file</span><span class="si">}</span><span class="s2">.haml&quot;</span><span class="p">),</span> <span class="vi">@haml_options</span><span class="p">)</span>
</span><span class='line'>  <span class="n">body</span><span class="o">.</span><span class="n">render</span> <span class="n">c</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>The first step is to instantiate an instance of <code>Haml::Engine</code> pointing to the layout template.  Then we need an instance of the <a href="https://github.com/scarpenter/command_line_haml/blob/master/generate.rb#L9"><code>Context</code></a> class to provide data to the templates as well as functions that can be called from within the templates.  Next is a call to <code>render</code> on the engine instance.  We pass in the context object and a block - the block will be called when a <code>yield</code> statement is encountered in the layout template.  This is the core of what enables the use of a layout.</p>

<p>Inside the render block, a new <code>Haml::Engine</code> instance is instantiated pointing to the &#8220;main&#8221; template being rendered.  Then it&#8217;s just a call to <code>render</code> on that instance, passing along the same <code>Context</code> instance.</p>

<h2>Partials</h2>

<p>A quick word about the way I&#8217;m using partials.  I wanted the ability to render common markup on multiple pages (or render page-specific markup in the layout); the same way you would use partials on the web.</p>

<figure class='code'><figcaption><span>Context class </span><a href='https://github.com/scarpenter/command_line_haml/blob/master/generate.rb#L9'>source </a></figcaption> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">render_partial</span><span class="p">(</span><span class="n">file_name</span><span class="p">)</span>
</span><span class='line'>  <span class="n">file_to_render</span> <span class="o">=</span> <span class="s2">&quot;./views/partials/</span><span class="si">#{</span><span class="n">file_name</span><span class="o">.</span><span class="n">to_s</span><span class="si">}</span><span class="s2">.haml&quot;</span>
</span><span class='line'>  <span class="k">if</span> <span class="vi">@scope</span>
</span><span class='line'>    <span class="n">scope_file</span> <span class="o">=</span> <span class="s2">&quot;./views/partials/</span><span class="si">#{</span><span class="vi">@scope</span><span class="o">.</span><span class="n">to_s</span><span class="si">}</span><span class="s2">_</span><span class="si">#{</span><span class="n">file_name</span><span class="o">.</span><span class="n">to_s</span><span class="si">}</span><span class="s2">.haml&quot;</span>
</span><span class='line'>    <span class="n">file_to_render</span> <span class="o">=</span> <span class="n">scope_file</span> <span class="k">if</span> <span class="no">File</span><span class="o">.</span><span class="n">exists?</span> <span class="n">scope_file</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>  <span class="k">if</span> <span class="no">File</span><span class="o">.</span><span class="n">exists?</span> <span class="n">file_to_render</span>
</span><span class='line'>    <span class="n">partial</span> <span class="o">=</span> <span class="no">Haml</span><span class="o">::</span><span class="no">Engine</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">File</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">file_to_render</span><span class="p">),</span> <span class="vi">@options</span><span class="p">)</span>
</span><span class='line'>    <span class="n">partial</span><span class="o">.</span><span class="n">render</span>
</span><span class='line'>  <span class="k">else</span>
</span><span class='line'>    <span class="kp">nil</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>The implementation here is pretty simple and uses just a few conventions.  Partials live in the <code>partials</code> subfolder of the <code>views</code> folder.  The default filename for a partial is just the name of the partial.  We also check for a file prefixed with the name of the enclosing template and use that if found.  That allows us to use different content depending on the &#8220;main&#8221; template that&#8217;s being rendered (check out the <a href="https://github.com/scarpenter/command_line_haml/tree/master/views/partials">&#8220;title&#8221;</a> partials in the example).  If neither the template-specific nor default partial is found, <code>nil</code> is returned and nothing is rendered in the enclosing template.</p>

<figure class='code'><figcaption><span>Layout</span><a href='https://github.com/scarpenter/command_line_haml/blob/master/views/layout.haml'>source </a></figcaption> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='haml'><span class='line'><span class="nn">!!!</span>
</span><span class='line'><span class="nt">%html</span>
</span><span class='line'>  <span class="nt">%head</span>
</span><span class='line'>    <span class="nt">%title</span>
</span><span class='line'>      <span class="p">=</span><span class="n">render_partial</span> <span class="ss">:title</span>
</span></code></pre></td></tr></table></div></figure>


<p>Calling the partials from a template is straightforward.  One thing to note is that the name of the function (<code>render_partial</code>) is arbitrary - as long as the function exists on the <code>Context</code> object that get passed to the <code>render</code> method it can be called from within a template.</p>

<p><a href="https://github.com/scarpenter/command_line_haml">My example</a> certainly doesn&#8217;t cover everything that could be done using Haml from the command line.  But hopefully it&#8217;s enough of a start to give you some ideas.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Announcing Armadillo Group Text]]></title>
    <link href="https://blog.seancarpenter.net/2013/05/07/announcing-armadillo-group-text/"/>
    <updated>2013-05-07T19:44:00-04:00</updated>
    <id>https://blog.seancarpenter.net/2013/05/07/announcing-armadillo-group-text</id>
    <content type="html"><![CDATA[<p>The company that I run with my wife (<a href="http://www.cleverarmadillo.com">Clever Armadillo LLC</a>) just released a new service, <a href="http://www.sendagrouptext.com">Armadillo Group Text</a>.</p>

<!-- more -->




<div class="centered screenshots">
    <a href="http://www.sendagrouptext.com" class="plain-image">
    <img src="http://pictures.seancarpenter.net/blog/armadillo_group_text.png" title="'Armadillo Group Text', 'Armadillo Group Text'" >
    </a>
</div>


<p>The purpose of Armadillo Group Text is to allow organizers of small groups to send text announcements to their members.  It&#8217;s ideal for coaches to notify their players of changes to a game or for a business association&#8217;s director to let members know that a meeting has been moved.  Any group that needs to notify members in a timely fashion can benefit from using Armadillo Group Text.</p>

<p>This is my first time using <a href="http://twilio.com">Twilio</a> and it&#8217;s been a joy so far.  The API is simple to use (especially with the help of the <a href="https://github.com/twilio/twilio-ruby">twilio-ruby</a> gem) and has been solid.  The ease of use has me wondering what kind of project I could do to utilize their voice services.</p>

<p>If you need to send a message to a group, give <a href="http://www.sendagrouptext.com">Armadillo Group Text</a> a try.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[App Store Pricing and Entitlement]]></title>
    <link href="https://blog.seancarpenter.net/2013/04/11/app-store-pricing-and-entitlement/"/>
    <updated>2013-04-11T18:20:00-04:00</updated>
    <id>https://blog.seancarpenter.net/2013/04/11/app-store-pricing-and-entitlement</id>
    <content type="html"><![CDATA[<p><a href="http://lexfriedman.com/">Lex Friedman</a> recently wrote an article at MacWorld titled &#8220;<a href="http://www.macworld.com/article/2032847/a-5-app-isnt-expensive-customers-need-to-help-fix-the-app-store-economy.html">A $5 app isn&#8217;t expensive: Customers need to help fix the App Store economy</a>&#8221; discussing pricing and the race to the bottom on the App Store.  If you haven&#8217;t read it, I highly recommend it.</p>

<!-- more -->


<p>I wholeheartedly agree with the points Lex makes in his article.  The pressure to price an app cheaply is real.  This is detrimental to the health of the App Store since the lower prices make it more and more difficult for professional developers to make a living selling apps.</p>

<p>The other thing I&#8217;ve noticed is a sense of entitlement on the part of app buyers even when they&#8217;ve purchased an inexpensive app.  I have no problem with and will gladly support an app that I&#8217;ve written; the part that bothers me is the expectation on the part of the user of instant, in-depth support on something they&#8217;ve paid a dollar for.  It&#8217;s unfortunate but true that the $0.70 I receive from each purchase does not account for very much support time (even using the low rate of $50/hr as an example, $0.70 only buys 50 seconds of support).</p>

<p>Here&#8217;s a real world example: My <a href="http://itunes.apple.com/us/app/romote/id488604877?ls=1&amp;mt=8&amp;partnerId=30&amp;siteID=GedyEx6hBKQ">Romote</a> app currently sells for $0.99.  It needs to communicate with your Roku device via your home network.  It attemps to auto-detect any Rokus you have, but this is a hit-or-miss proposition since many times the Roku devices will not respond to detection requests.  You can input the IP address of your Roku manually, but of course that means you need to find out what it is.  In addition, the variety of setups involved in users&#8217; home networks complicates matters.</p>

<p>Taking all of this together, it&#8217;s not surprising that I receive regular requests for help with Romote.  I&#8217;m happy to provide whatever help I can, which usually involves offering some suggestions around auto-detection and determining a Roku&#8217;s IP address.  But some people aren&#8217;t interested in even giving me a chance:</p>

<blockquote><p>Please respond I spent $ and would like results</p><footer><strong>A Romote User</strong> <cite>3/26/13 8:08 PM</cite></footer></blockquote>


<blockquote><p>don&#8217;t charge my account for that$$$ this app stinks as far as working on my roku. Your services did not work for me so I will not pay.</p><footer><strong>The Same User</strong> <cite>3/26/13 8:16 PM</cite></footer></blockquote>


<p>So since I didn&#8217;t respond within 8 minutes, I have no chance to respond at all.  I understand that it&#8217;s frustrating when an app doesn&#8217;t work immediately, but I do take pride in my work and use the app regularly myself so I know that it <em>does</em> work.</p>

<p>Occasionally I wonder if raising the price of the app would cut down on these types of angry requests.  Having fewer customers would also allow me to spend more time helping those that need it.  Of course, it may also reduce my sales to nothing since there are free competitors in the App Store.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Custom iOS Alert Dialogs]]></title>
    <link href="https://blog.seancarpenter.net/2013/03/30/custom-ios-alert-dialogs/"/>
    <updated>2013-03-30T19:48:00-04:00</updated>
    <id>https://blog.seancarpenter.net/2013/03/30/custom-ios-alert-dialogs</id>
    <content type="html"><![CDATA[<p>Sometimes when developing for iOS it&#8217;s nice to show an alert dialog that has some functionality in addition to that available from the standard <a href="http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAlertView_Class/UIAlertView/UIAlertView.html">UIAlertView</a>.</p>

<!-- more -->


<p>This additional functionality may take the form of including a text field on an alert or showing a progress indicator on the alert dialog.  Or, you may want to make the visual style of the alert match the rest of your app more closely.</p>

<p>A great library for assisting with these kinds of things is <a href="https://github.com/eaigner/CODialog">CODialog</a> by <a href="http://www.chocomoko.com">Erik Aigner</a>.  The <a href="https://github.com/eaigner/CODialog">Github project page</a> has some screenshots showing the kinds of things you can do with only a few lines of code.  The library is easy to include in your project since it consists of a single header file and a single implementation file.</p>

<p>In addition to the out-of-the-box examples, CODialog is easy to customize in other ways as well.  While I was working on <a href="http://itunes.apple.com/us/app/baseball-field-layout/id604707759?ls=1&amp;mt=8&amp;partnerId=30&amp;siteID=GedyEx6hBKQ">Baseball Field Layout</a> I wanted to create alert dialogs that matched the style of the app.  Using CODialog and customizing the implementation slightly, I was able to get alerts that looked just the way I wanted.</p>

<div class="screenshots centered">
    <img src="http://pictures.seancarpenter.net/blog/field_layout_alert.png" title="Baseball Field Layout alert" alt="Baseball Field Layout alert">
    <em>A Baseball Field Layout alert</em>
</div>


<p>This can certainly be taken too far and you should always keep the iOS <a href="http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/MobileHIG/Introduction/Introduction.html">Human Interface Guidelines</a> in mind.  But for adding that missing piece of functionality or adapting the display of alerts, trying something a bit different can have a big effect on your app.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Baseball Field Layout Released]]></title>
    <link href="https://blog.seancarpenter.net/2013/03/15/baseball-field-layout-released/"/>
    <updated>2013-03-15T15:00:00-04:00</updated>
    <id>https://blog.seancarpenter.net/2013/03/15/baseball-field-layout-released</id>
    <content type="html"><![CDATA[<p>It&#8217;s spring (or nearly so anyway) and that means it&#8217;s time for Little League baseball season to get started.  I have a great time coaching my son&#8217;s team: organizing practices, coming up with lineups, coaching the games.  But one thing that&#8217;s at a premium where I live is fields to practice on.  With a lot of baseball and softball teams there isn&#8217;t much chance to practice on an actual field.  However, there are plenty of open, grassy areas to practice at various schools, parks, etc. - the only problem is the lack of a baseball diamond.</p>

<!-- more -->




<div class="centered screenshots">
    <a href="http://itunes.apple.com/us/app/baseball-field-layout/id604707759?ls=1&amp;mt=8&amp;partnerId=30&amp;siteID=GedyEx6hBKQ" class="plain-image">
        <img src="http://pictures.seancarpenter.net/blog/baseball-field-layout.png" title="Baseball Field Layout" alt="Baseball Field Layout">
    </a>
</div>


<p>I decided to try to make it easier to lay out a basic diamond when practicing at one of these spots. <a href="http://itunes.apple.com/us/app/baseball-field-layout/id604707759?ls=1&amp;mt=8&amp;partnerId=30&amp;siteID=GedyEx6hBKQ">Baseball Field Layout</a> is the result.  To use the app, you just stand where you want home plate to be and let the iPhone&#8217;s GPS record your location.  Then you walk in the direction of the pitcher&#8217;s mound and Baseball Field Layout takes care of the rest, giving you the location of the pitcher&#8217;s mound and all three bases.  Field size is selectable at 60&prime;, 70&prime;, or 90&prime;.</p>

<p>This was also an opportunity to try out some iOS frameworks that I haven&#8217;t used before.  I got to use <a href="http://developer.apple.com/library/ios/#documentation/CoreLocation/Reference/CoreLocation_Framework/_index.html">Core Location</a>, <a href="http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MapKit_Framework_Reference/_index.html">MapKit</a>, <a href="https://developer.apple.com/in-app-purchase/">In-App Purchase</a>, and <a href="https://developer.apple.com/iad/">iAd</a> for the first time.  While In-App Purchase and iAd aren&#8217;t essential to this app, it was a nice way to try them out.</p>

<p>Due to the limits of the accuracy obtainable with the iPhone GPS you should only use this app for practicing or goofing around.</p>

<p>Baseball Field Layout is designed for the iPhone and requires a GPS to get reasonable accuracy.
<a href="http://itunes.apple.com/us/app/baseball-field-layout/id604707759?ls=1&amp;mt=8&amp;partnerId=30&amp;siteID=GedyEx6hBKQ" class="plain-image">
  <img src="http://pictures.seancarpenter.net/blog/app_store.svg" alt="Download on the App Store" width="200px" />
</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Importance of App Store Discoverability]]></title>
    <link href="https://blog.seancarpenter.net/2013/03/03/the-importance-of-app-store-discoverability/"/>
    <updated>2013-03-03T11:39:00-05:00</updated>
    <id>https://blog.seancarpenter.net/2013/03/03/the-importance-of-app-store-discoverability</id>
    <content type="html"><![CDATA[<p>Depending on the type of marketing you do for your app, being discoverable in the App Store can have a big impact on sales.</p>

<!-- more -->


<p>One of my apps (<a href="http://itunes.apple.com/us/app/romote/id488604877?ls=1&amp;mt=8&amp;partnerId=30&amp;siteID=GedyEx6hBKQ">Romote</a>) is a WiFi remote for <a href="http://www.roku.com">Roku 2</a> streaming devices.  I wrote this app mostly for my family&#8217;s use and only put it in the App Store since I already had an iOS developer account.  Much to my surprise, the app has been a consistent seller at $0.99 (with no outside promotion) even against free competition (there are a few features that differentiate it from its competitors like correct handling of dication in search fields and an iPad optimized layout).  While the volume of the sales were nothing special, they were consistent - at least until they disappeared entirely.</p>

<div class="centered screenshots">
    <img src="http://pictures.seancarpenter.net/blog/RomoteSales.png" title="Romote sales" alt="Romote sales">
    <em>Sales for Romote</em>
</div>


<p>Around the end of last year (2012) the sales regularly dropped to zero per day and stayed like that for multiple days at a time.  At the time I just assumed that people were no longer interested in paying $0.99 for an app when there were free alternatives.  Then while searching for something in the App Store I happened to try a search for &#8220;roku remote&#8221; and was quite surprised when Romote did not appear at all in the results.  Searching for the app name itself returned the app in approximately the 150<sup>th</sup> position, behind such apps as &#8220;Fart Studio - Revolutionary New Farting Surface!&#8221; and &#8220;NASA Earth as Art&#8221;, as well as several of its competitors.</p>

<p>I contacted Apple developer support about the problem and received a predictably vague response about many factors affecting an app&#8217;s search ranking.  While I understand the need for circumspection in these matters to prevent gaming and abuse I was frustrated that my app was not appearing for what I considered very relevant searches.  Whether as a result of this interaction or just via an update to the search ranking algorithm, Romote soon began appearing in results again and the graph above clearly shows the impact on sales.</p>

<p>I think this illustrates a problem for apps that aren&#8217;t receiving promotion outside the App Store (via reviews, blogs, etc.).  The discoverability of the app in the store will greatly impact its sales - this is even more true with the iOS 6 App Store redesign that shows fewer search results at a time.  The part that is a problem is the fact that you have almost no recourse when this occurs.  <a href="http://journal.darkskyapp.com/2012/app-store-search-optimization/">Adjusting</a> <a href="http://blog.tapstream.com/post/24542193450/on-naming-apps">app names</a> and keywords in an attempt to appear in results for truly relevant searches is a Sisyphean task.  This is analogous to Google controlling the majority of search traffic on the web (and with the same games being played by unscrupulous players) - if your product/site isn&#8217;t returned in Google searches your traffic will suffer.</p>

<p>I don&#8217;t think that there is a real solution to this problem (other than outside promotion) since Apple controls the App Store - that&#8217;s the price of admission for making your app available to the millions of iOS users out there.  But it is something to keep an eye on and be aware of, especially for smaller developers.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[CLLocation Extensions]]></title>
    <link href="https://blog.seancarpenter.net/2013/02/20/cllocation-extensions/"/>
    <updated>2013-02-20T16:51:00-05:00</updated>
    <id>https://blog.seancarpenter.net/2013/02/20/cllocation-extensions</id>
    <content type="html"><![CDATA[<p>I&#8217;ve been working on a new iOS project that uses <a href="http://developer.apple.com/library/ios/#documentation/CoreLocation/Reference/CoreLocation_Framework/_index.html">CoreLocation</a> to determine some points.  While <a href="http://developer.apple.com/library/ios/#documentation/CoreLocation/Reference/CLLocation_Class/CLLocation/CLLocation.html#//apple_ref/doc/uid/TP40007126">CLLocation</a> has a method for determining the distance between two locations (<code>distanceFromLocation:</code>) it doesn&#8217;t have one for doing the opposite: calculating a second location based on a distance (and bearing) from the first.</p>

<!-- More -->


<p>So I added a category on CLLocation that performs this calculation:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="cp">#import &lt;CoreLocation/CoreLocation.h&gt;</span>
</span><span class='line'><span class="cp">#import &quot;CLLocation+LocationExtensions.h&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="n">CLLocation</span><span class="o">*</span> <span class="n">startPoint</span> <span class="o">=</span> <span class="p">[[</span><span class="n">CLLocation</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithLatitude:</span><span class="mf">39.90657</span> <span class="nl">longitude:</span><span class="o">-</span><span class="mf">75.16656</span><span class="p">];</span>
</span><span class='line'><span class="n">CLLocation</span><span class="o">*</span> <span class="n">newPoint</span> <span class="o">=</span> <span class="p">[</span><span class="n">startPoint</span> <span class="nl">locationAtDistance:</span><span class="mi">300</span> <span class="nl">andBearing:</span><span class="mi">180</span><span class="p">];</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;New point: %@&quot;</span><span class="p">,</span> <span class="n">newPoint</span><span class="p">);</span> <span class="c1">// new point is at 39.90387204, -75.16656</span>
</span></code></pre></td></tr></table></div></figure>


<p>The other need I had was to calculate the bearing between two points:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="cp">#import &lt;CoreLocation/CoreLocation.h&gt;</span>
</span><span class='line'><span class="cp">#import &quot;CLLocation+LocationExtensions.h&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="n">CLLocation</span><span class="o">*</span> <span class="n">startPoint</span> <span class="o">=</span> <span class="p">[[</span><span class="n">CLLocation</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithLatitude:</span><span class="mf">39.90657</span> <span class="nl">longitude:</span><span class="o">-</span><span class="mf">75.16656</span><span class="p">];</span>
</span><span class='line'><span class="n">CLLocation</span><span class="o">*</span> <span class="n">endPoint</span> <span class="o">=</span> <span class="p">[[</span><span class="n">CLLocation</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithLatitude:</span><span class="mf">39.90387204</span> <span class="nl">longitude:</span><span class="o">-</span><span class="mf">75.16656</span><span class="p">];</span>
</span><span class='line'><span class="n">CLLocationDegrees</span> <span class="n">bearing</span> <span class="o">=</span> <span class="p">[</span><span class="n">startPoint</span> <span class="nl">bearingTo:</span><span class="n">endPoint</span><span class="p">];</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;Bearing: %f&quot;</span><span class="p">,</span> <span class="n">bearing</span><span class="p">);</span> <span class="c1">// bearing is 180</span>
</span></code></pre></td></tr></table></div></figure>


<p>Both of these calculations use the formulas provided on the page <a href="http://www.movable-type.co.uk/scripts/latlong.html">Calculate distance, bearing and more between Latitude/Longitude points</a>.  This page has lots of information on the formulas and provides them in mathematical notation as well as examples translated to Javascript.</p>

<p>My Objective-C category incorporating these calculations is available from <a href="https://github.com/scarpenter/LocationExtensions">my Github account</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Scraping Web Pages with Ruby]]></title>
    <link href="https://blog.seancarpenter.net/2013/01/26/scraping-web-pages-with-ruby/"/>
    <updated>2013-01-26T17:00:00-05:00</updated>
    <id>https://blog.seancarpenter.net/2013/01/26/scraping-web-pages-with-ruby</id>
    <content type="html"><![CDATA[<p>Ideally every site or service that you wanted to get information from in an automated fashion would provide an API.  But until that becomes a reality, page scraping is a useful technique to have in your toolbox.</p>

<!--more -->


<h2>Basic Scraping</h2>

<p>Basic scraping can be done by simply requesting the page and looking through the returned string for the information you want.  For simple data extraction, that may be all you need.  But if the data you&#8217;re looking for is harder to find, a library that provides some structured ways to access the data is more appropriate.</p>

<p>One such library in Ruby is <a href="http://nokogiri.org">Nokogiri</a>.  Although I usually think of Nokogiri as an XML parser, it also handles HTML.  Grabbing a page and finding some text is a few simple commands away:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s2">&quot;nokogiri&quot;</span>
</span><span class='line'><span class="nb">require</span> <span class="s2">&quot;open-uri&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="n">page</span> <span class="o">=</span> <span class="no">Nokogiri</span><span class="o">::</span><span class="no">HTML</span><span class="p">(</span><span class="nb">open</span><span class="p">(</span><span class="s2">&quot;http://seancarpenter.net&quot;</span><span class="p">))</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># Nokogiri supports CSS-style selectors</span>
</span><span class='line'><span class="n">h2s</span> <span class="o">=</span> <span class="n">page</span><span class="o">.</span><span class="n">css</span><span class="p">(</span><span class="s2">&quot;#left h2&quot;</span><span class="p">)</span>
</span><span class='line'><span class="nb">puts</span> <span class="n">h2s</span><span class="o">.</span><span class="n">length</span> <span class="c1"># outputs &quot;3&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="c1"># And XPath selectors</span>
</span><span class='line'><span class="n">h2s_xpath</span> <span class="o">=</span> <span class="n">page</span><span class="o">.</span><span class="n">xpath</span><span class="p">(</span><span class="s2">&quot;//div[@id=&#39;left&#39;]/h2&quot;</span><span class="p">)</span>
</span><span class='line'><span class="nb">puts</span> <span class="n">h2s_xpath</span><span class="o">.</span><span class="n">length</span> <span class="c1"># outputs &quot;3&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>If reading data is the only thing you need to do, then Nokogiri gets the job done.</p>

<h2>Reading and Sending Data</h2>

<p>Sometimes you may need to send some data in addition to just reading it.  One common situation is needing to log in to a site before being able to read the data you&#8217;re interested in.  In that case, another library comes to the rescue: <a href="http://mechanize.rubyforge.org/">Mechanize</a>.</p>

<p>Mechanize can handle all of the &#8220;bookkeeping&#8221; aspects of logging in: setting and sending cookies, following redirects, etc.  Mechanize also provides methods for dealing with <a href="http://mechanize.rubyforge.org/Mechanize/Page/Link.html">links</a>, <a href="http://mechanize.rubyforge.org/Mechanize/Form.html">forms</a>, and other structural elements of a page.  And when it comes time to extract the data, Mechanize uses Nokogiri under the hood so that you can use the same CSS and XPath selectors that Nokogiri provides.</p>

<p>Mechanize provides some nice <a href="http://mechanize.rubyforge.org/EXAMPLES_rdoc.html">examples</a> in their documentation so I won&#8217;t repeat them here.  Definitely check it out if you need to do any more &#8220;advanced scraping&#8221;.</p>

<p>While someday there may be an API available to get at any data that anyone finds interesting, until then don&#8217;t discount scraping as a viable alternative.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Putting a UISwitch in a UITableViewCell]]></title>
    <link href="https://blog.seancarpenter.net/2013/01/10/putting-a-uiswitch-in-a-uitableviewcell/"/>
    <updated>2013-01-10T17:43:00-05:00</updated>
    <id>https://blog.seancarpenter.net/2013/01/10/putting-a-uiswitch-in-a-uitableviewcell</id>
    <content type="html"><![CDATA[<p>Due to the ubiquitousness    of using UITableViews to display various types of UIs in iOS, many different types of content end up inside UITableViewCells.  One common approach involves putting a <code>UISwitch</code> inside a table cell to represent an on/off setting:</p>

<!-- more -->


<div class="screenshots centered">
    <img src="http://pictures.seancarpenter.net/blog/uiswitch_cell.png" title="UISwitch in a UITableViewCell" alt="UISwitch in a UITableViewCell">
    <em>A UISwitch in a UITableViewCell</em>
</div>


<p>So how do you actually go about making this type of cell?  The method I&#8217;m going to describe here doesn&#8217;t require a custom UITableViewCell subclass so that makes it easy to use in just about any iOS project.</p>

<h2>Configuring a cell to display a UISwitch</h2>

<p>The first step is to configure your table cell to contain a <code>UISwitch</code> and a <code>UILabel</code> (for the description):</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span><span class="p">(</span><span class="n">UITableViewCell</span><span class="o">*</span><span class="p">)</span> <span class="nf">tableView:</span><span class="p">(</span><span class="n">UITableView</span><span class="o">*</span><span class="p">)</span> <span class="n">tableView</span> <span class="nl">cellForRowAtIndexPath:</span><span class="p">(</span><span class="n">NSIndexPath</span><span class="o">*</span><span class="p">)</span> <span class="n">indexPath</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">static</span> <span class="n">NSString</span><span class="o">*</span> <span class="n">cellIdentifier</span> <span class="o">=</span> <span class="s">@&quot;switchCell&quot;</span><span class="p">;</span>
</span><span class='line'>    <span class="n">UITableViewCell</span><span class="o">*</span> <span class="n">cell</span> <span class="o">=</span> <span class="p">[</span><span class="n">tableView</span> <span class="nl">dequeueReusableCellWithIdentifier:</span><span class="n">cellIdentifier</span><span class="p">];</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="n">cell</span> <span class="o">==</span> <span class="nb">nil</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">cell</span> <span class="o">=</span> <span class="p">[[</span><span class="n">UITableViewCell</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithStyle:</span><span class="n">UITableViewCellStyleDefault</span> <span class="nl">reuseIdentifier:</span><span class="n">cellIdentifier</span><span class="p">];</span>
</span><span class='line'>        <span class="n">UISwitch</span><span class="o">*</span> <span class="n">s</span> <span class="o">=</span> <span class="p">[[</span><span class="n">UISwitch</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span><span class='line'>        <span class="n">CGSize</span> <span class="n">switchSize</span> <span class="o">=</span> <span class="p">[</span><span class="n">s</span> <span class="nl">sizeThatFits:</span><span class="n">CGSizeZero</span><span class="p">];</span>
</span><span class='line'>        <span class="n">s</span><span class="p">.</span><span class="n">frame</span> <span class="o">=</span> <span class="n">CGRectMake</span><span class="p">(</span><span class="n">cell</span><span class="p">.</span><span class="n">contentView</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">width</span> <span class="o">-</span> <span class="n">switchSize</span><span class="p">.</span><span class="n">width</span> <span class="o">-</span> <span class="mf">5.0f</span><span class="p">,</span>
</span><span class='line'>                             <span class="p">(</span><span class="n">cell</span><span class="p">.</span><span class="n">contentView</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">height</span> <span class="o">-</span> <span class="n">switchSize</span><span class="p">.</span><span class="n">height</span><span class="p">)</span> <span class="o">/</span> <span class="mf">2.0f</span><span class="p">,</span>
</span><span class='line'>                             <span class="n">switchSize</span><span class="p">.</span><span class="n">width</span><span class="p">,</span>
</span><span class='line'>                             <span class="n">switchSize</span><span class="p">.</span><span class="n">height</span><span class="p">);</span>
</span><span class='line'>        <span class="n">s</span><span class="p">.</span><span class="n">autoresizingMask</span> <span class="o">=</span> <span class="n">UIViewAutoresizingFlexibleLeftMargin</span><span class="p">;</span>
</span><span class='line'>        <span class="n">s</span><span class="p">.</span><span class="n">tag</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span>
</span><span class='line'>        <span class="p">[</span><span class="n">s</span> <span class="nl">addTarget:</span><span class="n">self</span> <span class="nl">action:</span><span class="k">@selector</span><span class="p">(</span><span class="nl">switchChanged:</span><span class="p">)</span> <span class="nl">forControlEvents:</span><span class="n">UIControlEventValueChanged</span><span class="p">];</span>
</span><span class='line'>        <span class="p">[</span><span class="n">cell</span><span class="p">.</span><span class="n">contentView</span> <span class="nl">addSubview:</span><span class="n">s</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>        <span class="n">UILabel</span><span class="o">*</span> <span class="n">l</span> <span class="o">=</span> <span class="p">[[</span><span class="n">UILabel</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
</span><span class='line'>        <span class="n">l</span><span class="p">.</span><span class="n">text</span> <span class="o">=</span> <span class="s">@&quot;Notifications&quot;</span><span class="p">;</span>
</span><span class='line'>        <span class="n">CGRect</span> <span class="n">labelFrame</span> <span class="o">=</span> <span class="n">CGRectInset</span><span class="p">(</span><span class="n">cell</span><span class="p">.</span><span class="n">contentView</span><span class="p">.</span><span class="n">bounds</span><span class="p">,</span> <span class="mf">10.0f</span><span class="p">,</span> <span class="mf">8.0f</span><span class="p">);</span>
</span><span class='line'>        <span class="n">labelFrame</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">width</span> <span class="o">=</span> <span class="n">cell</span><span class="p">.</span><span class="n">contentView</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">width</span> <span class="o">/</span> <span class="mf">2.0f</span><span class="p">;</span>
</span><span class='line'>        <span class="n">l</span><span class="p">.</span><span class="n">font</span> <span class="o">=</span> <span class="p">[</span><span class="n">UIFont</span> <span class="nl">boldSystemFontOfSize:</span><span class="mf">17.0f</span><span class="p">];</span>
</span><span class='line'>        <span class="n">l</span><span class="p">.</span><span class="n">frame</span> <span class="o">=</span> <span class="n">labelFrame</span><span class="p">;</span>
</span><span class='line'>        <span class="n">l</span><span class="p">.</span><span class="n">backgroundColor</span> <span class="o">=</span> <span class="p">[</span><span class="n">UIColor</span> <span class="n">clearColor</span><span class="p">];</span>
</span><span class='line'>        <span class="n">cell</span><span class="p">.</span><span class="n">accessibilityLabel</span> <span class="o">=</span> <span class="s">&quot;Notifications&quot;</span><span class="p">;</span>
</span><span class='line'>        <span class="p">[</span><span class="n">cell</span><span class="p">.</span><span class="n">contentView</span> <span class="nl">addSubview:</span><span class="n">l</span><span class="p">];</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="p">((</span><span class="n">UISwitch</span><span class="o">*</span><span class="p">)[</span><span class="n">cell</span><span class="p">.</span><span class="n">contentView</span> <span class="nl">viewWithTag:</span><span class="mi">100</span><span class="p">]).</span><span class="n">on</span> <span class="o">=</span> <span class="n">value</span><span class="p">;</span> <span class="c1">// &quot;value&quot; is whatever the switch should be set to</span>
</span><span class='line'>    <span class="k">return</span> <span class="n">cell</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This looks like a lot of code, but most of it is related to positioning the label and the switch in the table cell.</p>

<p>First, the switch.  On line 7, we get the size needed to display the switch.  Then the switch&#8217;s frame can be calculated (lines 8 - 11).  The <code>x</code> position of the switch is calculated by subtracting the switch&#8217;s width (plus a little padding) from the cell&#8217;s <code>contentView</code> width.  This places the switch against the right-hand side of the cell (inset by the padding amount).  The <code>y</code> position of the switch is calculated to center the switch vertically in the cell.</p>

<p>The label is a little simpler.  On line 19 <code>CGRectInset</code> is used to give us a <code>CGRect</code> with a horizontal padding of 10 and a vertical padding of 8.  Then the width of the label is shrunk on line 20 to be half the width of the cell.</p>

<p>Once the cell is configured, we set the switch&#8217;s value (finding it via the tag assigned on line 13) and we&#8217;re off to the races.</p>

<h2>Responding to the switch being switched</h2>

<p>Now we have a cell that displays a label and a switch with the switch&#8217;s value set appropriately.  How do we handle the user tapping the switch?  On line 14 in the setup code above, we added an action to be called when the switch&#8217;s value is changed.  We need to implement that action method:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">switchChanged:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">sender</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">UISwitch</span><span class="o">*</span> <span class="n">switcher</span> <span class="o">=</span> <span class="p">(</span><span class="n">UISwitch</span><span class="o">*</span><span class="p">)</span><span class="n">sender</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">BOOL</span> <span class="n">value</span> <span class="o">=</span> <span class="n">switcher</span><span class="p">.</span><span class="n">on</span><span class="p">;</span>
</span><span class='line'>    <span class="c1">// Store the value and/or respond appropriately</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Rounding out the behavior</h2>

<p>There&#8217;s one additional step we can take to improve the cell&#8217;s behavior.  Right now, if the user taps anywhere in the cell that isn&#8217;t the switch, nothing happens.  We should make it so that tapping the cell anywhere (the label, the padding, etc.) triggers the switch.  That can be handled in the table view&#8217;s delegate:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">tableView:</span><span class="p">(</span><span class="n">UITableView</span> <span class="o">*</span><span class="p">)</span><span class="nv">tableView</span> <span class="nf">didSelectRowAtIndexPath:</span><span class="p">(</span><span class="n">NSIndexPath</span> <span class="o">*</span><span class="p">)</span><span class="nv">indexPath</span> <span class="p">{</span>
</span><span class='line'>    <span class="p">[</span><span class="n">tableView</span> <span class="nl">deselectRowAtIndexPath:</span><span class="n">indexPath</span> <span class="nl">animated:</span><span class="n">NO</span><span class="p">];</span>
</span><span class='line'>    <span class="n">UITableViewCell</span><span class="o">*</span> <span class="n">cell</span> <span class="o">=</span> <span class="p">[</span><span class="n">tableView</span> <span class="nl">cellForRowAtIndexPath:</span><span class="n">indexPath</span><span class="p">];</span>
</span><span class='line'>    <span class="n">UISwitch</span><span class="o">*</span> <span class="n">switcher</span> <span class="o">=</span> <span class="p">(</span><span class="n">UISwitch</span><span class="o">*</span><span class="p">)[</span><span class="n">cell</span><span class="p">.</span><span class="n">contentView</span> <span class="nl">viewWithTag:</span><span class="mi">100</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">switcher</span> <span class="nl">setOn:</span><span class="o">!</span><span class="n">switcher</span><span class="p">.</span><span class="n">on</span> <span class="nl">animated:</span><span class="n">YES</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">self</span> <span class="nl">switchChanged:</span><span class="n">switcher</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>First we get a reference to the cell that was tapped, then the switch in that cell.  Line 5 animates toggling of the switch&#8217;s value.  Then we call the same action method that was assigned to the switch to process the value.</p>

<h2>Wrapping up</h2>

<p>There are other ways to include a <code>UISwitch</code> in a <code>UITableViewCell</code>.  One method is to subclass <code>UITableViewCell</code> and implement similar logic to that shown here.  That method is useful for encapsulating the switch and label related code.  If you take that route, you will probably want to create a delegate for your new subclass to allow the consuming code to be notified of switch value changes.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[GetCustomAttributes() and Overridden Properties]]></title>
    <link href="https://blog.seancarpenter.net/2012/12/15/getcustomattributes-and-overridden-properties/"/>
    <updated>2012-12-15T19:42:00-05:00</updated>
    <id>https://blog.seancarpenter.net/2012/12/15/getcustomattributes-and-overridden-properties</id>
    <content type="html"><![CDATA[<p>When using custom attributes in .Net, one of the most common tasks is to query a member for any custom attributes that are applied.  The <a href="http://msdn.microsoft.com/en-us/library/8fek28hz.aspx">MemberInfo</a> class has a <a href="http://msdn.microsoft.com/en-us/library/dwc6ew1d.aspx">GetCustomAttributes</a> method for just this purpose.</p>

<!-- more -->




<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">ExampleAttribute</span> <span class="p">:</span> <span class="n">Attribute</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">ClassWithAttribute</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'><span class="na">    [Example]</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">virtual</span> <span class="kt">string</span> <span class="n">Name</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'><span class="na">    [Example]</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">virtual</span> <span class="kt">int</span> <span class="n">Age</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">public</span> <span class="k">static</span> <span class="k">class</span> <span class="nc">AttributeChecker</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">static</span> <span class="n">IEnumerable</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="n">PropertiesWithAttribute</span><span class="p">(</span><span class="n">Type</span> <span class="n">type</span><span class="p">)</span>
</span><span class='line'>    <span class="p">{</span>
</span><span class='line'>        <span class="n">IList</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="n">propertiesWithAttribute</span> <span class="p">=</span> <span class="k">new</span> <span class="n">List</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;();</span>
</span><span class='line'>        <span class="kt">var</span> <span class="n">properties</span> <span class="p">=</span> <span class="n">type</span><span class="p">.</span><span class="n">GetProperties</span><span class="p">(</span><span class="n">BindingFlags</span><span class="p">.</span><span class="n">Public</span> <span class="p">|</span> <span class="n">BindingFlags</span><span class="p">.</span><span class="n">Instance</span><span class="p">);</span>
</span><span class='line'>        <span class="k">foreach</span><span class="p">(</span><span class="kt">var</span> <span class="n">property</span> <span class="k">in</span> <span class="n">properties</span><span class="p">)</span>
</span><span class='line'>        <span class="p">{</span>
</span><span class='line'>            <span class="kt">var</span> <span class="n">attributes</span> <span class="p">=</span> <span class="n">property</span><span class="p">.</span><span class="n">GetCustomAttributes</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">ExampleAttribute</span><span class="p">),</span> <span class="k">true</span><span class="p">);</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="n">attributes</span><span class="p">.</span><span class="n">Length</span> <span class="p">&gt;</span> <span class="m">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">propertiesWithAttribute</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">property</span><span class="p">.</span><span class="n">Name</span><span class="p">);</span> <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">propertiesWithAttribute</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Somewhere where the presence of the attribute is being checked</span>
</span><span class='line'><span class="kt">var</span> <span class="n">properties</span> <span class="p">=</span> <span class="n">AttributeChecker</span><span class="p">.</span><span class="n">PropertiesWithAttribute</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">ClassWithAttribute</span><span class="p">));</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is fairly straightforward reflection code that loops through all of the public properties on <code>ClassWithAttribute</code> and returns the names of any that have the <code>ExampleAttribute</code> applied.  In the example shown, on line 29 the <code>properties</code> variable will be a list containing the words &#8220;Name&#8221; and &#8220;Age&#8221;.</p>

<p>But what happens if we use a class derived from <code>ClassWithAttribute</code>?</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="k">public</span> <span class="k">class</span> <span class="nc">DerivedClassWithAttribute</span> <span class="p">:</span> <span class="n">ClassWithAttribute</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// Override the &quot;Name&quot; property to supply an additional attribute.</span>
</span><span class='line'><span class="na">    [DefaultValue(&quot;Phil&quot;)]</span>
</span><span class='line'>    <span class="k">public</span> <span class="k">override</span> <span class="kt">string</span> <span class="n">Name</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;}</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">var</span> <span class="n">properties</span> <span class="p">=</span> <span class="n">AttributeChecker</span><span class="p">.</span><span class="n">PropertiesWithAttribute</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">DerivedClassWithAttribute</span><span class="p">));</span>
</span><span class='line'><span class="c1">// What does properties contain?</span>
</span></code></pre></td></tr></table></div></figure>


<p>Perhaps surprisingly, the <code>properties</code> variable on line 7 contains the single word &#8220;Age&#8221;.  This surprised me since I&#8217;m supplying <code>true</code> as the second parameter to <code>GetCustomAttributes()</code> on line 21 of the first example.  When the second parameter is true, the member&#8217;s inheritance chain should be searched for attributes.  So why didn&#8217;t it find the <code>ExampleAttribute</code> declared in <code>ClassWithAttribute</code>?  The answer is in the documentation, although I missed it the first few times I read it (emphasis mine):</p>

<blockquote><p>inherit: true to search this member&#8217;s inheritance chain to find the attributes; otherwise, false. <strong>This parameter is ignored for properties and events; see Remarks</strong>.</p><footer><strong>MSDN</strong> <cite><a href='http://msdn.microsoft.com/en-us/library/dwc6ew1d.aspx'>MemberInfo.GetCustomAttributes</a></cite></footer></blockquote>


<p>The second parameter to <code>GetCustomAttributes()</code> is ignored if the method is being called on a property or an event (we have a property in this case).  Luckily the &#8220;Remarks&#8221; section of the documentation has a solution (emphasis mine):</p>

<blockquote><p>This method ignores the inherit parameter for properties and events. <strong>To search the inheritance chain for attributes on properties and events, use the appropriate overloads of the <a href="http://msdn.microsoft.com/en-us/library/system.attribute.getcustomattributes.aspx">Attribute.GetCustomAttributes</a> method</strong>.</p><footer><strong>MSDN</strong> <cite><a href='http://msdn.microsoft.com/en-us/library/dwc6ew1d.aspx'>MemberInfo.GetCustomAttributes</a></cite></footer></blockquote>


<p>So in this case we can simply replace line 21 in <code>AttributeChecker.PropertiesWithAttribute()</code> with the following:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='csharp'><span class='line'><span class="kt">var</span> <span class="n">attributes</span> <span class="p">=</span> <span class="n">Attribute</span><span class="p">.</span><span class="n">GetCustomAttributes</span><span class="p">(</span><span class="n">property</span><span class="p">,</span> <span class="k">typeof</span><span class="p">(</span><span class="n">ExampleAttribute</span><span class="p">),</span> <span class="k">true</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now running the code for <code>DerivedClassWithAttribute</code> will correctly return both &#8220;Name&#8221; and &#8220;Age&#8221;.  A simple change, but something that tripped me up for a while none the less.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[UIPageControl Doesn't Appear]]></title>
    <link href="https://blog.seancarpenter.net/2012/12/06/uipagecontrol-doesnt-appear/"/>
    <updated>2012-12-06T18:37:00-05:00</updated>
    <id>https://blog.seancarpenter.net/2012/12/06/uipagecontrol-doesnt-appear</id>
    <content type="html"><![CDATA[<p>I had a little trouble with my first use of a <a href="http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIPageControl_Class/Reference/Reference.html">UIPageControl</a>.  I added it to my view in a XIB file and set the &#8220;Tint Color&#8221; and &#8220;Current Page&#8221; properties to dark colors.  Everything looked great in the XIB but when I ran the app, the pager wasn&#8217;t there.</p>

<!-- more -->


<p>A couple of Google searches led to a <a href="http://stackoverflow.com/a/9612497/729">few</a> <a href="http://stackoverflow.com/a/6016125/729">posts</a> mentioning the fact that the pager looks like it&#8217;s invisible when shown on a light background.  This is a consequence of the default colors being variations of white.  I dismissed this as being my issue since I had set the colors to be dark in the XIB and everything looked fine there.</p>

<p>After much messing around with positioning, colors, etc. (everything I could think of) I went back to <a href="http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIPageControl_Class/Reference/Reference.html">Apple&#8217;s documentation</a>.  The <code>currentPageIndicatorTintColor</code> and <code>pageIndicatorTintColor</code> properties are only available in iOS 6.0 and above.  Since I was developing with the iOS 6 SDK, the properties were settable in the XIB.  But I was running the app on an iOS 5.1 device which didn&#8217;t have the properties, so the pager was in fact white.  I solved the problem by setting the pager colors back to the default in the XIB and displaying the pager on a dark background.</p>

<p>Two lessons here: 1) When something doesn&#8217;t seem to be working, it never hurts to give the documentation another look, and 2) It&#8217;s important to test your app on whatever iOS/device versions you&#8217;ll actually be deploying to.  While this particular issue doesn&#8217;t result in a runtime crash, having the pager be invisible to anyone running iOS 5 would not have been a good outcome.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Detecting Multiple Swipe Directions with UISwipeGestureRecognizer]]></title>
    <link href="https://blog.seancarpenter.net/2012/11/28/detecting-multiple-swipe-directions-with-uiswipegesturerecognizer/"/>
    <updated>2012-11-28T17:13:00-05:00</updated>
    <id>https://blog.seancarpenter.net/2012/11/28/detecting-multiple-swipe-directions-with-uiswipegesturerecognizer</id>
    <content type="html"><![CDATA[<p>I recently had the need to use a <a href="http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIGestureRecognizer_Class/Reference/Reference.html">UIGestureRecognizer</a> for the first time in one of my iOS apps.  Specifically, I was interested in recognizing swipe gestures in one of my views so <a href="http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UISwipeGestureRecognizer_Class/Reference/Reference.html">UISwipeGestureRecognizer</a> was the obvious choice.</p>

<!-- more -->


<p>UISwipeGestureRecognizer is easier to configure than some of the more complicated recognizers since there are only two configurable properties: <code>direction</code> and <code>numberOfTouchesRequired</code>.  I was only interested in single touch swipes, so the default value of <code>1</code> was fine for <code>numberOfTouchesRequired</code>.  The <code>direction</code> property consists of a bit flag of <code>UISwipeGestureRecognizerDirection</code> values.  My first attempt was to just include the values for left and right gestures:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="c1">// This may not do what you want...</span>
</span><span class='line'><span class="n">UISwipeGestureRecognizer</span><span class="o">*</span> <span class="n">r</span> <span class="o">=</span> <span class="p">[[</span><span class="n">UISwipeGestureRecognizer</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithTarget:</span><span class="n">self</span> <span class="nl">action:</span><span class="k">@selector</span><span class="p">(</span><span class="nl">swipe:</span><span class="p">)];</span>
</span><span class='line'><span class="n">r</span><span class="p">.</span><span class="n">direction</span> <span class="o">=</span> <span class="n">UISwipeGestureRecognizerDirectionRight</span> <span class="o">|</span> <span class="n">UISwipeGestureRecognizerDirectionLeft</span><span class="p">;</span>
</span><span class='line'><span class="p">[</span><span class="n">self</span> <span class="nl">addGestureRecognizer:</span><span class="n">r</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>This works fine and swipes in both directions are recognized.  The problem comes when it&#8217;s time to figure out which direction was swiped in the delegate method:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">swipe:</span><span class="p">(</span><span class="n">UIGestureRecognizer</span><span class="o">*</span><span class="p">)</span><span class="nv">recognizer</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// Uh, what direction was swiped?</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>There is no way to find out which swipe direction triggered the recognizer when the delegate message arrives.</p>

<p>The solution here is straightforward once you realize the problem: you just need to use two recognizers, each configured for a single direction:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">UISwipeGestureRecognizer</span><span class="o">*</span> <span class="n">right</span> <span class="o">=</span> <span class="p">[[</span><span class="n">UISwipeGestureRecognizer</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithTarget:</span><span class="n">self</span> <span class="nl">action:</span><span class="k">@selector</span><span class="p">(</span><span class="n">swipeRight</span><span class="p">)];</span>
</span><span class='line'><span class="n">right</span><span class="p">.</span><span class="n">direction</span> <span class="o">=</span> <span class="n">UISwipeGestureRecognizerDirectionRight</span><span class="p">;</span>
</span><span class='line'><span class="p">[</span><span class="n">self</span> <span class="nl">addGestureRecognizer:</span><span class="n">right</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'><span class="n">UISwipeGestureRecognizer</span><span class="o">*</span> <span class="n">left</span> <span class="o">=</span> <span class="p">[[</span><span class="n">UISwipeGestureRecognizer</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithTarget:</span><span class="n">self</span> <span class="nl">action:</span><span class="k">@selector</span><span class="p">(</span><span class="n">swipeLeft</span><span class="p">)];</span>
</span><span class='line'><span class="n">left</span><span class="p">.</span><span class="n">direction</span> <span class="o">=</span> <span class="n">UISwipeGestureRecognizerDirectionLeft</span><span class="p">;</span>
</span><span class='line'><span class="p">[</span><span class="n">self</span> <span class="nl">addGestureRecognizer:</span><span class="n">left</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now a different method (<code>swipeRight</code> or <code>swipeLeft</code>) will be called depending on which direction the user swipes.  This makes it easy to take the appropriate action in response.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Windows Phone 8 Makes It Hard To Get Started]]></title>
    <link href="https://blog.seancarpenter.net/2012/11/11/windows-phone-makes-it-hard-to-get-started/"/>
    <updated>2012-11-11T10:25:00-05:00</updated>
    <id>https://blog.seancarpenter.net/2012/11/11/windows-phone-makes-it-hard-to-get-started</id>
    <content type="html"><![CDATA[<p>I decided to give Windows Phone 8 development a shot, enticed by their &#8220;$8 for 8 days&#8221; deal on developer program membership (it&#8217;s normally $99/year).  My idea is to try writing <a href="http://itunes.apple.com/us/app/easy-score-keeper/id570999111?ls=1&amp;mt=8&amp;partnerId=30&amp;siteID=GedyEx6hBKQ">Easy Score Keeper</a> for Windows Phone 8 since I just released it on iOS.  Since I&#8217;ve been a Microsoft developer for 12 years and a .Net developer for about 9 I&#8217;m not worried about coding in C#.</p>

<p>But it turns out that getting started with development is harder than I expected.  First off, I&#8217;m using almost entirely Macs now (even my wife&#8217;s main computer is a MacBook Pro).  I thought I&#8217;d just use a <a href="http://www.parallels.com/products/desktop/">Parallels VM</a> (like I do in my day-to-day work).  Unfortunately, the Windows Phone 8 emulator is actually a Hyper-V virtual machine so that adds some constraints to a development setup:</p>

<!-- more -->


<ol>
<li>Hyper-V support in Windows 8 is <a href="http://blogs.windows.com/windows/b/bloggingwindows/archive/2012/04/16/announcing-the-windows-8-editions.aspx">only available in the Pro edition</a> or higher, so a &#8220;plain&#8221; Windows 8 install already doesn&#8217;t support running the emulator.</li>
<li>Your processor is required to support the relatively new <a href="http://en.wikipedia.org/wiki/Second_Level_Address_Translation">SLAT</a> capability.</li>
</ol>


<p>Since Parallels doesn&#8217;t pass through any processor virtualization support I won&#8217;t be able to do development in a VM (there are <a href="http://communities.vmware.com/message/2141330#2141330">reports</a> of it working in an unsupported way in VMWare Fusion).  My next idea was to use a Windows 7 computer I have around and install Windows 8 in a VHD (per <a href="http://www.hanselman.com/blog/GuideToInstallingAndBootingWindows8DeveloperPreviewOffAVHDVirtualHardDisk.aspx">Scott Hanselman&#8217;s guide</a>).  But the computer I was going to do that on has an Intel Core 2 Quad processor which doesn&#8217;t support SLAT, so that&#8217;s out.</p>

<p>I guess I&#8217;ll end up installing Bootcamp on my newest Mac (which has an Intel Core i5) and doing the development there.  That&#8217;s suboptimal since then I&#8217;ll need to reboot to switch between Windows Phone development and doing anything else on my machine.</p>

<p>This decision on the emulator seems odd considering that Windows Phone 8 is starting from behind in terms of developer adoption.  One way to get some apps in the store is to entice developers from other platforms to write for Windows Phone (either new apps or ports of existing ones).  But many developers (certainly iOS developers but I think most Android developers as well) are not running Windows natively on new hardware which makes the need for hardware supported virtualization cumbersome.  In addition, I know many Windows developers use VMs for development in order to manage separate environments, etc.  So this requirement is a problem for them as well.</p>

<p>The emulator requirements are also a problem if Microsoft is attempting to lure hobbyist developers.  Making a <a href="http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-for-windows-phone">Windows Phone 8 version</a> of Visual Studio Express free is a great way to get people interested (Visual Studio is a very full-featured IDE).  But the requirement for Windows 8 Pro means that basic machines being sold at retail stores won&#8217;t be able to develop Windows 8 Phone apps without an upgrade.  The SLAT requirement also means that only machines purchased in the last 2-3 years (since the release of the Core i3 and i5) are capable of running the emulator.</p>

<p>Obviously iOS development has a high financial bar for entry since you need a Mac; this kind of requirement isn&#8217;t unprecented.  But Apple isn&#8217;t trying to kickstart a new platform at this point.  In addition, a 4 year old MacBook Pro is capable of doing development for iOS 6 so at least you don&#8217;t need to go out and buy a brand new Mac if you have one around.</p>

<p>It&#8217;s probably too late at this point but it would be great if Microsoft could remove the Hyper-V requirement from the Windows Phone 8 emulator.  Making it as easy as possible to develop for their platform can only help in the long run.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Page Specific Javascript With the Rails Asset Pipeline]]></title>
    <link href="https://blog.seancarpenter.net/2012/11/05/page-specific-javascript-with-the-asset-pipeline/"/>
    <updated>2012-11-05T16:37:00-05:00</updated>
    <id>https://blog.seancarpenter.net/2012/11/05/page-specific-javascript-with-the-asset-pipeline</id>
    <content type="html"><![CDATA[<p>Rails&#8217; asset pipeline is a great way to manage your javascript and CSS in a Rails app.  By default it handles pre-processing your files (converting CoffeeScript to javascript and SASS to CSS), concatentating your files into a single file, and generating filenames including hashes of the content.  This reduces the number of HTTP requests necessary to download your files and makes it easy to use HTTP caching on your assets.</p>

<!-- more -->


<p>This works fine by default if you reference all of your javascript files from <code>application.js</code> which serves as a manifest of included files.  In the development environment the files are served individually and un-minified (which is useful for debugging) and in production they are concatenated and minified.  But what do you do if you want to have page (or section)-specific files?</p>

<p>Your first approach might be to just add a new file to the <code>app/assets/javascripts/</code> folder in your project and then reference it from your page:</p>

<div class="centered screenshots">
    <img src="http://pictures.seancarpenter.net/blog/assets_first.png" title="assets directory" alt="assets directory">
    <em>A separate CoffeeScript file</em>
</div>




<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="o">&lt;!--</span> <span class="no">Other</span> <span class="n">header</span><span class="o">-</span><span class="n">type</span> <span class="n">stuff</span> <span class="o">--&gt;</span>
</span><span class='line'><span class="o">&lt;%=</span> <span class="n">javascript_include_tag</span> <span class="s2">&quot;separated_code&quot;</span> <span class="o">%&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>This will work fine in development.  The file will be pre-processed and served separately like all the others and life will be good.  The problem is that this will fail in production if you&#8217;re precompiling your assets (which you should be).  The reason is that only <code>application.js</code> is considered as a manifest during precompilation.  So while <code>separated_code.js.coffee</code> exists in the assets directory it won&#8217;t be compiled and minified for production.</p>

<p>You can add additional manifest files to the list considered during precompilation fairly simply by modifying <code>application.rb</code>.  You can modify the <code>precompile</code> property of the assets configuration like so:</p>

<figure class='code'><figcaption><span>application.rb  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">config</span><span class="o">.</span><span class="n">assets</span><span class="o">.</span><span class="n">precompile</span> <span class="o">+=</span> <span class="sx">%w( separated.js )</span>
</span></code></pre></td></tr></table></div></figure>


<p>And add a new manifest file that <code>requires</code> the actual code:</p>

<figure class='code'><figcaption><span>separated.js  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">//= require separated_code</span>
</span></code></pre></td></tr></table></div></figure>


<p>This works but it&#8217;s pretty tedious to add every new file like this.  So instead, I decided to make it more generic.  I modified my <code>precompile</code> property like this:</p>

<figure class='code'><figcaption><span>application.rb  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">config</span><span class="o">.</span><span class="n">assets</span><span class="o">.</span><span class="n">precompile</span> <span class="o">+=</span> <span class="sx">%w( *-bundle.js )</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now I can add as many additional javascript manifest files as I need and include whatever individual files in those that I want to.  I&#8217;ve been using directories to organize the files that go in each bundle.  For example:</p>

<div class="centered screenshots">
    <img src="http://pictures.seancarpenter.net/blog/assets_grouped.png" title="assets directory" alt="assets directory">
    <em>CoffeeScript files for a section</em>
</div>




<figure class='code'><figcaption><span>section1-bundle.js  </span></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">//= require_tree ./section1/</span>
</span></code></pre></td></tr></table></div></figure>


<p>And in my actual page:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="o">&lt;!--</span> <span class="no">Other</span> <span class="n">header</span><span class="o">-</span><span class="n">type</span> <span class="n">stuff</span> <span class="o">--&gt;</span>
</span><span class='line'><span class="o">&lt;%=</span> <span class="n">javascript_include_tag</span> <span class="s2">&quot;section1-bundle&quot;</span> <span class="o">%&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>One additional step is to remove the <code>require_tree</code> directive from <code>application.js</code>.  Otherwise (since <code>require_tree</code> is recursive) the files in each bundle will also be included in the main application file which isn&#8217;t what you want.</p>

<p>Now I&#8217;m free to organize my javascript files in whatever way makes sense but still get the advantages of the asset pipeline (precompliation/concatentation/minification).  I&#8217;ve done a similar thing with my CSS files (although I&#8217;ve found there&#8217;s less reason to separate my CSS as much as my javascript).</p>

<p>I try to avoid putting anything that is shared into more than one of these bundles.  Placing the same file in more than one bundle will result in the contents of that file being downloaded more than once since it will be concatenated with the rest of the files in each bundle.  So I try to keep shared stuff required from <code>application.js</code>.</p>
]]></content>
  </entry>
  
</feed>
