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

  <title><![CDATA[SHAPE Code Blog]]></title>
  <link href="http://codeblog.shape.dk/atom.xml" rel="self"/>
  <link href="http://codeblog.shape.dk/"/>
  <updated>2015-04-23T10:52:23+02:00</updated>
  <id>http://codeblog.shape.dk/</id>
  <author>
    <name><![CDATA[SHAPE developers]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Introducing SHPKeyboardAwareness - Avoid the iPhone keyboard covering your text fields and views]]></title>
    <link href="http://codeblog.shape.dk/blog/2015/04/23/introducing-shpkeyboardawareness-avoid-the-iphone-keyboard-covering-your-text-fields-and-views/"/>
    <updated>2015-04-23T10:30:00+02:00</updated>
    <id>http://codeblog.shape.dk/blog/2015/04/23/introducing-shpkeyboardawareness-avoid-the-iphone-keyboard-covering-your-text-fields-and-views</id>
    <content type="html"><![CDATA[<p>Nothing ruins a perfectly good day at the office like the iOS keyboard showing up at the bottom half of your screen, covering buttons and text fields. Moving essential UI with the pace of the keyboard to keep it visible is a part of the mechanics of the UI that the user expects to work.</p>

<p>Unfortunately, we can’t take the mechanics of moving UI out of the way of the keyboard for granted. In fact, when they keyboard appears, it’s the developer&rsquo;s job to try to keep up with it and UIKit does not make that task particularly easy.</p>

<p>One hot summer day in the Shape office, we decided that we had enough of fighting the keyboard and we wanted to fix it once and for all.</p>

<p><strong>TL;DR: We are pretty happy with the result and we want you to use it as well. Check out <a href="https://github.com/shapehq/SHPKeyboardAwareness">SHPKeyboardAwareness</a> on GitHub.</strong></p>

<p>Now for the slightly longer version.</p>

<h2>Keeping up with the keyboard</h2>

<p>So how do we deal with the keyboard and move our precious UI out of the way? The <a href="https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html#//apple_ref/doc/uid/TP40009542-CH5-SW7">official documentation</a> has Apple&rsquo;s take.</p>

<p>Assuming you are not using a <code>UITableViewController</code> (which has some support for avoiding the keyboard), here are the basics:</p>

<p>Listen for notifications about when the keyboard appears and disappears.</p>

<figure class='code'><figcaption><span></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>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="c1">// Call this method somewhere in your view controller setup code.</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">registerForKeyboardNotifications</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="p">[[</span><span class="n">NSNotificationCenter</span> <span class="n">defaultCenter</span><span class="p">]</span> <span class="nl">addObserver:</span><span class="n">self</span>
</span><span class='line'>            <span class="nl">selector:</span><span class="k">@selector</span><span class="p">(</span><span class="nl">keyboardWasShown:</span><span class="p">)</span>
</span><span class='line'>            <span class="nl">name:</span><span class="n">UIKeyboardDidShowNotification</span> <span class="nl">object:</span><span class="nb">nil</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>   <span class="p">[[</span><span class="n">NSNotificationCenter</span> <span class="n">defaultCenter</span><span class="p">]</span> <span class="nl">addObserver:</span><span class="n">self</span>
</span><span class='line'>             <span class="nl">selector:</span><span class="k">@selector</span><span class="p">(</span><span class="nl">keyboardWillBeHidden:</span><span class="p">)</span>
</span><span class='line'>             <span class="nl">name:</span><span class="n">UIKeyboardWillHideNotification</span> <span class="nl">object:</span><span class="nb">nil</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Delegate the UITextField and save it in an instance variable when it becomes first responder.</p>

<figure class='code'><figcaption><span></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>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">textFieldDidBeginEditing:</span><span class="p">(</span><span class="n">UITextField</span> <span class="o">*</span><span class="p">)</span><span class="nv">textField</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">activeField</span> <span class="o">=</span> <span class="n">textField</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">textFieldDidEndEditing:</span><span class="p">(</span><span class="n">UITextField</span> <span class="o">*</span><span class="p">)</span><span class="nv">textField</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">activeField</span> <span class="o">=</span> <span class="nb">nil</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>When the keyboard appears, adjust your scroll view (assuming you are using a scroll view) and reset it when the keyboard goes away.</p>

<figure class='code'><figcaption><span></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>
<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>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="c1">// Called when the UIKeyboardDidShowNotification is sent.</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">keyboardWasShown:</span><span class="p">(</span><span class="n">NSNotification</span><span class="o">*</span><span class="p">)</span><span class="nv">aNotification</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">NSDictionary</span><span class="o">*</span> <span class="n">info</span> <span class="o">=</span> <span class="p">[</span><span class="n">aNotification</span> <span class="n">userInfo</span><span class="p">];</span>
</span><span class='line'>    <span class="n">CGSize</span> <span class="n">kbSize</span> <span class="o">=</span> <span class="p">[[</span><span class="n">info</span> <span class="nl">objectForKey:</span><span class="n">UIKeyboardFrameBeginUserInfoKey</span><span class="p">]</span> <span class="n">CGRectValue</span><span class="p">].</span><span class="n">size</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">UIEdgeInsets</span> <span class="n">contentInsets</span> <span class="o">=</span> <span class="n">UIEdgeInsetsMake</span><span class="p">(</span><span class="mf">0.0</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">,</span> <span class="n">kbSize</span><span class="p">.</span><span class="n">height</span><span class="p">,</span> <span class="mf">0.0</span><span class="p">);</span>
</span><span class='line'>    <span class="n">scrollView</span><span class="p">.</span><span class="n">contentInset</span> <span class="o">=</span> <span class="n">contentInsets</span><span class="p">;</span>
</span><span class='line'>    <span class="n">scrollView</span><span class="p">.</span><span class="n">scrollIndicatorInsets</span> <span class="o">=</span> <span class="n">contentInsets</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// If active text field is hidden by keyboard, scroll it so it’s visible</span>
</span><span class='line'>    <span class="c1">// Your app might not need or want this behavior.</span>
</span><span class='line'>    <span class="n">CGRect</span> <span class="n">aRect</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">view</span><span class="p">.</span><span class="n">frame</span><span class="p">;</span>
</span><span class='line'>    <span class="n">aRect</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">kbSize</span><span class="p">.</span><span class="n">height</span><span class="p">;</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">CGRectContainsPoint</span><span class="p">(</span><span class="n">aRect</span><span class="p">,</span> <span class="n">activeField</span><span class="p">.</span><span class="n">frame</span><span class="p">.</span><span class="n">origin</span><span class="p">)</span> <span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">scrollView</span> <span class="nl">scrollRectToVisible:</span><span class="n">activeField</span><span class="p">.</span><span class="n">frame</span> <span class="nl">animated:</span><span class="n">YES</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">// Called when the UIKeyboardWillHideNotification is sent</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">keyboardWillBeHidden:</span><span class="p">(</span><span class="n">NSNotification</span><span class="o">*</span><span class="p">)</span><span class="nv">aNotification</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'>    <span class="n">UIEdgeInsets</span> <span class="n">contentInsets</span> <span class="o">=</span> <span class="n">UIEdgeInsetsZero</span><span class="p">;</span>
</span><span class='line'>    <span class="n">scrollView</span><span class="p">.</span><span class="n">contentInset</span> <span class="o">=</span> <span class="n">contentInsets</span><span class="p">;</span>
</span><span class='line'>    <span class="n">scrollView</span><span class="p">.</span><span class="n">scrollIndicatorInsets</span> <span class="o">=</span> <span class="n">contentInsets</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This code pretty much gets the job done, but has a number of drawbacks:</p>

<ul>
<li>Fragmented code.</li>
<li>Not easily integrated.</li>
<li>Code must be duplicated across view controllers and is not easily encapsulated.</li>
<li>Requires even more fragments if mixed with UITextViews.</li>
<li>Does not consider rotation (keyboard frame is in screen coordinates).</li>
<li>Requires delegation of the input fields which may not always be convenient if the input field belongs to a subview.</li>
</ul>


<h2>Why is this so hard?</h2>

<p>In order to make this work, we need to rely on two distinct events (we use the term text field to denote the input view, but it also covers text view):</p>

<ol>
<li>The text field becoming first responder.</li>
<li>The keyboard-will-appear notification.</li>
</ol>


<p>We need the text field so we can get its frame in the (scroll) view and we need the keyboard notification to know the frame of the keyboard and the animation curve and duration with which it enters the screen so we can move the text field out of the way in the same pace. These are two distinct events and with imperative programming, it gets ugly fast. We need to rely on a different paradigm to solve this in a nice way.</p>

<h2>Enter Reactive Cocoa</h2>

<p>Functional Reactive Programming is all over the place these days and at Shape we have really embraced it using Reactive Cocoa. If you don’t know the framework you should read <a href="https://github.com/ReactiveCocoa/ReactiveCocoa">the documentation</a>. Even if you are not familiar with Reactive Cocoa, you can read on even though there may be some unfamiliar terms.</p>

<p>With Reactive Cocoa we can combine and merge distinct events and use their output as parameters to a function that makes the problem much easier to solve. Here’s how we do it:</p>

<figure class='code'><figcaption><span></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>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="c1">// shpka_rac_notifyUntilDealloc is our own convenience method that returns</span>
</span><span class='line'><span class="c1">// a signal with a notification that completes when the receiver deallocates.</span>
</span><span class='line'><span class="n">RACSignal</span> <span class="o">*</span><span class="n">keyboardSignal</span> <span class="o">=</span> <span class="p">[</span><span class="n">self</span> <span class="nl">shpka_rac_notifyUntilDealloc:</span><span class="n">UIKeyboardWillShowNotification</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// viewSignal is a signal that fires whenever a UITextField or UITextView becomes first responder.</span>
</span><span class='line'><span class="n">RACSignal</span> <span class="o">*</span><span class="n">viewSignal</span> <span class="o">=</span> <span class="p">[</span><span class="n">RACSignal</span> <span class="nl">merge:</span><span class="err">@</span><span class="p">[</span>
</span><span class='line'>  <span class="p">[</span><span class="n">self</span> <span class="nl">shpka_rac_notifyUntilDealloc:</span><span class="n">UITextFieldTextDidBeginEditingNotification</span><span class="p">],</span>
</span><span class='line'>  <span class="p">[</span><span class="n">self</span> <span class="nl">shpka_rac_notifyUntilDealloc:</span><span class="n">UITextViewTextDidBeginEditingNotification</span><span class="p">]]</span>
</span><span class='line'><span class="p">];</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// The two signals above, combined in a ‘zip’, meaning that one of the zipped signals</span>
</span><span class='line'><span class="c1">// will wait for the other before combinedShowSignal is fired.</span>
</span><span class='line'><span class="n">RACSignal</span> <span class="o">*</span><span class="n">combinedShowSignal</span> <span class="o">=</span> <span class="p">[</span><span class="n">RACSignal</span> <span class="nl">zip:</span><span class="err">@</span><span class="p">[</span><span class="n">viewSignal</span><span class="p">,</span><span class="n">keyboardSignal</span><span class="p">]];</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now we have achieved a unification of the two distinct events and merged them into a single event we can work on to achieve keyboard bliss. When fired, <code>combinedShowSignal</code> will send a tuple of two <code>NSNotification</code> objects which we can unwrap and perform the logic necessary to animate the changes to our UI with the keyboard animation. If you want to check out how that is done, please have a look at the <a href="https://github.com/shapehq/SHPKeyboardAwareness">code on GitHub</a>.</p>

<h2>Wrapping it up</h2>

<p>We wanted to solve keyboard avoidance in the general case, encapsulating all the logic needed in a separate module. Also, it was a priority that the solution didn’t impose any design requirements or assumptions when integrating it into our projects. In other words, we wanted a very lean, decoupled and easy to use interface.</p>

<p>We decided on isolating all the code in a category, not on <code>UIView</code> or <code>UIViewController</code> but on <code>NSObject</code> which may sound a bit odd. Read on. The interface comes in two flavors and this is what it looks like:</p>

<p>A Reactive Cocoa based interface:</p>

<figure class='code'><figcaption><span></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='objective-c'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">RACSignal</span> <span class="o">*</span><span class="p">)</span><span class="nf">shp_keyboardAwarenessSignal</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>A traditional interface:</p>

<figure class='code'><figcaption><span></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='objective-c'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">shp_engageKeyboardAwareness</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>So why an NSObject category? Any object that imports the header can call one of these methods and get either a ‘next’ or a callback when the keyboard is about to appear or disappear. So it’s up to you if you want to handle the keyboard from the view controller, a view or some helper object.</p>

<p>The traditional interface requires that the receiver implements a single method defined in the <code>SHPKeyboardAwarenessClient</code> protocol to get the callback. Whenever the signal or callback is fired, a value of the type <code>SHPKeyboardEvent</code> is provided, which is a simple container object, holding all relevant information to move the UI out of the way. It is thus the job of the receiver to decide how to deal with the keyboard event, but all the necessary bits of information is collected and delivered in a nice package.</p>

<p>Here’s an example where SHPKeyboardAwareness is used from a view controller, managing a collection view:</p>

<figure class='code'><figcaption><span></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>
<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>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">viewDidLoad</span> <span class="p">{</span>
</span><span class='line'>    <span class="p">[</span><span class="n">super</span> <span class="n">viewDidLoad</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// Subscribe to keyboard events. The receiver (self) will be automatically unsubscribed when deallocated</span>
</span><span class='line'>    <span class="p">[</span><span class="n">self</span> <span class="n">shp_engageKeyboardAwareness</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">keyboardTriggeredEvent:</span><span class="p">(</span><span class="n">SHPKeyboardEvent</span> <span class="o">*</span><span class="p">)</span><span class="nv">keyboardEvent</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">CGFloat</span> <span class="n">offset</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>    <span class="k">switch</span> <span class="p">(</span><span class="n">keyboardEvent</span><span class="p">.</span><span class="n">keyboardEventType</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">case</span> <span class="nl">SHPKeyboardEventTypeShow:</span>
</span><span class='line'>
</span><span class='line'>            <span class="c1">// Keyboard will appear. Calculate the new offset from the provided offset</span>
</span><span class='line'>            <span class="n">offset</span> <span class="o">=</span> <span class="n">collectionView</span><span class="p">.</span><span class="n">contentOffset</span><span class="p">.</span><span class="n">y</span> <span class="o">-</span> <span class="n">keyboardEvent</span><span class="p">.</span><span class="n">requiredViewOffset</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>            <span class="c1">// Save the current view offset into the event to retrieve it later</span>
</span><span class='line'>            <span class="n">keyboardEvent</span><span class="p">.</span><span class="n">originalOffset</span> <span class="o">=</span> <span class="n">collectionView</span><span class="p">.</span><span class="n">contentOffset</span><span class="p">.</span><span class="n">y</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>            <span class="k">break</span><span class="p">;</span>
</span><span class='line'>        <span class="k">case</span> <span class="nl">SHPKeyboardEventTypeHide:</span>
</span><span class='line'>
</span><span class='line'>            <span class="c1">// Keyboard will hide. Reset view offset to its state before keyboard appeared</span>
</span><span class='line'>            <span class="n">offset</span> <span class="o">=</span> <span class="n">keyboardEvent</span><span class="p">.</span><span class="n">originalOffset</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>            <span class="k">break</span><span class="p">;</span>
</span><span class='line'>        <span class="k">default</span><span class="o">:</span>
</span><span class='line'>            <span class="k">break</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// Animate the offset change with the provided curve and duration</span>
</span><span class='line'>    <span class="p">[</span><span class="n">UIView</span> <span class="nl">animateWithDuration:</span><span class="n">keyboardEvent</span><span class="p">.</span><span class="n">keyboardAnimationDuration</span>
</span><span class='line'>                          <span class="nl">delay:</span><span class="mi">0</span>
</span><span class='line'>                        <span class="nl">options:</span><span class="n">keyboardEvent</span><span class="p">.</span><span class="n">keyboardAnimationOptionCurve</span>
</span><span class='line'>                     <span class="nl">animations:</span><span class="o">^</span><span class="p">{</span>
</span><span class='line'>        <span class="n">self</span><span class="p">.</span><span class="n">collectionView</span><span class="p">.</span><span class="n">contentOffset</span> <span class="o">=</span> <span class="n">CGPointMake</span><span class="p">(</span><span class="n">collectionView</span><span class="p">.</span><span class="n">contentOffset</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">offset</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>                <span class="n">self</span><span class="p">.</span><span class="n">collectionView</span><span class="p">.</span><span class="n">contentInset</span> <span class="o">=</span> <span class="n">UIEdgeInsetsMake</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">event</span><span class="p">.</span><span class="n">keyboardFrame</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">height</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span><span class='line'>        <span class="n">self</span><span class="p">.</span><span class="n">collectionView</span><span class="p">.</span><span class="n">scrollIndicatorInsets</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">collectionView</span><span class="p">.</span><span class="n">contentInset</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span> <span class="nl">completion:</span><span class="nb">nil</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Notice that nowhere do we unsubscribe from keyboard events. When the receiver is deallocated, the subscription is silently cancelled so there is no need to do any house cleaning at any point.</p>

<p>There’s another nice feature you might notice in the code sample above. We can store the original offset in the <code>SHPKeyboardEvent</code> object on the ‘show’ event, so we can read it out and restore the collection view to its former state when the  keyboard disappears. SHPKeyboardAwareness ensures that the same event instance is passed on ‘show’ and ‘hide’ events so that state can be saved and restored.</p>

<h2>One more thing</h2>

<p>SHPKeyboardAwareness has one last trick up its sleeve. In the example presented above, an event will be fired whenever a ‘UITextField’ or ‘UITextView’ will become first responder. There is a way to limit the scope however. When engaging keyboard awareness, you can pass in a view that you want events for. You will then only get keyboard events if the keyboard frame conflicts with the given view. This is useful, if for instance you have a container view with a text field and an action button inside and you want the entire container to clear the keyboard. The interface looks like this:</p>

<p>Reactive Cocoa based:</p>

<figure class='code'><figcaption><span></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='objective-c'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">RACSignal</span> <span class="o">*</span><span class="p">)</span><span class="nf">shp_keyboardAwarenessSignalForView:</span><span class="p">(</span><span class="n">UIView</span> <span class="o">*</span><span class="p">)</span><span class="nv">view</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Traditional:</p>

<figure class='code'><figcaption><span></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='objective-c'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">shp_engageKeyboardAwarenessForView:</span><span class="p">(</span><span class="n">UIView</span> <span class="o">*</span><span class="p">)</span><span class="nv">view</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The result may look like this:</p>

<p><img src="https://raw.githubusercontent.com/shapehq/SHPKeyboardAwareness/master/example.gif" alt="SHPKeyboardAwareness in action" /></p>

<h2>Conclusion</h2>

<p>We really like how this project turned out and we’re very happy to release it to the world. In fact, SHPKeyboardAwareness is the first open source project from <a href="http://shape.dk">Shape</a>. We encourage you to try it out and if you find any bugs or ways of improving it, pull requests are very welcome. <a href="https://github.com/shapehq/SHPKeyboardAwareness">Get SHPKeyboardAwareness here</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Custom SSL certificate with Charles Web Proxy]]></title>
    <link href="http://codeblog.shape.dk/blog/2014/01/06/custom-ssl-certificate-with-charles-web-proxy/"/>
    <updated>2014-01-06T15:00:00+01:00</updated>
    <id>http://codeblog.shape.dk/blog/2014/01/06/custom-ssl-certificate-with-charles-web-proxy</id>
    <content type="html"><![CDATA[<p><em>Update April 2015: The SSL proxy handling in Charles 3.10 has been improved so this guide is no longer necessary. Charles now creates a root SSL certificate on each computer it is running on instead of using the same certificate on all computers. This means that it is no longer necessary to create your own certificate manually.</em></p>

<p><a href="http://www.charlesproxy.com/">Charles Web Proxy</a> is an excellent tool for debugging HTTP requests. It has support for inspecting requests/responses and even more cool features like breakpoints or rewrites. I use it when developing iOS apps that communicate with a server over HTTP but also to figure out how my favorite apps from the App Store works. The <a href="http://www.charlesproxy.com/documentation/">Charles documentation</a> is a good resource for understanding the features in Charles.</p>

<p><img src="http://codeblog.shape.dk/images/proxy.png" alt="Charles Web Proxy acts as the server to the client and as the client to the server." /></p>

<h2>HTTPS</h2>

<p>Support for SSL proxying is built into Charles using man-in-the-middle HTTPS proxy. It is incredibly useful as many apps use HTTPS. Instead of the client seeing the certificate of the server it sees a certificate Charles has signed with its own root certificate. Further Charles communicates with the server using the certificate of the server. In this way the client thinks it is communicating with the server and the server thinks it is communicating with the client, while they are in fact both talking to Charles.</p>

<p>However, since the certificate provided by Charles is not signed by a trusted certificate authority, the client will in most cases reject it. To avoid this you have to add the root certificate of Charles as a trusted certificate on the client. There are both instruction how to do that for <a href="http://www.charlesproxy.com/documentation/using-charles/ssl-certificates/">Mac/PC</a> and <a href="http://www.charlesproxy.com/documentation/faqs/ssl-connections-from-within-iphone-applications/">iPhone</a>.</p>

<h2>Security problem</h2>

<p>Installing the root certificate of Charles as a trusted certificate on your device however introduces security threats. An evil-minded person could simply use an SSL certificate signed with the root certificate of Charles to perform a man-in-the-middle attack on your device, since this certificate and its key is available for everyone to download on the internet.</p>

<h2>Custom SSL certificate</h2>

<p>Luckily Charles supports using your own custom SSL certificate as the root certificate, which you have to create yourselves. This can be done using <code>openssl</code>. You will be asked some information about the certificate. I recommend at least setting <code>Organization Name</code> to something meaningful as for instance <code>Charles Proxy Custom SSL certificate</code>. This makes it easier to find the certificate in Keychain.</p>

<figure class='code'><figcaption><span></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='bash'><span class='line'><span class="nv">$ </span>openssl req -x509 -newkey rsa:1024 -keyout charles.key -out charles.crt -days 3650 -nodes
</span></code></pre></td></tr></table></div></figure>


<p>An X.509 certificate and a private key will be created.
Charles expects a PKCS12 file where these are bundled together. So lets create such a bundle. You will be asked for a password and you must specify one for Charles to accept the bundle. Further every time Charles is launched you will be asked to type in this password. In the end of this post I will show how to avoid this.</p>

<figure class='code'><figcaption><span></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='bash'><span class='line'><span class="nv">$ </span>openssl pkcs12 -export -out charles.pfx -inkey charles.key -in charles.crt
</span><span class='line'>Enter Export Password: &lt;YOUR KEY&gt;
</span><span class='line'>Verifying - Enter Export Password: &lt;YOUR KEY&gt;
</span></code></pre></td></tr></table></div></figure>


<p>Now simply select the <code>charles.pfx</code> file in <code>Proxy Settings</code> <code>SSL</code> <code>Use a Custom CA Certificate</code> in Charles. Notice that Charles only saves the path to the file, so place the file somewhere meaningful.</p>

<p>Remember to install the certificate in keychain by simply opening the <code>charles.crt</code> file. It can be installed in the iOS simulator by dragging the <code>charles.crt</code> into the simulator window and on your iOS device by sending it using email. Remember to delete the old Charles certificate if you had it installed.</p>

<h2>Replace default certificate</h2>

<p>Charles is now using our custom SSL certificate and we can be happy and feel secure. However, if you like me use Charles on a daily basis you will quickly get annoyed by having to provide the password of the PKCS12 bundle every time you launch Charles. My method to avoid this is to trick Charles into thinking that it is using the default Charles CA certificate when it is actually using my custom certificate.</p>

<p>Charles stores the used certificate in a keystore file located in a jar file. The trick is to create a new keystore file with our custom certificate and then replace the file. We use <code>keytool</code> to make the keystore file from the <code>charles.pfx</code> file. The file is protected by a password, and it is important that we use the same password as the keystore file bundled with Charles. A quick inspection of the Charles jar file reveals that this password is expected to be <code>Q6uKCvhD6AmtSNn7rAGxrN8pv9t93</code>.</p>

<figure class='code'><figcaption><span></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>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>keytool -v -importkeystore -srckeystore charles.pfx -srcstoretype PKCS12 -destkeystore keystore -deststoretype JKS
</span><span class='line'>Enter destination keystore password: Q6uKCvhD6AmtSNn7rAGxrN8pv9t93
</span><span class='line'>Re-enter new password: Q6uKCvhD6AmtSNn7rAGxrN8pv9t93
</span><span class='line'>Enter <span class="nb">source </span>keystore password: &lt;YOUR KEY&gt;
</span></code></pre></td></tr></table></div></figure>


<p>This will generate a <code>keystore</code> file. The private key stored is still protected by key provided when it was created. This must be changed as well to the key Charles expects.</p>

<figure class='code'><figcaption><span></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='bash'><span class='line'><span class="nv">$ </span>keytool -alias 1 -keypasswd -new Q6uKCvhD6AmtSNn7rAGxrN8pv9t93 -keystore keystore -storepass Q6uKCvhD6AmtSNn7rAGxrN8pv9t93 -keypass &lt;YOUR KEY&gt;
</span></code></pre></td></tr></table></div></figure>


<p>The last thing to do is to replace the default keystore file with the new generated one, which is located inside the <code>charles.jar</code> file.</p>

<figure class='code'><figcaption><span></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='bash'><span class='line'>jar vfu /Applications/Charles.app/Contents/Resources/Java/charles.jar keystore
</span></code></pre></td></tr></table></div></figure>


<p>Remember to disable <code>Use a Custom CA Certificate</code> in Charles. Charles is now using your custom SSL certificate and you don&rsquo;t have to type in a password every time you launch Charles.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Live editing layout constants using Classy, Masonry and ClassyLiveLayout]]></title>
    <link href="http://codeblog.shape.dk/blog/2013/12/16/live-editing-layout-constants-using-classy/"/>
    <updated>2013-12-16T19:03:00+01:00</updated>
    <id>http://codeblog.shape.dk/blog/2013/12/16/live-editing-layout-constants-using-classy</id>
    <content type="html"><![CDATA[<p>The source code and example project presented in this post are available at <a href="https://github.com/olegam/ClassyLiveLayout">https://github.com/olegam/ClassyLiveLayout</a> and using the CocoaPod <code>ClassyLiveLayout</code>.</p>

<p><img src="http://codeblog.shape.dk/images/ClassyLiveLayout1.gif" alt="Gif showing editing layout constants results in real time layout updates" /></p>

<p>Implementing user interfaces often requires many iterations where you compile your app, launch it in the simulator, navigate to the screen you are working on, check the result and then go back to code and make a change. Then repeat. In many cases this can be a tiresome process. If it takes a long time to compile the app or navigate to the relevant situation I find this particularly frustrating.</p>

<p>I never use nibs or storyboards (for several reasons, but <a href="http://blog.teamtreehouse.com/why-i-dont-use-interface-builder">Sam Soffes sums it up</a> pretty well). In contrast I&rsquo;m a huge fan of <a href="https://github.com/lukaswelte/DCIntrospect-ARC">DCIntrospect</a>, a tool to inspect and tweak view frames directly in the simulator. I use that all the time and only fall back to <a href="http://revealapp.com">Reveal app</a> when there is a more complex case I need to inspect. Using DCIntrospect is convenient because it lets you move and resize views directly in the simulator using the arrow keys. But once you figure out how many pixels you want to move your view you still need to remember that value, make the necessary code change and run the app again to check the result. Wouldn&rsquo;t it be nice if this process could be made easier? I&rsquo;ll show a new approach later in this post after mentioning two essential components that makes this possible.</p>

<h2>Masonry</h2>

<p>I have been using Jonas Budelmann&rsquo;s excellent <a href="https://github.com/cloudkite/Masonry">Masonry</a> DSL for AutoLayout for the last few months. It makes setting up layout constraints very easy and declarative compared to the <a href="https://developer.apple.com/library/Mac/DOCUMENTATION/AppKit/Reference/NSLayoutConstraint_Class/NSLayoutConstraint/NSLayoutConstraint.html">more verbose APIs provided by Apple</a>. Constraining a view to its superview with some padding could look like this using Masonry:</p>

<figure class='code'><figcaption><span></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>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">UIEdgeInsets</span> <span class="n">padding</span> <span class="o">=</span> <span class="n">UIEdgeInsetsMake</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">10</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="p">[</span><span class="n">view1</span> <span class="nl">mas_makeConstraints:</span><span class="o">^</span><span class="p">(</span><span class="n">MASConstraintMaker</span> <span class="o">*</span><span class="n">make</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">make</span><span class="p">.</span><span class="n">top</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="n">superview</span><span class="p">.</span><span class="n">mas_top</span><span class="p">).</span><span class="n">with</span><span class="p">.</span><span class="n">offset</span><span class="p">(</span><span class="n">padding</span><span class="p">.</span><span class="n">top</span><span class="p">);</span>
</span><span class='line'>    <span class="n">make</span><span class="p">.</span><span class="n">left</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="n">superview</span><span class="p">.</span><span class="n">mas_left</span><span class="p">).</span><span class="n">with</span><span class="p">.</span><span class="n">offset</span><span class="p">(</span><span class="n">padding</span><span class="p">.</span><span class="n">left</span><span class="p">);</span>
</span><span class='line'>    <span class="n">make</span><span class="p">.</span><span class="n">bottom</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="n">superview</span><span class="p">.</span><span class="n">mas_bottom</span><span class="p">).</span><span class="n">with</span><span class="p">.</span><span class="n">offset</span><span class="p">(</span><span class="o">-</span><span class="n">padding</span><span class="p">.</span><span class="n">bottom</span><span class="p">);</span>
</span><span class='line'>    <span class="n">make</span><span class="p">.</span><span class="n">right</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="n">superview</span><span class="p">.</span><span class="n">mas_right</span><span class="p">).</span><span class="n">with</span><span class="p">.</span><span class="n">offset</span><span class="p">(</span><span class="o">-</span><span class="n">padding</span><span class="p">.</span><span class="n">right</span><span class="p">);</span>
</span><span class='line'><span class="p">}];</span>
</span></code></pre></td></tr></table></div></figure>


<p>or even this:</p>

<figure class='code'><figcaption><span></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="p">[</span><span class="n">view1</span> <span class="nl">mas_makeConstraints:</span><span class="o">^</span><span class="p">(</span><span class="n">MASConstraintMaker</span> <span class="o">*</span><span class="n">make</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">make</span><span class="p">.</span><span class="n">edges</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="n">superview</span><span class="p">).</span><span class="n">with</span><span class="p">.</span><span class="n">insets</span><span class="p">(</span><span class="n">padding</span><span class="p">);</span>
</span><span class='line'><span class="p">}];</span>
</span></code></pre></td></tr></table></div></figure>


<p>Basically, if you don&rsquo;t know Masonry you should check it out right now. One very nice feature recently added to Masonry is the <code>mas_updateConstraints:</code> method. It let&rsquo;s you easily change the layout of a view by automatically updating existing constraints, instead of manually saving pointers to the constraint you may need to update in ivars. We will see how this comes in extremely handy when combined with the next awesome library and a little extra magic.</p>

<h2>Classy</h2>

<p>Another excellent tool from Jonas Budelmann (he is called <a href="https://twitter.com/cloudkite">@cloudkite</a> on twitter and <a href="https://github.com/cloudkite">github</a>) that I just recently started using is <a href="http://classy.as">Classy</a>. Classy is a little like CSS (or actually more like <a href="http://learnboost.github.io/stylus/">Stylus</a>, but for native iOS apps. Classy let&rsquo;s you define stylesheets where you can match your views using different kinds of selectors and set styling properties on them. In this way it&rsquo;s easy to define all your styling in a central place that&rsquo;s much more convenient and flexible than Apple&rsquo;s appearance proxy API. A stylesheet could look something like this:</p>

<figure class='code'><figcaption><span></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>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">$main</span><span class="o">-</span><span class="n">color</span> <span class="o">=</span> <span class="err">#</span><span class="n">e1e1e1</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="n">MYCustomView</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">background</span><span class="o">-</span><span class="nl">color:</span> <span class="n">$main</span><span class="o">-</span><span class="n">color</span><span class="p">;</span>
</span><span class='line'>  <span class="n">title</span><span class="o">-</span><span class="nl">insets:</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">10</span><span class="p">;</span>
</span><span class='line'>  <span class="o">&gt;</span> <span class="n">UIProgressView</span><span class="p">.</span><span class="n">tinted</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">progress</span><span class="o">-</span><span class="n">tint</span><span class="o">-</span><span class="nl">color:</span> <span class="n">black</span><span class="p">;</span>
</span><span class='line'>    <span class="n">track</span><span class="o">-</span><span class="n">tint</span><span class="o">-</span><span class="nl">color:</span> <span class="n">yellow</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="o">^</span><span class="n">UIButton</span><span class="p">.</span><span class="n">warning</span><span class="p">,</span> <span class="n">UIView</span><span class="p">.</span><span class="n">warning</span> <span class="o">^</span><span class="n">UIButton</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">title</span><span class="o">-</span><span class="n">color</span><span class="p">[</span><span class="nl">state:</span><span class="n">highlighted</span><span class="p">]</span><span class="o">:</span> <span class="err">#</span><span class="n">e3e3e3</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>We can define variables and enjoy shortcuts for declaring colors, fonts, size, etc. You should really check out the features and the syntax on the <a href="http://classy.as">Classy website</a>.</p>

<p>Another very nice thing about Classy is it&rsquo;s live reloading feature. When running the app in the simulator we can simply edit the stylesheet file and and as soon as we save the file, the app&rsquo;s appearance will update immediately. I think this is so cool! But also extremely useful. Now the iteration time for tweaking things like colors, font sizes, scrollview insets etc. is pretty much down to zero.</p>

<h2>ClassyLiveLayout</h2>

<p>I have quickly become addicted to this live editing thing and I now enjoy compiling way fewer times during the day. But all adjustments not made using Classy still require a fresh compile and restart of the app. One such adjustment is tweaking the constant numbers used to define the view layout. Like the top margin of a view or the distance between two views. If I were to define a view with two rectangles with the same height and top margin I might do something like this:</p>

<figure class='code'><figcaption><span></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>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="p">[</span><span class="n">_blueBoxView</span> <span class="nl">mas_updateConstraints:</span><span class="o">^</span><span class="p">(</span><span class="n">MASConstraintMaker</span> <span class="o">*</span><span class="n">make</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">make</span><span class="p">.</span><span class="n">width</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="err">@</span><span class="mf">80.f</span><span class="p">);</span>
</span><span class='line'>  <span class="n">make</span><span class="p">.</span><span class="n">height</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="err">@</span><span class="mf">100.f</span><span class="p">);</span>
</span><span class='line'>  <span class="n">make</span><span class="p">.</span><span class="n">top</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="err">@</span><span class="mf">60.f</span><span class="p">);</span>
</span><span class='line'>  <span class="n">make</span><span class="p">.</span><span class="n">left</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="err">@</span><span class="mf">50.f</span><span class="p">);</span>
</span><span class='line'><span class="p">}];</span>
</span><span class='line'>
</span><span class='line'><span class="p">[</span><span class="n">_redBoxView</span> <span class="nl">mas_updateConstraints:</span><span class="o">^</span><span class="p">(</span><span class="n">MASConstraintMaker</span> <span class="o">*</span><span class="n">make</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">make</span><span class="p">.</span><span class="n">width</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="err">@</span><span class="mf">120.f</span><span class="p">);</span>
</span><span class='line'>  <span class="n">make</span><span class="p">.</span><span class="n">height</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="n">_blueBoxView</span><span class="p">);</span>
</span><span class='line'>  <span class="n">make</span><span class="p">.</span><span class="n">top</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="n">_blueBoxView</span><span class="p">);</span>
</span><span class='line'>  <span class="n">make</span><span class="p">.</span><span class="n">left</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="n">_blueBoxView</span><span class="p">.</span><span class="n">mas_right</span><span class="p">).</span><span class="n">with</span><span class="p">.</span><span class="n">offset</span><span class="p">(</span><span class="mf">30.f</span><span class="p">);</span>
</span><span class='line'><span class="p">}];</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is how the layout looks when rendered in the simulator:
<img src="http://codeblog.shape.dk/images/view_with_blue_and_red_box.png" alt="Screenshot of app with blue and red box views" /></p>

<p>In a real app I would probably extract the magic numbers into constants. I thought it would be nice if we could edit those constants at runtime and see the effect immediately like the example with Classy above. So <a href="https://github.com/cloudkite/Masonry/issues/35">I asked Jonas Budelmann if he had any ideas on how that could be done</a> and he luckily had! So here goes a solution based on Jonas&#8217; idea and <a href="https://github.com/olegam/ClassyLiveLayout">a category I wrote on UIView</a> to get rid of the boilerplate.</p>

<p>The <code>UIView+ClassyLayoutProperties</code> category defines the following properties on <code>UIView</code>:</p>

<figure class='code'><figcaption><span></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>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">@property</span><span class="p">(</span><span class="n">nonatomic</span><span class="p">,</span> <span class="n">assign</span><span class="p">)</span> <span class="n">UIEdgeInsets</span> <span class="n">cas_margin</span><span class="p">;</span>
</span><span class='line'><span class="k">@property</span><span class="p">(</span><span class="n">nonatomic</span><span class="p">,</span> <span class="n">assign</span><span class="p">)</span> <span class="n">CGSize</span> <span class="n">cas_size</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// shorthand properties for setting only a single constant value</span>
</span><span class='line'><span class="k">@property</span><span class="p">(</span><span class="n">nonatomic</span><span class="p">,</span> <span class="n">assign</span><span class="p">)</span> <span class="n">CGFloat</span> <span class="n">cas_sizeWidth</span><span class="p">;</span>
</span><span class='line'><span class="k">@property</span><span class="p">(</span><span class="n">nonatomic</span><span class="p">,</span> <span class="n">assign</span><span class="p">)</span> <span class="n">CGFloat</span> <span class="n">cas_sizeHeight</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">@property</span><span class="p">(</span><span class="n">nonatomic</span><span class="p">,</span> <span class="n">assign</span><span class="p">)</span> <span class="n">CGFloat</span> <span class="n">cas_marginTop</span><span class="p">;</span>
</span><span class='line'><span class="k">@property</span><span class="p">(</span><span class="n">nonatomic</span><span class="p">,</span> <span class="n">assign</span><span class="p">)</span> <span class="n">CGFloat</span> <span class="n">cas_marginLeft</span><span class="p">;</span>
</span><span class='line'><span class="k">@property</span><span class="p">(</span><span class="n">nonatomic</span><span class="p">,</span> <span class="n">assign</span><span class="p">)</span> <span class="n">CGFloat</span> <span class="n">cas_marginBottom</span><span class="p">;</span>
</span><span class='line'><span class="k">@property</span><span class="p">(</span><span class="n">nonatomic</span><span class="p">,</span> <span class="n">assign</span><span class="p">)</span> <span class="n">CGFloat</span> <span class="n">cas_marginRight</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The first two properties <code>cas_size</code> and <code>cas_margin</code> are the interesting ones, the others are just shorthands to set individual values of the CGSize and UIEdgeInsets structs. We can access these properties from a stylesheet to define our constants:</p>

<figure class='code'><figcaption><span></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>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">UIView</span><span class="p">.</span><span class="n">blue</span><span class="o">-</span><span class="n">box</span> <span class="p">{</span>
</span><span class='line'>    <span class="nl">cas_size:</span> <span class="mi">80</span> <span class="mi">100</span>
</span><span class='line'>    <span class="n">cas_margin</span><span class="o">-</span><span class="nl">top:</span> <span class="mi">60</span>
</span><span class='line'>    <span class="n">cas_margin</span><span class="o">-</span><span class="nl">left:</span> <span class="mi">50</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="n">UIView</span><span class="p">.</span><span class="n">red</span><span class="o">-</span><span class="n">box</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">cas_size</span><span class="o">-</span><span class="nl">width:</span> <span class="mi">120</span>
</span><span class='line'>    <span class="n">cas_margin</span><span class="o">-</span><span class="nl">left:</span> <span class="mi">20</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>We will also refer to them when we define the layout in <code>-updateConstraints</code> (or <code>-updateViewConstrains</code> if we are lazy and setup the view from the ViewController):</p>

<figure class='code'><figcaption><span></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>
</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">updateViewConstraints</span> <span class="p">{</span>
</span><span class='line'>  <span class="p">[</span><span class="n">super</span> <span class="n">updateViewConstraints</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>  <span class="p">[</span><span class="n">_blueBoxView</span> <span class="nl">mas_updateConstraints:</span><span class="o">^</span><span class="p">(</span><span class="n">MASConstraintMaker</span> <span class="o">*</span><span class="n">make</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="n">make</span><span class="p">.</span><span class="n">width</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="err">@</span><span class="p">(</span><span class="n">_blueBoxView</span><span class="p">.</span><span class="n">cas_size</span><span class="p">.</span><span class="n">width</span><span class="p">));</span>
</span><span class='line'>      <span class="n">make</span><span class="p">.</span><span class="n">height</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="err">@</span><span class="p">(</span><span class="n">_blueBoxView</span><span class="p">.</span><span class="n">cas_size</span><span class="p">.</span><span class="n">height</span><span class="p">));</span>
</span><span class='line'>      <span class="n">make</span><span class="p">.</span><span class="n">top</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="err">@</span><span class="p">(</span><span class="n">_blueBoxView</span><span class="p">.</span><span class="n">cas_margin</span><span class="p">.</span><span class="n">top</span><span class="p">));</span>
</span><span class='line'>      <span class="n">make</span><span class="p">.</span><span class="n">left</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="err">@</span><span class="p">(</span><span class="n">_blueBoxView</span><span class="p">.</span><span class="n">cas_margin</span><span class="p">.</span><span class="n">left</span><span class="p">));</span>
</span><span class='line'>  <span class="p">}];</span>
</span><span class='line'>
</span><span class='line'>  <span class="p">[</span><span class="n">_redBoxView</span> <span class="nl">mas_updateConstraints:</span><span class="o">^</span><span class="p">(</span><span class="n">MASConstraintMaker</span> <span class="o">*</span><span class="n">make</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="n">make</span><span class="p">.</span><span class="n">width</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="err">@</span><span class="p">(</span><span class="n">_redBoxView</span><span class="p">.</span><span class="n">cas_size</span><span class="p">.</span><span class="n">width</span><span class="p">));</span>
</span><span class='line'>      <span class="n">make</span><span class="p">.</span><span class="n">height</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="n">_blueBoxView</span><span class="p">);</span>
</span><span class='line'>      <span class="n">make</span><span class="p">.</span><span class="n">top</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="n">_blueBoxView</span><span class="p">);</span>
</span><span class='line'>      <span class="n">make</span><span class="p">.</span><span class="n">left</span><span class="p">.</span><span class="n">equalTo</span><span class="p">(</span><span class="n">_blueBoxView</span><span class="p">.</span><span class="n">mas_right</span><span class="p">).</span><span class="n">with</span><span class="p">.</span><span class="n">offset</span><span class="p">(</span><span class="n">_redBoxView</span><span class="p">.</span><span class="n">cas_margin</span><span class="p">.</span><span class="n">left</span><span class="p">);</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>That&rsquo;s basically everything needed to be able to live edit margin and size constants and see the results in real time in the simulator. If you want to try this yourself go get the <a href="https://github.com/olegam/ClassyLiveLayout">ClassyLiveLayout demo app</a> or follow the extra steps listed in the next section.</p>

<p>Note that we do not have to use all the margin and size values. Also we can use the margin values to specify either the distance to the superview or to a neighbor view.</p>

<p>The <code>cas_size</code> and <code>cas_margin</code> property setter implementations call <code>-setNeedsUpdateConstraints</code> on the superview after storing the new value in an associated object. This causes <code>-updateConstraints</code> to be called if it is overridden or <code>-updateViewConstrains</code> on the ViewController. In either of these methods <code>mas_updateConstraints:</code> can update the constraints with the new constants.</p>

<h2>Configuring your project</h2>

<p>Your podfile should look something like this:</p>

<figure class='code'><figcaption><span></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='ruby'><span class='line'><span class="n">pod</span> <span class="s1">&#39;Masonry&#39;</span>
</span><span class='line'><span class="n">pod</span> <span class="s1">&#39;Classy&#39;</span>
</span><span class='line'><span class="n">pod</span> <span class="s1">&#39;ClassyLiveLayout&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Your <code>Prefix.pch</code> file should include</p>

<figure class='code'><figcaption><span></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='ruby'><span class='line'><span class="c1">#import &quot;Masonry.h&quot;</span>
</span><span class='line'><span class="c1">#import &quot;Classy.h&quot;</span>
</span><span class='line'><span class="c1">#import &quot;ClassyLiveLayout.h&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>And the <code>-application:didFinishLaunchingWithOptions:</code> method in your app delegate should include these lines to activate Classy live reload:</p>

<figure class='code'><figcaption><span></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>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="cp">#if TARGET_IPHONE_SIMULATOR</span>
</span><span class='line'>    <span class="n">NSString</span> <span class="o">*</span><span class="n">absoluteFilePath</span> <span class="o">=</span> <span class="n">CASAbsoluteFilePath</span><span class="p">(</span><span class="s">@&quot;stylesheet.cas&quot;</span><span class="p">);</span>
</span><span class='line'>    <span class="p">[</span><span class="n">CASStyler</span> <span class="n">defaultStyler</span><span class="p">].</span><span class="n">watchFilePath</span> <span class="o">=</span> <span class="n">absoluteFilePath</span><span class="p">;</span>
</span><span class='line'><span class="cp">#endif</span>
</span></code></pre></td></tr></table></div></figure>


<p>This assumes your stylesheet is called <code>stylesheet.cas</code>. If you want to call it something else then follow the <a href="http://classy.as/getting-started/">Classy setup instructions</a>.</p>

<p>So by using Classy, Masonry and a little extra salt we were able to edit and tweak layout constants in real time without adding extra boilerplate to our app.</p>

<p>Do you think this is too much &lsquo;automagic&rsquo;? Let me know what you think in the comments and also please submit any ideas for improvements.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[ReactiveCocoa essentials: Understanding and using RACCommand]]></title>
    <link href="http://codeblog.shape.dk/blog/2013/12/05/reactivecocoa-essentials-understanding-and-using-raccommand/"/>
    <updated>2013-12-05T15:45:00+01:00</updated>
    <id>http://codeblog.shape.dk/blog/2013/12/05/reactivecocoa-essentials-understanding-and-using-raccommand</id>
    <content type="html"><![CDATA[<p>The source code accompanying this blog post is on github: <a href="https://github.com/olegam/RACCommandExample">https://github.com/olegam/RACCommandExample</a></p>

<h2>Is RACCommand your new best friend?</h2>

<p>The <code>RACCommand</code> is one of the essential parts of ReactiveCocoa that eventually can save you a lot of time and help make your iOS or OS X apps more robust.</p>

<p>I&rsquo;ve met several people new to ReactiveCocoa (hereafter abbreviated RAC) who don&rsquo;t entirely understand how <code>RACCommand</code> works and when it should be used. So I thought it would be useful to write a small introduction to shed some light. The official documentation doesn&rsquo;t give many examples of how to use RACCommand, but the <a href="https://github.com/ReactiveCocoa/ReactiveCocoa/blob/master/ReactiveCocoaFramework/ReactiveCocoa/RACCommand.h">comments in the header file are great</a>. However, they may be hard to understand if you&rsquo;re new to RAC.</p>

<p>The <code>RACCommand</code> class is used to represent the execution of some action. Often the execution is triggered by some action in the UI. Like when the user taps a button. <code>RACCommand</code> instances can be configured to handle reasoning about when it can be executed. This can easily be bound to the UI and the command will also make sure it doesn&rsquo;t start executing when it&rsquo;s not enabled. A commonly used strategy for when the command can execute is to leave the <code>allowsConcurrentExecution</code> at it default value of <code>NO</code>. This will make sure the command doesn&rsquo;t start executing again if it&rsquo;s already executing. The result of command execution is represented as a <code>RACSignal</code> and can hence yield results with <code>next:</code> (representing new values or results), <code>completed</code> or <code>error:</code>. I&rsquo;ll show how this is used below.</p>

<h2>The example app</h2>

<p>Let&rsquo;s assume we are making a simple iOS app that will let the user subscribe to an email list. In the simplest form we will have a text field and a button. When the user has entered his email and taps the button the email address should be posted to some webservice. Easy enough. However there are some edge cases that we should make sure to handle to provide the best experience. What happens if the user taps the button twice? How are errors handled? What if the email is invalid? <code>RACCommand</code> can help us handle those cases. I&rsquo;ve implemented a small app to demonstrate the concepts discussed in this post.</p>

<p><img src="http://codeblog.shape.dk/images/raccommand_example_app_screenshot.png" alt="Screenshot of example app" /></p>

<p>Get the source code for the example app here: <a href="https://github.com/olegam/RACCommandExample">https://github.com/olegam/RACCommandExample</a></p>

<p>With a very simple view controller the app also demonstrates a way to practice the MVVM pattern in iOS apps. Basically the view controller sets up the view hierarchy and instantiates an instance of the view model.</p>

<figure class='code'><figcaption><span></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='objc'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">bindWithViewModel</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">RAC</span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">viewModel</span><span class="p">,</span> <span class="n">email</span><span class="p">)</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">emailTextField</span><span class="p">.</span><span class="n">rac_textSignal</span><span class="p">;</span>
</span><span class='line'>  <span class="n">self</span><span class="p">.</span><span class="n">subscribeButton</span><span class="p">.</span><span class="n">rac_command</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">viewModel</span><span class="p">.</span><span class="n">subscribeCommand</span><span class="p">;</span>
</span><span class='line'>  <span class="n">RAC</span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">statusLabel</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span> <span class="o">=</span> <span class="n">RACObserve</span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">viewModel</span><span class="p">,</span> <span class="n">statusMessage</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The above method (called from <code>viewDidLoad</code>) creates the bindings between the view and the view model. All the interesting stuff is in the view model. It has the following interface:</p>

<figure class='code'><figcaption><span></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>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">@interface</span> <span class="nc">SubscribeViewModel</span> : <span class="nc">NSObject</span>
</span><span class='line'>
</span><span class='line'><span class="k">@property</span><span class="p">(</span><span class="n">nonatomic</span><span class="p">,</span> <span class="n">strong</span><span class="p">)</span> <span class="n">RACCommand</span> <span class="o">*</span><span class="n">subscribeCommand</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// write to this property</span>
</span><span class='line'><span class="k">@property</span><span class="p">(</span><span class="n">nonatomic</span><span class="p">,</span> <span class="n">strong</span><span class="p">)</span> <span class="n">NSString</span> <span class="o">*</span><span class="n">email</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// read from this property</span>
</span><span class='line'><span class="k">@property</span><span class="p">(</span><span class="n">nonatomic</span><span class="p">,</span> <span class="n">strong</span><span class="p">)</span> <span class="n">NSString</span> <span class="o">*</span><span class="n">statusMessage</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">@end</span>
</span></code></pre></td></tr></table></div></figure>


<p>The RACCommand property exposed here is what the rest of this post will be about. The two other string properties were bound to properties of the view as shown above. The full implementation of the view model looks like this:</p>

<figure class='code'><figcaption><span></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>
<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>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="cp">#import &quot;SubscribeViewModel.h&quot;</span>
</span><span class='line'><span class="cp">#import &quot;AFHTTPRequestOperationManager+RACSupport.h&quot;</span>
</span><span class='line'><span class="cp">#import &quot;NSString+EmailAdditions.h&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="k">static</span> <span class="n">NSString</span> <span class="o">*</span><span class="k">const</span> <span class="n">kSubscribeURL</span> <span class="o">=</span> <span class="s">@&quot;http://reactivetest.apiary.io/subscribers&quot;</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">@interface</span> <span class="nc">SubscribeViewModel</span> <span class="p">()</span>
</span><span class='line'><span class="k">@property</span><span class="p">(</span><span class="n">nonatomic</span><span class="p">,</span> <span class="n">strong</span><span class="p">)</span> <span class="n">RACSignal</span> <span class="o">*</span><span class="n">emailValidSignal</span><span class="p">;</span>
</span><span class='line'><span class="k">@end</span>
</span><span class='line'>
</span><span class='line'><span class="k">@implementation</span> <span class="nc">SubscribeViewModel</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nf">init</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">self</span> <span class="o">=</span> <span class="p">[</span><span class="n">super</span> <span class="n">init</span><span class="p">];</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="n">self</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="p">[</span><span class="n">self</span> <span class="n">mapSubscribeCommandStateToStatusMessage</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">self</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">mapSubscribeCommandStateToStatusMessage</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">RACSignal</span> <span class="o">*</span><span class="n">startedMessageSource</span> <span class="o">=</span> <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">subscribeCommand</span><span class="p">.</span><span class="n">executionSignals</span> <span class="nl">map:</span><span class="o">^</span><span class="kt">id</span><span class="p">(</span><span class="n">RACSignal</span> <span class="o">*</span><span class="n">subscribeSignal</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="n">NSLocalizedString</span><span class="p">(</span><span class="s">@&quot;Sending request...&quot;</span><span class="p">,</span> <span class="nb">nil</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}];</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">RACSignal</span> <span class="o">*</span><span class="n">completedMessageSource</span> <span class="o">=</span> <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">subscribeCommand</span><span class="p">.</span><span class="n">executionSignals</span> <span class="nl">flattenMap:</span><span class="o">^</span><span class="n">RACStream</span> <span class="o">*</span><span class="p">(</span><span class="n">RACSignal</span> <span class="o">*</span><span class="n">subscribeSignal</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="p">[[[</span><span class="n">subscribeSignal</span> <span class="n">materialize</span><span class="p">]</span> <span class="nl">filter:</span><span class="o">^</span><span class="kt">BOOL</span><span class="p">(</span><span class="n">RACEvent</span> <span class="o">*</span><span class="n">event</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>          <span class="k">return</span> <span class="n">event</span><span class="p">.</span><span class="n">eventType</span> <span class="o">==</span> <span class="n">RACEventTypeCompleted</span><span class="p">;</span>
</span><span class='line'>      <span class="p">}]</span> <span class="nl">map:</span><span class="o">^</span><span class="kt">id</span><span class="p">(</span><span class="kt">id</span> <span class="n">value</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>          <span class="k">return</span> <span class="n">NSLocalizedString</span><span class="p">(</span><span class="s">@&quot;Thanks&quot;</span><span class="p">,</span> <span class="nb">nil</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="n">RACSignal</span> <span class="o">*</span><span class="n">failedMessageSource</span> <span class="o">=</span> <span class="p">[[</span><span class="n">self</span><span class="p">.</span><span class="n">subscribeCommand</span><span class="p">.</span><span class="n">errors</span> <span class="nl">subscribeOn:</span><span class="p">[</span><span class="n">RACScheduler</span> <span class="n">mainThreadScheduler</span><span class="p">]]</span> <span class="nl">map:</span><span class="o">^</span><span class="kt">id</span><span class="p">(</span><span class="n">NSError</span> <span class="o">*</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="n">NSLocalizedString</span><span class="p">(</span><span class="s">@&quot;Error :(&quot;</span><span class="p">,</span> <span class="nb">nil</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}];</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">RAC</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">statusMessage</span><span class="p">)</span> <span class="o">=</span> <span class="p">[</span><span class="n">RACSignal</span> <span class="nl">merge:</span><span class="err">@</span><span class="p">[</span><span class="n">startedMessageSource</span><span class="p">,</span> <span class="n">completedMessageSource</span><span class="p">,</span> <span class="n">failedMessageSource</span><span class="p">]];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">RACCommand</span> <span class="o">*</span><span class="p">)</span><span class="nf">subscribeCommand</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">_subscribeCommand</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="n">NSString</span> <span class="o">*</span><span class="n">email</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">email</span><span class="p">;</span>
</span><span class='line'>      <span class="n">_subscribeCommand</span> <span class="o">=</span> <span class="p">[[</span><span class="n">RACCommand</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithEnabled:</span><span class="n">self</span><span class="p">.</span><span class="n">emailValidSignal</span> <span class="nl">signalBlock:</span><span class="o">^</span><span class="n">RACSignal</span> <span class="o">*</span><span class="p">(</span><span class="kt">id</span> <span class="n">input</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>          <span class="k">return</span> <span class="p">[</span><span class="n">SubscribeViewModel</span> <span class="nl">postEmail:</span><span class="n">email</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 class="k">return</span> <span class="n">_subscribeCommand</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">+</span> <span class="p">(</span><span class="n">RACSignal</span> <span class="o">*</span><span class="p">)</span><span class="nf">postEmail:</span><span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="nv">email</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">AFHTTPRequestOperationManager</span> <span class="o">*</span><span class="n">manager</span> <span class="o">=</span> <span class="p">[</span><span class="n">AFHTTPRequestOperationManager</span> <span class="n">manager</span><span class="p">];</span>
</span><span class='line'>  <span class="n">manager</span><span class="p">.</span><span class="n">requestSerializer</span> <span class="o">=</span> <span class="p">[</span><span class="n">AFJSONRequestSerializer</span> <span class="n">new</span><span class="p">];</span>
</span><span class='line'>  <span class="n">NSDictionary</span> <span class="o">*</span><span class="n">body</span> <span class="o">=</span> <span class="err">@</span><span class="p">{</span><span class="s">@&quot;email&quot;</span><span class="o">:</span> <span class="n">email</span> <span class="o">?:</span> <span class="s">@&quot;&quot;</span><span class="p">};</span>
</span><span class='line'>  <span class="k">return</span> <span class="p">[[[</span><span class="n">manager</span> <span class="nl">rac_POST:</span><span class="n">kSubscribeURL</span> <span class="nl">parameters:</span><span class="n">body</span><span class="p">]</span> <span class="n">logError</span><span class="p">]</span> <span class="n">replayLazily</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">RACSignal</span> <span class="o">*</span><span class="p">)</span><span class="nf">emailValidSignal</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">_emailValidSignal</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="n">_emailValidSignal</span> <span class="o">=</span> <span class="p">[</span><span class="n">RACObserve</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">email</span><span class="p">)</span> <span class="nl">map:</span><span class="o">^</span><span class="kt">id</span><span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="n">email</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>          <span class="k">return</span> <span class="err">@</span><span class="p">([</span><span class="n">email</span> <span class="n">isValidEmail</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 class="k">return</span> <span class="n">_emailValidSignal</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">@end</span>
</span></code></pre></td></tr></table></div></figure>


<p>This might seem like a big chunk so let&rsquo;s go through it in smaller parts. The <code>RACCommand</code> that we are most interested in is created like this:</p>

<figure class='code'><figcaption><span></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>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">RACCommand</span> <span class="o">*</span><span class="p">)</span><span class="nf">subscribeCommand</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">_subscribeCommand</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="n">NSString</span> <span class="o">*</span><span class="n">email</span> <span class="o">=</span> <span class="n">self</span><span class="p">.</span><span class="n">email</span><span class="p">;</span>
</span><span class='line'>      <span class="n">_subscribeCommand</span> <span class="o">=</span> <span class="p">[[</span><span class="n">RACCommand</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithEnabled:</span><span class="n">self</span><span class="p">.</span><span class="n">emailValidSignal</span> <span class="nl">signalBlock:</span><span class="o">^</span><span class="n">RACSignal</span> <span class="o">*</span><span class="p">(</span><span class="kt">id</span> <span class="n">input</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>          <span class="k">return</span> <span class="p">[</span><span class="n">SubscribeViewModel</span> <span class="nl">postEmail:</span><span class="n">email</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 class="k">return</span> <span class="n">_subscribeCommand</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The command is initialized with an <code>enabledSignal</code> parameter. This is a signal indicating when the command can execute. In our case it should be allowed to execute when the email address entered by the user is valid. The <code>self.emailValidSignal</code> is a signal that sends a <code>NO</code> or a <code>YES</code> every time the email changes.</p>

<p>The <code>signalBlock</code> parameter is invoked every time the command needs to execute. The block should return a signal representing the execution. Since we leave the default property of <code>allowsConcurrentExecution</code> on <code>NO</code> the command will watch this signal and not allow any new executions before the execution in progress completes.</p>

<p>Because the command is set on the button&rsquo;s <code>rac_command</code> property defined in the <code>UIButtton+RACCommandSupport</code> category the button will automatically change between the enabled and disabled state based on when the command can execute.</p>

<p>Also the command will automatically execute when the button is tapped by the user. We get all this for free with <code>RACCommand</code>. If you need to execute the command manually you can do this by messaging <code>-[RACCommand execute:]</code>. The argument is an optional input. We don&rsquo;t use it here, but it is often very useful (the button sends itself as input when it calls <code>-execute:</code>). The <code>-execute:</code> method is also one of the places you can hook in to watch the status of the execution. You could potentially do something like this:</p>

<figure class='code'><figcaption><span></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="p">[[</span><span class="n">self</span><span class="p">.</span><span class="n">viewModel</span><span class="p">.</span><span class="n">subscribeCommand</span> <span class="nl">execute:</span><span class="nb">nil</span><span class="p">]</span> <span class="nl">subscribeCompleted:</span><span class="o">^</span><span class="p">{</span>
</span><span class='line'>  <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;The command executed&quot;</span><span class="p">);</span>
</span><span class='line'><span class="p">}];</span>
</span></code></pre></td></tr></table></div></figure>


<p>In our example the button executes the command for us (so we don&rsquo;t call <code>-execute:</code>) and hence we have to listen for another property of the command in order to update the UI when the command executes. There are several opportunities to chose between here. And this can maybe be a little confusing. The <code>executionSignals</code> property of <code>RACCommand</code> is a signal that sends a <code>next:</code> every time the commands start executing. The argument is the signal created by the command. So it&rsquo;s a signal of signals. We use that in the <code>mapSubscribeCommandStateToStatusMessage</code> method of the view model to get a signal with a string value every time the command is started:</p>

<figure class='code'><figcaption><span></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="n">RACSignal</span> <span class="o">*</span><span class="n">startedMessageSource</span> <span class="o">=</span> <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">subscribeCommand</span><span class="p">.</span><span class="n">executionSignals</span> <span class="nl">map:</span><span class="o">^</span><span class="kt">id</span><span class="p">(</span><span class="n">RACSignal</span> <span class="o">*</span><span class="n">subscribeSignal</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">NSLocalizedString</span><span class="p">(</span><span class="s">@&quot;Sending request...&quot;</span><span class="p">,</span> <span class="nb">nil</span><span class="p">);</span>
</span><span class='line'><span class="p">}];</span>
</span></code></pre></td></tr></table></div></figure>


<p>To get a similar signal with a string every time the command completes execution we have to do a little more work if we want to be purely functional:</p>

<figure class='code'><figcaption><span></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='objc'><span class='line'><span class="n">RACSignal</span> <span class="o">*</span><span class="n">completedMessageSource</span> <span class="o">=</span> <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">subscribeCommand</span><span class="p">.</span><span class="n">executionSignals</span> <span class="nl">flattenMap:</span><span class="o">^</span><span class="n">RACStream</span> <span class="o">*</span><span class="p">(</span><span class="n">RACSignal</span> <span class="o">*</span><span class="n">subscribeSignal</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="p">[[[</span><span class="n">subscribeSignal</span> <span class="n">materialize</span><span class="p">]</span> <span class="nl">filter:</span><span class="o">^</span><span class="kt">BOOL</span><span class="p">(</span><span class="n">RACEvent</span> <span class="o">*</span><span class="n">event</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="n">event</span><span class="p">.</span><span class="n">eventType</span> <span class="o">==</span> <span class="n">RACEventTypeCompleted</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}]</span> <span class="nl">map:</span><span class="o">^</span><span class="kt">id</span><span class="p">(</span><span class="kt">id</span> <span class="n">value</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="k">return</span> <span class="n">NSLocalizedString</span><span class="p">(</span><span class="s">@&quot;Thanks&quot;</span><span class="p">,</span> <span class="nb">nil</span><span class="p">);</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>The <code>flattenMap:</code> method used above invokes a block with the <code>subscribeSignal</code> when the command executes. This block returns a new signal and it&rsquo;s values are passed down into the resulting signal. The <code>materialize</code> operator let&rsquo;s us get a signal of <code>RACEvent</code>s (ie. the <code>next:</code> <code>complete</code> and <code>error:</code> messages are delivered as <code>RACEvent</code> instances as <code>next:</code> values on the resulting signal). We can then filter those events to only get the ones from when the signal completes and in that case map it to a string value. Did I loose you here? I hope not, but you may need to look up the documentation of <a href="https://github.com/ReactiveCocoa/ReactiveCocoa/blob/d4924b237720afef62c1334437140bb803fb5242/ReactiveCocoaFramework/ReactiveCocoa/RACStream.h#L98">flattenMap:</a> and <a href="https://github.com/ReactiveCocoa/ReactiveCocoa/blob/2d5f163547f2b9c6ee25cf2c9ff8554faf7929f2/ReactiveCocoaFramework/ReactiveCocoa/RACSignal%2BOperations.h#L558">materialize</a> to better understand what they do.</p>

<p>We could have implemented this behavior in a different way that is less functional, but maybe easier to understand:</p>

<figure class='code'><figcaption><span></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='objc'><span class='line'><span class="err">@</span><span class="n">weakify</span><span class="p">(</span><span class="n">self</span><span class="p">);</span>
</span><span class='line'><span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">subscribeCommand</span><span class="p">.</span><span class="n">executionSignals</span> <span class="nl">subscribeNext:</span><span class="o">^</span><span class="p">(</span><span class="n">RACSignal</span> <span class="o">*</span><span class="n">subscribeSignal</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="p">[</span><span class="n">subscribeSignal</span> <span class="nl">subscribeCompleted:</span><span class="o">^</span><span class="p">{</span>
</span><span class='line'>      <span class="err">@</span><span class="n">strongify</span><span class="p">(</span><span class="n">self</span><span class="p">);</span>
</span><span class='line'>      <span class="n">self</span><span class="p">.</span><span class="n">statusMessage</span> <span class="o">=</span> <span class="s">@&quot;Thanks&quot;</span><span class="p">;</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>However, I don&rsquo;t like the above implementation as it involves side effects in the blocks. This also has the disadvantage of referring and retaining <code>self</code> in the block. Thus I have to use the <code>@weakify</code> and <code>@strongify</code> macros (defined in the <code>libextobjc</code> pod) to avoid a retain cycle. So better just avoid side effects altogether when possible as I did with the original implementation.</p>

<p>There is an important details to note about the <code>executionSignals</code> property. The signals sent here do not include error events. For those there is a special <code>errors</code> property. A signal that sends any error during execution of the command as a <code>next:</code>. The errors are not sent as regular <code>error:</code> events as that would terminate the signal. We can easily map the the errors to string messages:</p>

<figure class='code'><figcaption><span></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="n">RACSignal</span> <span class="o">*</span><span class="n">failedMessageSource</span> <span class="o">=</span> <span class="p">[[</span><span class="n">self</span><span class="p">.</span><span class="n">subscribeCommand</span><span class="p">.</span><span class="n">errors</span> <span class="nl">subscribeOn:</span><span class="p">[</span><span class="n">RACScheduler</span> <span class="n">mainThreadScheduler</span><span class="p">]]</span> <span class="nl">map:</span><span class="o">^</span><span class="kt">id</span><span class="p">(</span><span class="n">NSError</span> <span class="o">*</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="n">NSLocalizedString</span><span class="p">(</span><span class="s">@&quot;Error :(&quot;</span><span class="p">,</span> <span class="nb">nil</span><span class="p">);</span>
</span><span class='line'><span class="p">}];</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now when we have 3 signals with status messages we want to show to the user we can merge them into one signal and bind that to the <code>statusMessage</code> property of the view model (bound to the <code>statusLabel.text</code> property of the view controller).</p>

<figure class='code'><figcaption><span></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='objc'><span class='line'><span class="n">RAC</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">statusMessage</span><span class="p">)</span> <span class="o">=</span> <span class="p">[</span><span class="n">RACSignal</span> <span class="nl">merge:</span><span class="err">@</span><span class="p">[</span><span class="n">startedMessageSource</span><span class="p">,</span> <span class="n">completedMessageSource</span><span class="p">,</span> <span class="n">failedMessageSource</span><span class="p">]];</span>
</span></code></pre></td></tr></table></div></figure>


<p>So this was an example of how a <code>RACCommand</code> can be used in practice in an iOS app. I think this way of implementing logic has many advantages over the way many people would implement it with a <code>UITextFieldDelegate</code> in the view controller and lots of state stored in ivars or properties.</p>

<h2>Other RACCommand details of interest</h2>

<p><code>RACCommand</code> has an <code>executing</code> property that is actually a signal sending <code>YES</code> when <code>execute:</code> is invoked and <code>NO</code> when it terminates. Upon subscription the signal will send it&rsquo;s current value. If you just need to get the current value and don&rsquo;t want a signal, you can get it immediately like this:</p>

<figure class='code'><figcaption><span></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='objc'><span class='line'><span class="kt">BOOL</span> <span class="n">commandIsExecuting</span> <span class="o">=</span> <span class="p">[[</span><span class="n">command</span><span class="p">.</span><span class="n">executing</span> <span class="n">first</span><span class="p">]</span> <span class="n">boolValue</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>The <code>enabled</code> property is also a signal sending <code>YES</code> and <code>NO</code>. It will send <code>NO</code> when the command was created with an <code>enabledSignal</code> and that signal sends a <code>NO</code> or if the signal is executing and <code>allowsConcurrentExecutions</code> is set to <code>NO</code>.</p>

<p>If you try to message <code>-execute:</code> on a signal that is not enabled it will immediately send an error, but that error will not be sent to the <code>errors</code> signal.</p>

<p>The <code>-execute:</code> method will automatically subscribe to the original signal and multicast it. This basically means that you do not have to subscribe to the returned signal, but if you do so you should not be afraid of side effects happening twice.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Transparent OAuth token refresh using ReactiveCocoa]]></title>
    <link href="http://codeblog.shape.dk/blog/2013/12/02/transparent-oauth-token-refresh-using-reactivecocoa/"/>
    <updated>2013-12-02T17:25:00+01:00</updated>
    <id>http://codeblog.shape.dk/blog/2013/12/02/transparent-oauth-token-refresh-using-reactivecocoa</id>
    <content type="html"><![CDATA[<h2>OAuth 2.0 refresh tokens meet your master</h2>

<p>Almost all the apps that we develop integrate with some sort of backend web service and a lot of them also require users to authenticate in order to access certain resources.</p>

<p>Using some sort of OAuth 2.0 for authentication is very common today. For example we had to integrate with the Salesforce REST API in one of our recent apps. When developing this app we came to a pretty good solution for automatically and transparently refreshing the user&rsquo;s access token when needed. In this post we would like to share that solution.</p>

<p>OAuth 2.0 basically works by issuing an access token and a refresh token to an authenticated user. The access token is needed in all requests to the API to ensure the user is authorized to access the requested resources. The access token is typically short-lived and the developer should assume it can expire at any time. The refresh token can be used to request a new access token when the old one has expired without needing the user to re-authenticate.</p>

<h2>The problem</h2>

<p>In order to correctly handle situations where an access token has expired we need to catch all errors and check the reason. In case the error is caused by an expired access token we should try to get a new one using the refresh token and if successful we should replay the original request with the new access token. In case the request failed for any other reason we should just let the regular error handling mechanisms handle the situation.</p>

<h2>What we did</h2>

<p>At Shape we love <a href="https://github.com/ReactiveCocoa/ReactiveCocoa">ReactiveCocoa</a> and try to use it as much as possible to make our apps more reliable and maintainable as well as more enjoyable to develop. Since we already build most of our API clients using ReactiveCocoa we had a feeling that the token refresh problem could be solved beautifully using ReactiveCocoa.</p>

<p>One of the best things about ReactiveCocoa is the amazing efforts put into the project by the developers (primarily Github&rsquo;s Justin Spahr-Summers and Josh Abernathy). They are always ready to assist with their experience and endless knowledge when you find yourself stuck. In this case we had some <a href="https://github.com/ReactiveCocoa/ReactiveCocoa/issues/768">great input</a> from Josh Abernathy that helped us arrive at the final solution.</p>

<p>We represent API requests using RACSignals that will <code>next</code> and <code>complete</code> or <code>error</code> when the requests finish. An easy way to do this is to use the <code>AFNetworking-RACExtensions</code> pod that we described in our last post: <a href="http://codeblog.shape.dk/blog/2013/11/16/wrapping-afnetworking-with-reactivecocoa">Wrapping AFNetworking with ReactiveCocoa</a>.</p>

<p>An API request in our solution could look like this:</p>

<figure class='code'><figcaption><span></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>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">RACSignal</span> <span class="o">*</span><span class="p">)</span><span class="nf">getResourceWithId:</span><span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="nv">resourceId</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">NSString</span> <span class="o">*</span><span class="n">path</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSString</span> <span class="nl">stringWithFormat:</span><span class="s">@&quot;resource/%@&quot;</span><span class="p">,</span> <span class="n">resourceId</span><span class="p">];</span>
</span><span class='line'>    <span class="n">RACSignal</span> <span class="o">*</span><span class="n">requestSignal</span> <span class="o">=</span> <span class="p">[[</span><span class="n">self</span><span class="p">.</span><span class="n">requestOperationManager</span> <span class="nl">rac_GET:</span><span class="n">path</span> <span class="nl">parameters:</span><span class="nb">nil</span><span class="p">]</span> <span class="nl">map:</span><span class="o">^</span><span class="kt">id</span><span class="p">(</span><span class="n">RACTuple</span> <span class="o">*</span><span class="n">tuple</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">RACTupleUnpack</span><span class="p">(</span><span class="n">AFHTTPRequestOperation</span> <span class="o">*</span><span class="n">operation</span><span class="p">,</span> <span class="n">NSDictionary</span> <span class="o">*</span><span class="n">response</span><span class="p">)</span> <span class="o">=</span> <span class="n">tuple</span><span class="p">;</span>
</span><span class='line'>        <span class="k">return</span> <span class="n">response</span><span class="p">[</span><span class="s">@&quot;results&quot;</span><span class="p">];</span>
</span><span class='line'>    <span class="p">}];</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">[</span><span class="n">self</span> <span class="nl">doRequestAndRefreshTokenIfNecessary:</span><span class="n">requestSignal</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>In the above example <code>self.requestOperationManager</code> is an instance of <code>AFHTTPRequestOperationManager</code> that has a custom <code>requestSerializer</code> set to take care of adding the access token to every request. Notice how we wrap our API request signal with the <code>doRequestAndRefreshTokenIfNecessary:</code> method to get the desired transparent token refresh behavior. The method looks like this:</p>

<figure class='code'><figcaption><span></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>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">RACSignal</span> <span class="o">*</span><span class="p">)</span><span class="nf">doRequestAndRefreshTokenIfNecessary:</span><span class="p">(</span><span class="n">RACSignal</span> <span class="o">*</span><span class="p">)</span><span class="nv">requestSignal</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">[</span><span class="n">requestSignal</span> <span class="nl">catch:</span><span class="o">^</span><span class="p">(</span><span class="n">NSError</span> <span class="o">*</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="c1">// Catch the error, refresh the token, and then do the request again.</span>
</span><span class='line'>        <span class="kt">BOOL</span> <span class="n">hasRefreshToken</span> <span class="o">=</span> <span class="p">[</span><span class="n">UserManager</span> <span class="n">sharedInstance</span><span class="p">].</span><span class="n">refreshToken</span> <span class="o">!=</span> <span class="nb">nil</span><span class="p">;</span>
</span><span class='line'>        <span class="kt">BOOL</span> <span class="n">httpCode401AccessDenied</span> <span class="o">=</span> <span class="n">error</span><span class="p">.</span><span class="n">code</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1011</span><span class="p">;</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="n">httpCode401AccessDenied</span> <span class="o">&amp;&amp;</span> <span class="n">hasRefreshToken</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;Will attempt to refresh access token.&quot;</span><span class="p">);</span>
</span><span class='line'>            <span class="k">return</span> <span class="p">[[[</span><span class="n">self</span> <span class="n">refreshToken</span><span class="p">]</span> <span class="n">ignoreValues</span><span class="p">]</span> <span class="nl">concat:</span><span class="n">requestSignal</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">requestSignal</span><span class="p">;</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 method catches errors on API request signals before they are propagated to its subscribers. This is done with the <code>catch:</code> method that lets us create a new signal when an error is sent on a signal. Inside the catch block we check if the error is caused by an expired token or any other error. If it is any other error we return the original signal so the error can just propagate to the subscribers without any modified behavior.</p>

<p>The magic happens when we receive an expired token error. In this case we use the <code>concat:</code> method to create a new signal composed of the refresh token signal and the original signal. The request signal will be re-subscribed to when the refresh signal completes and thus repeat (using the newly acquired access token). Any error will immediately propagate to the subscriber and terminate the signal.</p>

<h2>What we achieved</h2>

<p>By wrapping our API requests in the <code>doRequestAndRefreshTokenIfNecessary:</code> method we now get automatic and transparent handling of expired access tokens. Consumers of the API clients should not need to worry about tokens that may expire and how to handle that.</p>

<p>With the solution presented above we solved a common problem using very little code and without using any ivars or properties to store state. As mentioned above the main trick used was given to us on the ReactiveCocoa github issues page, but we thought it would be worth explaining here.</p>

<p>If you have any suggestions for improvements then please let us know in the comments.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Wrapping AFNetworking with ReactiveCocoa]]></title>
    <link href="http://codeblog.shape.dk/blog/2013/11/16/wrapping-afnetworking-with-reactivecocoa/"/>
    <updated>2013-11-16T22:35:00+01:00</updated>
    <id>http://codeblog.shape.dk/blog/2013/11/16/wrapping-afnetworking-with-reactivecocoa</id>
    <content type="html"><![CDATA[<p>When you learn to use <a href="https://github.com/ReactiveCocoa/ReactiveCocoa">ReactiveCocoa</a> and discover how it can make your iOS apps more robust and more fun to develop and maintain then you suddenly want to use it all the time. Often it is necessary to bridge the Functional Reactive Programming (<a href="http://en.wikipedia.org/wiki/Functional_reactive_programming">FRP</a>) world with the imperative one. The cocoa touch frameworks and most third party libraries are based on imperative concepts and associated design patterns such as delegates, target-action and callback blocks. In FRP we like to operate on signals representing values changing over time instead of keeping track of state. Often it is worth the while to build a ReactiveCocoa bridge on top of existing APIs in order to consume them in a functional way.</p>

<p>One third party library used by a lot of apps is <a href="https://github.com/AFNetworking/AFNetworking">AFNetworking</a> from <a href="http://twitter.com/mattt">Mattt Thompson</a>. The latest version 2.0 has many features and offer many conveniences over using NSURLConnection directly. The AFNetworking API is also <a href="http://cocoadocs.org/docsets/AFNetworking/2.0.0/">well documented</a>.</p>

<p>If we write a few categories to offer a RACSignal-based API for the most used methods it will be easy to integrate with the rest of our ReactiveCocoa-based app.</p>

<p><code>AFHTTPRequestOperationManager</code> is a class that makes it easy to dispatch network requests. One way to make a request is using the <code>-[AFHTTPRequestOperationManager GET:parameters:success:failure]</code> method. The full signature of the method is</p>

<figure class='code'><figcaption><span></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>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">AFHTTPRequestOperation</span> <span class="o">*</span><span class="p">)</span><span class="nf">GET:</span><span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="nv">URLString</span>
</span><span class='line'>                     <span class="nf">parameters:</span><span class="p">(</span><span class="n">NSDictionary</span> <span class="o">*</span><span class="p">)</span><span class="nv">parameters</span>
</span><span class='line'>                        <span class="nf">success:</span><span class="p">(</span><span class="kt">void</span> <span class="p">(</span><span class="o">^</span><span class="p">)(</span><span class="n">AFHTTPRequestOperation</span> <span class="o">*</span><span class="n">operation</span><span class="p">,</span> <span class="kt">id</span> <span class="n">responseObject</span><span class="p">))</span><span class="nv">success</span>
</span><span class='line'>                        <span class="nf">failure:</span><span class="p">(</span><span class="kt">void</span> <span class="p">(</span><span class="o">^</span><span class="p">)(</span><span class="n">AFHTTPRequestOperation</span> <span class="o">*</span><span class="n">operation</span><span class="p">,</span> <span class="n">NSError</span> <span class="o">*</span><span class="n">error</span><span class="p">))</span><span class="nv">failure</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>By creating a category on <code>AFHTTPRequestOperationManager</code> we can get an interface like this:</p>

<figure class='code'><figcaption><span></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='objc'><span class='line'><span class="k">@interface</span> <span class="nc">AFHTTPRequestOperationManager</span> <span class="nl">(ReactiveExtension)</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// sends a next with the AFHTTPRequestOperation instance and completes if the request succeeds.</span>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">RACSignal</span> <span class="o">*</span><span class="p">)</span><span class="nf">signalForGET:</span><span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="nv">URLString</span> <span class="nf">parameters:</span><span class="p">(</span><span class="n">NSDictionary</span> <span class="o">*</span><span class="p">)</span><span class="nv">parameters</span><span class="p">;</span>
</span><span class='line'><span class="k">@end</span>
</span></code></pre></td></tr></table></div></figure>


<p>The method returns a signal that will be used to communicate the results of the request after it succeeds or fails. My implementation with ReactiveCocoa looks like this:</p>

<figure class='code'><figcaption><span></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='objc'><span class='line'><span class="k">@implementation</span> <span class="nc">AFHTTPRequestOperationManager</span> <span class="nl">(ReactiveExtension)</span>
</span><span class='line'>
</span><span class='line'><span class="k">-</span> <span class="p">(</span><span class="n">RACSignal</span> <span class="o">*</span><span class="p">)</span><span class="nf">signalForGET:</span><span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span><span class="nv">URLString</span> <span class="nf">parameters:</span><span class="p">(</span><span class="n">NSDictionary</span> <span class="o">*</span><span class="p">)</span><span class="nv">parameters</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="p">[[</span><span class="n">RACSignal</span> <span class="nl">createSignal:</span><span class="o">^</span><span class="n">RACDisposable</span> <span class="o">*</span><span class="p">(</span><span class="kt">id</span> <span class="o">&lt;</span><span class="n">RACSubscriber</span><span class="o">&gt;</span> <span class="n">subscriber</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="n">AFHTTPRequestOperation</span> <span class="o">*</span><span class="n">op</span> <span class="o">=</span> <span class="p">[</span><span class="n">self</span> <span class="nl">GET:</span><span class="n">URLString</span> <span class="nl">parameters:</span><span class="n">parameters</span> <span class="nl">success:</span><span class="o">^</span><span class="p">(</span><span class="n">AFHTTPRequestOperation</span> <span class="o">*</span><span class="n">operation</span><span class="p">,</span> <span class="kt">id</span> <span class="n">responseObject</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>          <span class="p">[</span><span class="n">subscriber</span> <span class="nl">sendNext:</span><span class="n">operation</span><span class="p">];</span>
</span><span class='line'>          <span class="p">[</span><span class="n">subscriber</span> <span class="n">sendCompleted</span><span class="p">];</span>
</span><span class='line'>      <span class="p">}</span> <span class="nl">failure:</span><span class="o">^</span><span class="p">(</span><span class="n">AFHTTPRequestOperation</span> <span class="o">*</span><span class="n">operation</span><span class="p">,</span> <span class="n">NSError</span> <span class="o">*</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>          <span class="n">NSMutableDictionary</span> <span class="o">*</span><span class="n">userInfo</span> <span class="o">=</span> <span class="p">[</span><span class="n">error</span><span class="p">.</span><span class="n">userInfo</span> <span class="n">mutableCopy</span><span class="p">]</span> <span class="o">?:</span> <span class="p">[</span><span class="n">NSMutableDictionary</span> <span class="n">dictionary</span><span class="p">];</span>
</span><span class='line'>          <span class="n">userInfo</span><span class="p">[</span><span class="n">kAFNetworkingReactiveExtensionErrorInfoOperationKey</span><span class="p">]</span> <span class="o">=</span> <span class="n">operation</span><span class="p">;</span>
</span><span class='line'>          <span class="n">NSError</span> <span class="o">*</span><span class="n">errorWithOperation</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSError</span> <span class="nl">errorWithDomain:</span><span class="n">error</span><span class="p">.</span><span class="n">domain</span> <span class="nl">code:</span><span class="n">error</span><span class="p">.</span><span class="n">code</span> <span class="nl">userInfo:</span><span class="n">userInfo</span><span class="p">];</span>
</span><span class='line'>          <span class="p">[</span><span class="n">subscriber</span> <span class="nl">sendError:</span><span class="n">errorWithOperation</span><span class="p">];</span>
</span><span class='line'>      <span class="p">}];</span>
</span><span class='line'>      <span class="k">return</span> <span class="p">[</span><span class="n">RACDisposable</span> <span class="nl">disposableWithBlock:</span><span class="o">^</span><span class="p">{</span>
</span><span class='line'>          <span class="p">[</span><span class="n">op</span> <span class="n">cancel</span><span class="p">];</span>
</span><span class='line'>      <span class="p">}];</span>
</span><span class='line'>  <span class="p">}]</span> <span class="n">replayLazily</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="k">@end</span>
</span></code></pre></td></tr></table></div></figure>


<p>There are a few things to note here. First the method creates a new signal using the <code>+[RACSignal createSignal:]</code> method. <code>-[AFHTTPRequestOperationManager GET:parameters:success:failure]</code>&rsquo;s success block sends a next with the operation object and also completes the signal. The failure block is slightly more complicated. I wrap the <code>AFHTTPRequestOperation</code> instance in the user dictionary of the <code>NSError</code> object. This is useful in cases when the consumer needs to know the exact response data even though the request failed.</p>

<p>Another important detail is the <code>RACDisposable</code> object returned in the <code>createSignal:</code> method. The disposable is used to cancel the request operation in the case the subscriber disposes its subscription. This is a great example of the power of Reactive Cocoa. The request signal may be operated on by many parts of the app and the object eventually subscribing to it may not need to know about the internals of the network layer. Still it can cancel the request if it does not need the response anyway.</p>

<p>Finally I apply the <code>replayLaizily</code> operator on the signal to ensure side effects only occur once even if the signal is subscribed to multiple times.</p>

<p>UPDATE: Turns out there is already a pod that wraps all AFNetwork&rsquo;s block based methods called <code>AFNetworking-RACExtensions</code>. Unfortunately the original repo and podspec has not been updated for AFNetworking 2.0, but there is a <a href="https://github.com/knshiro/AFNetworking-RACExtensions">fork</a> that seems to work well. Just put this in your Podfile to use the fixed fork:</p>

<figure class='code'><figcaption><span></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">pod</span> <span class="s1">&#39;AFNetworking-RACExtensions&#39;</span><span class="p">,</span> <span class="ss">:git</span> <span class="o">=&gt;</span> <span class="s1">&#39;https://github.com/knshiro/AFNetworking-RACExtensions.git&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>When you have the <code>AFNetworking-RACExtensions</code> pod you can go ahead and make requests like:</p>

<figure class='code'><figcaption><span></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='objc'><span class='line'><span class="n">AFHTTPRequestOperationManager</span> <span class="o">*</span><span class="n">manager</span> <span class="o">=</span> <span class="p">[</span><span class="n">AFHTTPRequestOperationManager</span> <span class="n">manager</span><span class="p">];</span>
</span><span class='line'><span class="p">[[</span><span class="n">manager</span> <span class="nl">rac_GET:</span><span class="s">@&quot;http://exampl.com/1.json&quot;</span> <span class="nl">parameters:</span><span class="nb">nil</span><span class="p">]</span> <span class="nl">subscribeNext:</span><span class="o">^</span><span class="p">(</span><span class="n">RACTuple</span> <span class="o">*</span><span class="n">tuple</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="n">RACTupleUnpack</span><span class="p">(</span><span class="n">AFHTTPRequestOperation</span> <span class="o">*</span><span class="n">operation</span><span class="p">,</span> <span class="n">NSDictionary</span> <span class="o">*</span><span class="n">response</span><span class="p">)</span> <span class="o">=</span> <span class="n">tuple</span><span class="p">;</span>
</span><span class='line'>  <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;response: %@&quot;</span><span class="p">,</span> <span class="p">[</span><span class="n">response</span> <span class="n">description</span><span class="p">]);</span>
</span><span class='line'><span class="p">}];</span>
</span></code></pre></td></tr></table></div></figure>


<p>Of course the real fun doesn&rsquo;t start until you begin operating on and combining signals, but that&rsquo;s a topic for another blog post.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Welcome to the SHAPE code blog]]></title>
    <link href="http://codeblog.shape.dk/blog/2013/11/16/welcome-to-the-shape-code-blog/"/>
    <updated>2013-11-16T19:52:00+01:00</updated>
    <id>http://codeblog.shape.dk/blog/2013/11/16/welcome-to-the-shape-code-blog</id>
    <content type="html"><![CDATA[<p>When we develop apps for iOS, Android and the web we gather new experiences all the time. We do a lot to share these experiences with each other internally in SHAPE. But sometimes we also want to share our ideas and findings with the community. This blog will be our channel to share code-related experiences and ideas.</p>

<p>Since we mostly work with iOS and Android development many of the posts will likely be related to those technologies. But as we are pretty curious of nature we also work, experiment and play with a broad range of other technologies such as Ruby on Rails, node.js, Go, angular.js, Windows Phone, etc. So we might also blog about any of those or other technologies.</p>

<p>You can reach out to us on twitter (<a href="http://www.twitter.com/shapedk">@shapedk</a>) or send us an email at <a href="mailto:hello@shape.dk">hello@shape.dk</a>.</p>
]]></content>
  </entry>
  
</feed>
