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

  <title><![CDATA[それはBooks]]></title>
  <link href="http://hamasyou.com/atom.xml" rel="self"/>
  <link href="http://hamasyou.com/"/>
  <updated>2017-12-22T11:43:15+09:00</updated>
  <id>http://hamasyou.com/</id>
  <author>
    <name><![CDATA[hamasyou]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[[iOS] ReSwift の State を RxSwift っぽく使えるようにする]]></title>
    <link href="http://hamasyou.com/blog/2017/05/10/swift-reswift-rxswift/"/>
    <updated>2017-05-10T11:08:30+09:00</updated>
    <id>http://hamasyou.com/blog/2017/05/10/swift-reswift-rxswift/</id>
    <content type="html"><![CDATA[<p>Swift ライブラリの <a href="https://github.com/ReSwift/ReSwift" rel="external nofollow" title="ReSwift">ReSwift</a> を <a href="https://github.com/ReactiveX/RxSwift" rel="external nofollow" title="RxSwift">RxSwift</a> に合わせて使えるようにするメモです。</p>

<h2>ReSwift とは</h2>

<p>ReSwift とは、iOS アプリを <a href="https://github.com/reactjs/redux" rel="external nofollow" title="Redux">Redux</a> のように作れるようにしてくれるライブラリです。</p>

<p>スマホアプリを作っていると</p>

<ul>
<li>アプリの状態管理を一元管理したい</li>
<li>アプリの状態が変わったら、UI を最新に更新したい</li>
</ul>


<p>という要求が出てくると思います。そんなときに、ReSwift でステートを一元管理し、UI の更新を RxSwift の I/F に合わせて使えると結構便利です。</p>

<!-- more -->


<h2>ソースコード</h2>

<p>ということで、メモ書きなので、さっとソースを貼り付けておきます。</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>
<span class="line-number">68</span>
<span class="line-number">69</span>
<span class="line-number">70</span>
<span class="line-number">71</span>
<span class="line-number">72</span>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="c1">/// アプリの `Store` クラス</span>
</span><span class="line"><span class="c1">/// Rx 拡張を行うために独自クラスを作成する</span>
</span><span class="line"><span class="k">class</span> <span class="nl">AppStore</span> <span class="p">:</span> <span class="n">Store</span><span class="o">&lt;</span><span class="n">AppState</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class="line">
</span><span class="line">    <span class="n">required</span> <span class="n">convenience</span> <span class="k">init</span><span class="p">(</span><span class="nl">reducer</span><span class="p">:</span> <span class="p">@</span><span class="n">escaping</span> <span class="p">(</span><span class="n">Action</span><span class="p">,</span> <span class="n">AppState</span><span class="o">?</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">AppState</span><span class="p">,</span> <span class="nl">state</span><span class="p">:</span> <span class="n">State</span><span class="o">?</span><span class="p">)</span> <span class="p">{</span>
</span><span class="line">        <span class="nb">self</span><span class="p">.</span><span class="k">init</span><span class="p">(</span><span class="nl">reducer</span><span class="p">:</span> <span class="n">reducer</span><span class="p">,</span> <span class="nl">state</span><span class="p">:</span> <span class="n">state</span><span class="p">,</span> <span class="nl">middleware</span><span class="p">:</span> <span class="p">[])</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line">
</span><span class="line"><span class="p">}</span>
</span><span class="line">
</span><span class="line"><span class="c1">/// AppStore を Rx 化するためのプロキシ</span>
</span><span class="line"><span class="k">class</span> <span class="n">AppStoreProxy</span><span class="o">&lt;</span><span class="n">SelectedState</span><span class="o">&gt;</span> <span class="o">:</span> <span class="n">StoreSubscriber</span> <span class="p">{</span>
</span><span class="line">
</span><span class="line">    <span class="k">typealias</span> <span class="n">StoreSubscriberStateType</span> <span class="o">=</span> <span class="n">SelectedState</span>
</span><span class="line">
</span><span class="line">    <span class="n">private</span> <span class="k">weak</span> <span class="k">var</span> <span class="nl">source</span><span class="p">:</span> <span class="n">AppStore</span><span class="o">?</span>
</span><span class="line">    <span class="n">private</span><span class="p">(</span><span class="kr">set</span><span class="p">)</span> <span class="k">var</span> <span class="n">subject</span> <span class="o">=</span> <span class="n">PublishSubject</span><span class="o">&lt;</span><span class="n">StoreSubscriberStateType</span><span class="o">&gt;</span><span class="p">()</span>
</span><span class="line">
</span><span class="line">    <span class="n">fileprivate</span> <span class="k">init</span><span class="p">(</span><span class="nl">source</span><span class="p">:</span> <span class="n">AppStore</span><span class="p">)</span> <span class="p">{</span>
</span><span class="line">        <span class="nb">self</span><span class="p">.</span><span class="n">source</span> <span class="o">=</span> <span class="n">source</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line">
</span><span class="line">    <span class="k">func</span> <span class="n">newState</span><span class="p">(</span><span class="nl">state</span><span class="p">:</span> <span class="n">StoreSubscriberStateType</span><span class="p">)</span> <span class="p">{</span>
</span><span class="line">        <span class="n">subject</span><span class="p">.</span><span class="n">on</span><span class="p">(.</span><span class="n">next</span><span class="p">(</span><span class="n">state</span><span class="p">))</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line">
</span><span class="line">    <span class="k">deinit</span> <span class="p">{</span>
</span><span class="line">        <span class="n">subject</span><span class="p">.</span><span class="n">on</span><span class="p">(.</span><span class="n">completed</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><span class="line"><span class="k">extension</span> <span class="nl">AppStore</span> <span class="p">:</span> <span class="n">ReactiveCompatible</span> <span class="p">{</span>
</span><span class="line"><span class="p">}</span>
</span><span class="line">
</span><span class="line">
</span><span class="line"><span class="k">extension</span> <span class="n">Reactive</span> <span class="k">where</span> <span class="nl">Base</span><span class="p">:</span> <span class="n">AppStore</span> <span class="p">{</span>
</span><span class="line">
</span><span class="line">    <span class="k">func</span> <span class="n">state</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">Observable</span><span class="o">&lt;</span><span class="n">AppStore</span><span class="p">.</span><span class="n">State</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class="line">        <span class="k">return</span> <span class="n">state</span> <span class="p">{</span> <span class="err">$</span><span class="mi">0</span> <span class="p">}</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line">
</span><span class="line">    <span class="k">func</span> <span class="n">state</span><span class="o">&lt;</span><span class="nl">SelectedState</span><span class="p">:</span> <span class="n">StateType</span><span class="o">&gt;</span><span class="p">(</span><span class="nl">selector</span><span class="p">:</span> <span class="p">@</span><span class="n">escaping</span> <span class="p">((</span><span class="n">AppStore</span><span class="p">.</span><span class="n">State</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">SelectedState</span><span class="p">))</span> <span class="o">-&gt;</span> <span class="n">Observable</span><span class="o">&lt;</span><span class="n">SelectedState</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class="line">        <span class="k">return</span> <span class="n">Observable</span><span class="p">.</span><span class="n">create</span> <span class="p">{</span> <span class="n">observer</span> <span class="k">in</span>
</span><span class="line">            <span class="k">let</span> <span class="n">proxy</span> <span class="o">=</span> <span class="n">AppStoreProxy</span><span class="o">&lt;</span><span class="n">SelectedState</span><span class="o">&gt;</span><span class="p">(</span><span class="nl">source</span><span class="p">:</span> <span class="nb">self</span><span class="p">.</span><span class="n">base</span><span class="p">)</span>
</span><span class="line">            <span class="n">_</span> <span class="o">=</span> <span class="n">proxy</span><span class="p">.</span><span class="n">subject</span><span class="p">.</span><span class="n">bind</span><span class="p">(</span><span class="nl">to</span><span class="p">:</span> <span class="n">observer</span><span class="p">)</span>
</span><span class="line">
</span><span class="line">            <span class="nb">self</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">subscribe</span><span class="p">(</span><span class="n">proxy</span><span class="p">,</span> <span class="nl">transform</span><span class="p">:</span> <span class="p">{</span> <span class="p">(</span><span class="nl">subscriber</span><span class="p">:</span> <span class="n">Subscription</span><span class="o">&lt;</span><span class="n">AppState</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Subscription</span><span class="o">&lt;</span><span class="n">SelectedState</span><span class="o">&gt;</span> <span class="k">in</span>
</span><span class="line">                <span class="n">subscriber</span><span class="p">.</span><span class="n">select</span><span class="p">(</span><span class="n">selector</span><span class="p">)</span>
</span><span class="line">            <span class="p">})</span>
</span><span class="line">
</span><span class="line">            <span class="k">return</span> <span class="n">Disposables</span><span class="p">.</span><span class="n">create</span> <span class="p">{</span>
</span><span class="line">                <span class="nb">self</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">unsubscribe</span><span class="p">(</span><span class="n">proxy</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="p">}</span>
</span><span class="line">
</span><span class="line">    <span class="k">func</span> <span class="n">state</span><span class="o">&lt;</span><span class="nl">SelectedState</span><span class="p">:</span> <span class="n">StateType</span> <span class="o">&amp;</span> <span class="n">Identifiable</span><span class="o">&gt;</span><span class="p">(</span><span class="nl">selector</span><span class="p">:</span> <span class="p">@</span><span class="n">escaping</span> <span class="p">((</span><span class="n">AppStore</span><span class="p">.</span><span class="n">State</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">SelectedState</span><span class="p">))</span> <span class="o">-&gt;</span> <span class="n">Observable</span><span class="o">&lt;</span><span class="n">SelectedState</span><span class="o">&gt;</span> <span class="p">{</span>
</span><span class="line">        <span class="k">return</span> <span class="n">Observable</span><span class="p">.</span><span class="n">create</span> <span class="p">{</span> <span class="n">observer</span> <span class="k">in</span>
</span><span class="line">            <span class="k">let</span> <span class="n">proxy</span> <span class="o">=</span> <span class="n">AppStoreProxy</span><span class="o">&lt;</span><span class="n">SelectedState</span><span class="o">&gt;</span><span class="p">(</span><span class="nl">source</span><span class="p">:</span> <span class="nb">self</span><span class="p">.</span><span class="n">base</span><span class="p">)</span>
</span><span class="line">            <span class="n">_</span> <span class="o">=</span> <span class="n">proxy</span><span class="p">.</span><span class="n">subject</span><span class="p">.</span><span class="n">bind</span><span class="p">(</span><span class="nl">to</span><span class="p">:</span> <span class="n">observer</span><span class="p">)</span>
</span><span class="line">
</span><span class="line">            <span class="nb">self</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">subscribe</span><span class="p">(</span><span class="n">proxy</span><span class="p">,</span> <span class="nl">transform</span><span class="p">:</span> <span class="p">{</span> <span class="p">(</span><span class="nl">subscriber</span><span class="p">:</span> <span class="n">Subscription</span><span class="o">&lt;</span><span class="n">AppState</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Subscription</span><span class="o">&lt;</span><span class="n">SelectedState</span><span class="o">&gt;</span> <span class="k">in</span>
</span><span class="line">                <span class="n">subscriber</span><span class="p">.</span><span class="n">select</span><span class="p">(</span><span class="n">selector</span><span class="p">)</span>
</span><span class="line">            <span class="p">})</span>
</span><span class="line">
</span><span class="line">            <span class="k">return</span> <span class="n">Disposables</span><span class="p">.</span><span class="n">create</span> <span class="p">{</span>
</span><span class="line">                <span class="nb">self</span><span class="p">.</span><span class="n">base</span><span class="p">.</span><span class="n">unsubscribe</span><span class="p">(</span><span class="n">proxy</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="p">}</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td>
</tr></table></div></figure>


<p>これで、ReSwift の <code>State</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="swift"><span class="line"><span class="n">store</span><span class="p">.</span><span class="n">rx</span><span class="p">.</span><span class="n">state</span> <span class="p">{</span> <span class="err">$</span><span class="mf">0.</span><span class="n">userState</span> <span class="p">}</span>
</span><span class="line">  <span class="p">.</span><span class="n">map</span> <span class="p">{</span> <span class="err">$</span><span class="mf">0.</span><span class="n">name</span> <span class="p">}</span>
</span><span class="line">  <span class="p">.</span><span class="n">bind</span><span class="p">(</span><span class="nl">to</span><span class="p">:</span> <span class="n">nameLabel</span><span class="p">.</span><span class="n">rx</span><span class="p">.</span><span class="n">text</span><span class="p">)</span>
</span><span class="line">  <span class="p">.</span><span class="n">disposed</span><span class="p">(</span><span class="nl">by</span><span class="p">:</span> <span class="n">disposeBag</span><span class="p">)</span>
</span></code></pre></td>
</tr></table></div></figure>


<h2>オブザーブしているステートが更新されたときのみ通知して欲しい時</h2>

<p>ReSwift を RxSwift のように使うだけであれば、上の拡張でいいのですが、たくさんステートが出来てくると、
関係ないステートが更新されたときにも変更が通知されてしまって、パフォーマンスを気にすることが出てくるかもしれません。</p>

<p>そんなときは、<code>distinctUntilChanged</code> を使って、監視しているステートが更新されたかどうかを確認するようにするといいと思います。</p>

<p><code>State</code> 自体を <code>==</code> で比較できるように、State に <code>Identifier</code> を導入して、更新されたかどうかをチェック出来るようにしてみます。
(というのも、State は構造体(<code>struct</code>) で作ることになると思うので、同一のステートかどうかの一致が大変なのです。)</p>

<h3>State に一意性を持たせる</h3>

<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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="c1">/// 識別子コンポーネント</span>
</span><span class="line"><span class="k">struct</span> <span class="nl">IdentifiableComponent</span> <span class="p">:</span> <span class="n">Hashable</span> <span class="p">{</span>
</span><span class="line">
</span><span class="line">    <span class="k">typealias</span> <span class="n">Identifier</span> <span class="o">=</span> <span class="n">UInt64</span>
</span><span class="line">
</span><span class="line">    <span class="c1">/// インスタンス生成毎に一意になる値を生成するクラス</span>
</span><span class="line">    <span class="n">private</span> <span class="k">struct</span> <span class="n">Counter</span> <span class="p">{</span>
</span><span class="line">        <span class="k">static</span> <span class="k">let</span> <span class="n">lock</span> <span class="o">=</span> <span class="n">DispatchSemaphore</span><span class="p">(</span><span class="nl">value</span><span class="p">:</span> <span class="mi">1</span><span class="p">)</span>
</span><span class="line">        <span class="k">static</span> <span class="k">var</span> <span class="nl">count</span><span class="p">:</span> <span class="n">Identifier</span> <span class="o">=</span> <span class="mi">0</span>
</span><span class="line">        <span class="k">static</span> <span class="k">func</span> <span class="n">getAndIncrement</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">Identifier</span> <span class="p">{</span>
</span><span class="line">            <span class="n">lock</span><span class="p">.</span><span class="n">wait</span><span class="p">()</span>
</span><span class="line">            <span class="n">defer</span> <span class="p">{</span> <span class="n">lock</span><span class="p">.</span><span class="n">signal</span><span class="p">()</span> <span class="p">}</span>
</span><span class="line">            <span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span>
</span><span class="line">            <span class="k">return</span> <span class="n">count</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">/// インスタンスの識別子</span>
</span><span class="line">    <span class="n">private</span><span class="p">(</span><span class="kr">set</span><span class="p">)</span> <span class="k">var</span> <span class="nl">identifier</span><span class="p">:</span> <span class="n">Identifier</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">.</span><span class="n">getAndIncrement</span><span class="p">()</span>
</span><span class="line">
</span><span class="line">    <span class="k">var</span> <span class="nl">hashValue</span><span class="p">:</span> <span class="n">Int</span> <span class="p">{</span> <span class="k">return</span> <span class="n">identifier</span><span class="p">.</span><span class="n">hashValue</span> <span class="p">}</span>
</span><span class="line">
</span><span class="line">    <span class="kr">mutating</span> <span class="k">func</span> <span class="n">update</span><span class="p">()</span> <span class="p">{</span>
</span><span class="line">        <span class="n">identifier</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">.</span><span class="n">getAndIncrement</span><span class="p">()</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line">
</span><span class="line">    <span class="k">static</span> <span class="k">func</span> <span class="o">==</span><span class="p">(</span><span class="nl">lhs</span><span class="p">:</span> <span class="n">IdentifiableComponent</span><span class="p">,</span> <span class="nl">rhs</span><span class="p">:</span> <span class="n">IdentifiableComponent</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Bool</span> <span class="p">{</span>
</span><span class="line">        <span class="k">return</span> <span class="n">lhs</span><span class="p">.</span><span class="n">identifier</span> <span class="o">==</span> <span class="n">rhs</span><span class="p">.</span><span class="n">identifier</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line"><span class="p">}</span>
</span><span class="line">
</span><span class="line"><span class="k">protocol</span> <span class="nl">HasIdentifiableComponent</span> <span class="p">:</span> <span class="n">Equatable</span> <span class="p">{</span>
</span><span class="line">    <span class="k">var</span> <span class="nl">identifiableComponent</span><span class="p">:</span> <span class="n">IdentifiableComponent</span> <span class="p">{</span> <span class="kr">get</span> <span class="p">}</span>
</span><span class="line"><span class="p">}</span>
</span><span class="line">
</span><span class="line"><span class="c1">/// 識別子を持つタイプ</span>
</span><span class="line"><span class="k">protocol</span> <span class="nl">Identifiable</span> <span class="p">:</span> <span class="n">HasIdentifiableComponent</span> <span class="p">{</span>
</span><span class="line"><span class="p">}</span>
</span><span class="line">
</span><span class="line"><span class="k">extension</span> <span class="n">Identifiable</span> <span class="p">{</span>
</span><span class="line">
</span><span class="line">    <span class="k">var</span> <span class="nl">identifier</span><span class="p">:</span> <span class="n">IdentifiableComponent</span><span class="p">.</span><span class="n">Identifier</span> <span class="p">{</span>
</span><span class="line">        <span class="k">return</span> <span class="n">identifiableComponent</span><span class="p">.</span><span class="n">identifier</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line">
</span><span class="line">    <span class="k">static</span> <span class="k">func</span> <span class="o">==</span><span class="p">(</span><span class="nl">lhs</span><span class="p">:</span> <span class="kt">Self</span><span class="p">,</span> <span class="nl">rhs</span><span class="p">:</span> <span class="kt">Self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Bool</span> <span class="p">{</span>
</span><span class="line">        <span class="k">return</span> <span class="n">lhs</span><span class="p">.</span><span class="n">identifiableComponent</span> <span class="o">==</span> <span class="n">rhs</span><span class="p">.</span><span class="n">identifiableComponent</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>複雑そうなことをやっていますが、要はインスタンスを生成するたびに一意の数値を割り当てて、
状態が更新されたらその値をインクリメントするという方法で、数値比較だけで状態が変わったかを判断できるようにしています。</p>

<p>この識別子コンポーネントを State に持たせるようにして</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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="k">struct</span> <span class="nl">UserState</span> <span class="p">:</span> <span class="n">StateType</span><span class="p">,</span> <span class="n">Identifiable</span> <span class="p">{</span>
</span><span class="line">
</span><span class="line">  <span class="n">fileprivate</span><span class="p">(</span><span class="kr">set</span><span class="p">)</span> <span class="k">var</span> <span class="n">identifiableComponent</span> <span class="o">=</span> <span class="n">IdentifiableComponent</span><span class="p">()</span>
</span><span class="line">
</span><span class="line">  <span class="k">var</span> <span class="nl">name</span><span class="p">:</span> <span class="n">String</span><span class="o">?</span>
</span><span class="line"><span class="p">}</span>
</span><span class="line">
</span><span class="line"><span class="c1">// MARK: - Reducer</span>
</span><span class="line"><span class="k">extension</span> <span class="n">UserState</span> <span class="p">{</span>
</span><span class="line">    <span class="k">static</span> <span class="k">func</span> <span class="n">reducer</span><span class="p">(</span><span class="nl">state</span><span class="p">:</span> <span class="n">UserState</span><span class="o">?</span><span class="p">,</span> <span class="nl">action</span><span class="p">:</span> <span class="n">Action</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">UserState</span> <span class="p">{</span>
</span><span class="line">        <span class="k">var</span> <span class="n">state</span> <span class="o">=</span> <span class="n">state</span> <span class="o">??</span> <span class="n">UserState</span><span class="p">()</span>
</span><span class="line">
</span><span class="line">        <span class="k">switch</span> <span class="n">action</span> <span class="p">{</span>
</span><span class="line">        <span class="k">case</span> <span class="k">let</span> <span class="n">action</span> <span class="kt">as</span> <span class="n">UserActions</span><span class="p">.</span><span class="nl">SetName</span><span class="p">:</span>
</span><span class="line">            <span class="n">state</span><span class="p">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">action</span><span class="p">.</span><span class="n">name</span>
</span><span class="line">            <span class="n">state</span><span class="p">.</span><span class="n">identifiableComponent</span><span class="p">.</span><span class="n">update</span><span class="p">()</span>
</span><span class="line">
</span><span class="line">        <span class="k">default</span><span class="o">:</span>
</span><span class="line">            <span class="k">break</span>
</span><span class="line">        <span class="p">}</span>
</span><span class="line">
</span><span class="line">        <span class="k">return</span> <span class="n">state</span>
</span><span class="line">    <span class="p">}</span>
</span></code></pre></td>
</tr></table></div></figure>


<p>こんな感じで、ステートが更新したときに、<code>identifiableComponent.update()</code> を呼び出すと状態が更新されたことをマークします。
これで、ステートが更新されたときだけ UI を更新するようなコードを次のように書けるようになります。</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="swift"><span class="line"><span class="n">store</span><span class="p">.</span><span class="n">rx</span><span class="p">.</span><span class="n">state</span> <span class="p">{</span> <span class="err">$</span><span class="mf">0.</span><span class="n">userState</span> <span class="p">}</span>
</span><span class="line">  <span class="p">.</span><span class="n">distinctUntilChanged</span><span class="p">()</span>
</span><span class="line">  <span class="p">.</span><span class="n">map</span> <span class="p">{</span> <span class="err">$</span><span class="mf">0.</span><span class="n">name</span> <span class="p">}</span>
</span><span class="line">  <span class="p">.</span><span class="n">bind</span><span class="p">(</span><span class="nl">to</span><span class="p">:</span> <span class="n">nameLabel</span><span class="p">.</span><span class="n">rx</span><span class="p">.</span><span class="n">text</span><span class="p">)</span>
</span><span class="line">  <span class="p">.</span><span class="n">disposed</span><span class="p">(</span><span class="nl">by</span><span class="p">:</span> <span class="n">disposeBag</span><span class="p">)</span>
</span></code></pre></td>
</tr></table></div></figure>


<p>パフォーマンスも気にせず使えるようになりました。</p>

<p>既存のプロジェクトからの抜粋なので、一部省略している箇所があります。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Game Programming Patterns ソフトウェア開発の問題解決メニュー (impress top gear)]]></title>
    <link href="http://hamasyou.com/blog/2015/12/16/9784844338901/"/>
    <updated>2015-12-16T09:38:35+09:00</updated>
    <id>http://hamasyou.com/blog/2015/12/16/9784844338901/</id>
    <content type="html"><![CDATA[<p>読了。後で書く。</p>

<!-- more -->


<h2>目次</h2>

<ul>
<li>Part I　イントロダクション

<ul>
<li>第1章　アーキテクチャ、実行速度、ゲーム</li>
</ul>
</li>
<li>Part Ⅱ　デザインパターン再訪

<ul>
<li>第2章　コマンド</li>
<li>第3章　フライウェイト</li>
<li>第4章　オブザーバ</li>
<li>第5章　プロトタイプ</li>
<li>第6章　シングルトン</li>
<li>第7章　ステート</li>
</ul>
</li>
<li>Part Ⅲ　シーケンスのパターン

<ul>
<li>第8章　ダブルバッファ</li>
<li>第9章　ゲームループ</li>
<li>第10章　更新メソッド</li>
</ul>
</li>
<li>Part IV　ビヘイビアのパターン

<ul>
<li>第11章　バイトコード</li>
<li>第12章　サブクラスサンドボックス</li>
<li>第13章　型オブジェクト</li>
</ul>
</li>
<li>Part V　分離のパターン

<ul>
<li>第14章　コンポーネント</li>
<li>第15章　イベントキュー</li>
<li>第16章　サービスロケータ</li>
</ul>
</li>
<li>Part VI　最適化のパターン

<ul>
<li>第17章　データ局所化</li>
<li>第18章　ダーティフラグ</li>
<li>第19章　オブジェクトプール</li>
<li>第20章　空間分割</li>
</ul>
</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[ゲームエンジン・アーキテクチャ 第2版]]></title>
    <link href="http://hamasyou.com/blog/2015/12/16/9784797377484/"/>
    <updated>2015-12-16T09:26:45+09:00</updated>
    <id>http://hamasyou.com/blog/2015/12/16/9784797377484/</id>
    <content type="html"><![CDATA[<p>読了。後で書く。</p>

<!-- more -->


<h2>目次</h2>

<ul>
<li>第1部 基盤

<ul>
<li>第1章 イントロダクション</li>
<li>第2章 仕事用ツール</li>
<li>第3章 ゲームのためのソフトウェアエンジニアリングの基本</li>
<li>第4章 ゲームのための3D計算</li>
</ul>
</li>
<li>第2部 低レベルエンジンシステム

<ul>
<li>第5章 エンジンサポートシステム</li>
<li>第6章 リソースとファイルシステム</li>
<li>第7章 ゲームループとリアルタイムシミュレーション</li>
<li>第8章 ヒューマンインターフェイスデバイス（HID）</li>
<li>第9章 デバッグおよび開発のツール</li>
</ul>
</li>
<li>第3部 グラフィックス、モーション、サウンド

<ul>
<li>第10章 レンダリングエンジン</li>
<li>第11章 アニメーションシステム</li>
<li>第12章 コリジョンと剛体力学</li>
<li>第13章 オーディオ</li>
</ul>
</li>
<li>第4部 ゲームプレイ

<ul>
<li>第14章 ゲームプレイシステムの概要</li>
<li>第15章 ランタイムのゲームプレイ基本システム</li>
</ul>
</li>
<li>第5部 まとめ

<ul>
<li>第16章 まだやることがあるってこと？</li>
</ul>
</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[ゲームデザイナーのための空間設計 歴史的建造物から学ぶレベルデザイン]]></title>
    <link href="http://hamasyou.com/blog/2015/12/16/9784862462619/"/>
    <updated>2015-12-16T09:22:57+09:00</updated>
    <id>http://hamasyou.com/blog/2015/12/16/9784862462619/</id>
    <content type="html"><![CDATA[<p>読了。後で書く。</p>

<!-- more -->


<h2>目次</h2>

<ul>
<li>Chapter1 建造物からレベルデザインを学ぶ準備

<ul>
<li>これから見ていく準備段階として、建築史の概要を学びます。</li>
</ul>
</li>
<li>Chapter2 レベルデザインのツールとテクニック

<ul>
<li>空間の設計に便利な意匠図や視覚化の方法を説明します。</li>
</ul>
</li>
<li>Chapter3 基本的な空間配置とゲーム空間の種類

<ul>
<li>ゲーム空間を分析して、設計に使用できるタイプを特定します。</li>
</ul>
</li>
<li>Chapter4 ビジュアル要素によるチュートリアル

<ul>
<li>プレイヤーにゲームのメカニクスを教える方法を紹介します。</li>
</ul>
</li>
<li>Chapter5 生存本能を利用したレベルデザイン

<ul>
<li>感情を動かし、プレイヤーを促すテクニックを取り上げます。</li>
</ul>
</li>
<li>Chapter6 報酬の空間でプレイヤーを誘い込む

<ul>
<li>心理学を利用し、プレイヤーに報酬を与える方法を説明します。</li>
</ul>
</li>
<li>Chapter7 ゲーム空間におけるストーリーテリング

<ul>
<li>ストーリーを語り、円滑に進める空間構築の方法を探求します。</li>
</ul>
</li>
<li>Chapter8 インタラクティブ空間とワールドデザイン

<ul>
<li>空間を概観し、庭園デザインの手法を活かす方法を紹介します。</li>
</ul>
</li>
<li>Chapter9 プレイヤーの交流を生み出すレベルデザイン

<ul>
<li>プレイヤーの交流を促す方法を、都市デザインに学びます。</li>
</ul>
</li>
<li>Chapter10 サウンドによるレベルデザインの強化

<ul>
<li>リズムの効果を知り、空間効果を増幅させる方法を見ていきます。</li>
</ul>
</li>
<li>Chapter11 現実世界を舞台にしたレベルデザイン

<ul>
<li>都市や屋外空間でプレイするゲームに、空間原理を応用します。</li>
</ul>
</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[売れるゲームのUI/UX 制作現場の舞台裏]]></title>
    <link href="http://hamasyou.com/blog/2015/12/16/9784844365242/"/>
    <updated>2015-12-16T09:18:42+09:00</updated>
    <id>http://hamasyou.com/blog/2015/12/16/9784844365242/</id>
    <content type="html"><![CDATA[<p>読了。後で書く。</p>

<!-- more -->


<h2>目次</h2>

<ul>
<li>第1章 ゲーム開発者に欠かせないUI/UXの基礎知識

<ul>
<li>「ユーザー体験の創造」と「ナビゲーションの最適化」</li>
<li>各デバイス/プラットフォームの特性を押さえる</li>
<li>スマートデバイスゲームにおけるUI/UX設計のヒントを探る</li>
<li>コンソールゲームにおけるUI/UX設計のヒントを探る</li>
<li>アーケードゲームにおけるUI/UX設計のヒントを探る</li>
</ul>
</li>
<li>第2章 スマートデバイスゲームのUI/UX

<ul>
<li>白猫プロジェクト(コロプラ)</li>
<li>にゃんこ大戦争(PONOS)</li>
<li>ぼくらの甲子園! ポケット(面白法人カヤック)</li>
<li>モンスターストライク(ミクシィ)</li>
</ul>
</li>
<li>第3章 コンソールゲームのUI/UX

<ul>
<li>ファイナルファンタジーXIV: 新生エオルゼア(スクウェア・エニックス)</li>
<li>D4: Dark Dreams Don’t Die(アクセスゲームズ)</li>
<li>フェアルーン(フライハイワークス/スキップモア)</li>
</ul>
</li>
<li>第4章 アーケードゲームのUI/UX

<ul>
<li>戦国大戦(セガ・インタラクティブ)</li>
<li>ガンスリンガー ストラトス2(スクウェア・エニックス/バイキング)</li>
</ul>
</li>
<li>第5章 UI/UXの歴史を紐解き、これからの技術動向を考える

<ul>
<li>ゲームUI/UXのこれまでとAIが拓く未来</li>
<li>ゲームの世界に欠かせない3D立体視の基礎</li>
<li>VRが生み出す新しいゲームUI/UXの世界</li>
</ul>
</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[シングルページWebアプリケーション ―Node.js、MongoDBを活用したJavaScript SPA]]></title>
    <link href="http://hamasyou.com/blog/2015/12/16/9784873116730/"/>
    <updated>2015-12-16T09:12:25+09:00</updated>
    <id>http://hamasyou.com/blog/2015/12/16/9784873116730/</id>
    <content type="html"><![CDATA[<p>読了。後で書く。</p>

<!-- more -->


<h2>目次</h2>

<ul>
<li>まえがき</li>
<li>はじめに</li>
<li>本書について</li>
<li>I部　SPAの紹介</li>
<li>1章　最初のシングルページアプリケーション

<ul>
<li>1.1　定義、簡単な歴史、重点事項</li>
<li>1.2　最初の SPAを構築する</li>
<li>1.3　適切に記述されたSPAのユーザメリット</li>
<li>1.4　まとめ</li>
</ul>
</li>
<li>2章　JavaScriptのおさらい

<ul>
<li>2.1　変数スコープ</li>
<li>2.2　変数の巻き上げ</li>
<li>2.3　高度な変数の巻き上げと実行コンテキストオブジェクト</li>
<li>2.4　スコープチェーン</li>
<li>2.5　JavaScriptオブジェクトとプロトタイプチェーン</li>
<li>2.6　関数 .詳しく調べる</li>
<li>2.7　まとめ</li>
</ul>
</li>
<li>II部　SPAクライアント</li>
<li>3章　シェルの開発

<ul>
<li>3.1　シェルを完全に把握する</li>
<li>3.2　ファイルと名前空間を用意する</li>
<li>3.3　機能コンテナを作成する</li>
<li>3.4　機能コンテナをレンダリングする</li>
<li>3.5　機能コンテナを管理する</li>
<li>3.6　アプリケーション状態を管理する</li>
<li>3.7　まとめ</li>
</ul>
</li>
<li>4章　機能モジュールの追加

<ul>
<li>4.1　機能モジュール方式</li>
<li>4.2　機能モジュールファイルを用意する</li>
<li>4.3　メソッド APIを設計する</li>
<li>4.4　機能 APIを実装する</li>
<li>4.5　頻繁に必要となるメソッドを追加する</li>
<li>4.6　まとめ</li>
</ul>
</li>
<li>5章　モデルの構築

<ul>
<li>5.1　モデルを理解する</li>
<li>5.2　モデルとその他のファイルを用意する</li>
<li>5.3　peopleオブジェクトを設計する</li>
<li>5.4　peopleオブジェクトを構築する</li>
<li>5.5　シェルでサインインとサインアウトを可能にする</li>
<li>5.6　まとめ</li>
</ul>
</li>
<li>6章　モデルとデータモジュールの完成

<ul>
<li>6.1　chatオブジェクトを設計する</li>
<li>6.2　chatオブジェクトを構築する</li>
<li>6.3　モデルにアバターサポートを追加する</li>
<li>6.4　チャット機能モジュールを完成させる</li>
<li>6.5　アバター機能モジュールを作成する</li>
<li>6.6　データバインディングと jQuery</li>
<li>6.7　データモジュールを作成する</li>
<li>6.8　まとめ</li>
</ul>
</li>
<li>III部　SPAサーバ</li>
<li>7章　 Webサーバ

<ul>
<li>7.1　サーバの役割</li>
<li>7.2　Node.js</li>
<li>7.3　高度なルーティング</li>
<li>7.4　認証と認可を追加する</li>
<li>7.5　WebSocketとSocket.IO</li>
<li>7.6　まとめ</li>
</ul>
</li>
<li>8章　サーバデータベース

<ul>
<li>8.1　データベースの役割</li>
<li>8.2　MongoDBとは</li>
<li>8.3　MongoDBドライバを使う</li>
<li>8.4　クライアントデータを検証する</li>
<li>8.5　個別の CRUDモジュールを作成する</li>
<li>8.6　チャットモジュールを構築する</li>
<li>8.7　まとめ</li>
</ul>
</li>
<li>9章　 SPAを本番環境に備える

<ul>
<li>9.1　SPAを検索エンジンに対して最適化する</li>
<li>9.2　クラウドサービスとサードパーティサービス</li>
<li>9.3　キャッシングとキャッシュバスティング</li>
<li>9.4　まとめ</li>
</ul>
</li>
<li>付録A　JavaScriptコーディング標準

<ul>
<li>A.1　なぜコーディング標準が必要なのか</li>
<li>A.2　コードレイアウトとコメント</li>
<li>A.3　変数名</li>
<li>A.4　変数の宣言と割り当て</li>
<li>A.5　関数</li>
<li>A.6　名前空間</li>
<li>A.7　ファイル名とレイアウト</li>
<li>A.8　構文</li>
<li>A.9　コードを検証する</li>
<li>A.10　モジュール用のテンプレート</li>
<li>A.11　まとめ</li>
</ul>
</li>
<li>付録B　SPAのテスト

<ul>
<li>B.1　テストモードを準備する</li>
<li>B.2　テストフレームワークを選ぶ</li>
<li>B.3　nodeunitを準備する</li>
<li>B.4　テストスイートを作成する</li>
<li>B.5　テストに合わせて SPAモジュールを調整する</li>
<li>B.6　まとめ</li>
</ul>
</li>
<li>索引</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Reactive Extensions Basic]]></title>
    <link href="http://hamasyou.com/blog/2015/12/15/reactive-extensions-basic/"/>
    <updated>2015-12-15T11:11:45+09:00</updated>
    <id>http://hamasyou.com/blog/2015/12/15/reactive-extensions-basic/</id>
    <content type="html"><![CDATA[<p><strong class="text-danger">Reactive Extensions (Rx)</strong> の覚書です。主に RxSwift をベースにしていますが、ReactiveX 全般に通じると思います。</p>

<p>細かいニュアンスは間違っているかも。。</p>

<p>基本用語の整理です。</p>

<!-- more -->




<div id="toc"></div>


<h2>Reactive Extensions</h2>

<p>大雑把に言うと、<strong class="text-danger">Observer Pattern (オブザーバパターン)</strong> と <strong class="text-danger">Stream/Sequence Programming</strong> を合わせたものが <strong class="text-danger">Reactive Extensions</strong> です。</p>

<h3>Observable</h3>

<p>オブザーバパターンにおいて、観測される対象を Subject と呼びますが、Rx では観測される対象のことを <strong class="text-danger">Observable</strong> と呼びます。観測する側は <em>Observer (オブザーバ）</em> なので、観測される側は <em>Observable</em> なわけです。</p>

<p>Rx では、Observable なものを <code>subscribe</code> (購読) することで、Observable から送られてくるデータを受け取ります。この、Observable からデータが流れてくることを <strong class="text-danger">Stream (ストリーム)</strong> と呼びます。流れてくるデータは <strong class="text-danger">Element</strong> と呼ばれます。</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="swift"><span class="line"><span class="n">someObservable</span>
</span><span class="line">    <span class="p">.</span><span class="n">subscribe</span> <span class="p">{</span> <span class="p">(</span><span class="nl">e</span><span class="p">:</span> <span class="n">Event</span><span class="o">&lt;</span><span class="n">Element</span><span class="o">&gt;</span><span class="p">)</span> <span class="k">in</span>
</span><span class="line">        <span class="k">switch</span> <span class="n">e</span> <span class="p">{</span>
</span><span class="line">        <span class="k">case</span> <span class="p">.</span><span class="n">Next</span><span class="p">(</span><span class="k">let</span> <span class="n">val</span><span class="p">)</span><span class="o">:</span>
</span><span class="line">        <span class="k">case</span> <span class="p">.</span><span class="n">Error</span><span class="p">(</span><span class="k">let</span> <span class="n">error</span><span class="p">)</span><span class="o">:</span>
</span><span class="line">        <span class="k">case</span> <span class="p">.</span><span class="nl">Completed</span><span class="p">:</span>
</span><span class="line">        <span class="p">}</span>
</span><span class="line">    <span class="p">.</span><span class="n">scopedDispose</span><span class="p">()</span>
</span></code></pre></td>
</tr></table></div></figure>


<p>ストリームには状態が3種類あり、それぞれ <code>Next</code>、<code>Error</code>、<code>Completed</code> になります。</p>

<h4>Next</h4>

<p>ストリームから次のデータが流れてきたことを表します。正常処理と考えて構いません。</p>

<h4>Error</h4>

<p>Observable な対象が何かしらエラーを起こし、観測したかったデータが流れてこなかったことを表します。Rx では、Error を起こしたストリームは閉じられます。つまり、次のデータが流れてこないことを表します。</p>

<h4>Completed</h4>

<p>Observable な対象のストリームが閉じられ、この Observable な対象からは今後データが流れてこないことを表します。</p>

<h4>dispose</h4>

<p>観測を取りやめたい時には、<code>dispose</code> を呼び出します。いつ dispose するかを使い分けられるように、<code>Dispose</code> の実装がいろいろあります。</p>

<h3>Subject</h3>

<p><strong class="text-danger">Observable</strong> は観測対象のことでしたが、Rx においては観測可能な事柄のことを <strong class="text-danger">Subject (事象)</strong> と呼ぶほうが一般的だったりします。Subject を観測するわけですが、観測するデータのことは <strong class="text-danger">Behavior (振る舞い)</strong> と呼ばれます。<code>Subject</code> / <code>Behavior</code> は Reactive Extensions における一般的な説明となりますが、こと Rx Programming においては、<code>Observable</code> と <code>Subject</code>、<code>Element</code> と <code>Behavior</code> は似て非なるものとして扱われています。</p>

<h2>Hot and Cold Observables</h2>

<p>Observable な対象は、2つの種類にわけられます。<code>Hot</code> と <code>Cold</code> です。</p>

<h3>Hot Observable</h3>

<p>Hot な Observable とは、観測対象である Observable が作られたときから、任意のタイミングでデータを送信することができるものになります。</p>

<p>実はこの Hot Observable のことを、Rx Programming では <em>Subject</em> と呼ばれています。Subject は任意のタイミングでデータをストリームに流すことができ、同時に Observable なわけです。</p>

<p>Subject は任意のタイミングで <strong class="text-danger">Behavior (振る舞い)</strong> を決められることから、Subject / Behavior はセットで使われる言葉になります。</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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="k">let</span> <span class="n">msg</span> <span class="o">=</span> <span class="n">PublishSubject</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span><span class="p">()</span>
</span><span class="line">
</span><span class="line"><span class="n">msg</span><span class="p">.</span><span class="n">subscribeNext</span> <span class="p">{</span> <span class="n">print</span><span class="p">(</span><span class="err">$</span><span class="mi">0</span><span class="p">)</span> <span class="p">}</span>
</span><span class="line">
</span><span class="line"><span class="n">msg</span><span class="p">.</span><span class="n">onNext</span><span class="p">(</span><span class="s">"Hello World"</span><span class="p">)</span>
</span><span class="line"><span class="n">msg</span><span class="p">.</span><span class="n">onCompleted</span><span class="p">()</span>
</span></code></pre></td>
</tr></table></div></figure>


<h3>Cold Observable</h3>

<p>Cold な Obserable は、任意のタイミングでデータを流すことができません。いつデータが流れてくるのかわかりませんし、観測対象がいなければ、そもそも振る舞いが起きることもありません。</p>

<p>よく、API 通信を Observable にしますが、subscribe (観測) を忘れると、API 呼び出しがされないことになりますので注意が必要です。</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="swift"><span class="line"><span class="n">API</span><span class="p">.</span><span class="n">call</span><span class="p">()</span>
</span><span class="line">    <span class="p">.</span><span class="n">subscribeNext</span> <span class="p">{</span>
</span><span class="line">        <span class="c1">// When to occur?</span>
</span><span class="line">    <span class="p">}</span>
</span></code></pre></td>
</tr></table></div></figure>


<h2>Rx でプログラミングすると何が嬉しいか</h2>

<h3>テスタビリティが向上</h3>

<p>Rx は UI プログラミングで語られることが多いと思いますが、プログラムのあらゆる境界を Observable でつなぐことで、テスタビリティが向上します。</p>

<p>Observable でつなぐことにより、直接のデータの生成元に依存せずにプログラムを記述することができるようになるので、テスト時だけデータ生成部分をいじることで、例えば API 通信結果を画面に表示するようなプログラムでも、API 通信を行うことなくデータを生成し、Stream に流すことで色々な依存関係を排除することが出来るのです。</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="swift"><span class="line"><span class="k">func</span> <span class="nf">something</span><span class="p">(</span><span class="nl">dataSource</span><span class="p">:</span> <span class="n">Observable</span><span class="o">&lt;</span><span class="n">DataSource</span><span class="o">&gt;</span><span class="p">)</span> <span class="p">{</span>
</span><span class="line">    <span class="n">dataSource</span><span class="p">.</span>
</span><span class="line">        <span class="n">subscribeNext</span> <span class="p">{</span>
</span><span class="line">            <span class="c1">// do something</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">// development</span>
</span><span class="line"><span class="n">something</span><span class="p">(</span><span class="n">API</span><span class="p">.</span><span class="n">call</span><span class="p">())</span>
</span><span class="line"><span class="c1">// test</span>
</span><span class="line"><span class="n">something</span><span class="p">(</span><span class="n">just</span><span class="p">(</span><span class="n">DummyDataSource</span><span class="p">()))</span>
</span></code></pre></td>
</tr></table></div></figure>


<h3>非同期処理</h3>

<p>また、Rx には Stream の観測を任意のスレッドで行うスケジューリングの機能が備わっているものがほとんどですので、時間の掛かるデータ生成処理はバックグラウンドで行い、UI の表示処理のところだけメインスレッドで行うといったことを容易に行なえます。</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="swift"><span class="line"><span class="n">API</span><span class="p">.</span><span class="n">call</span><span class="p">()</span>
</span><span class="line">    <span class="p">.</span><span class="n">map</span> <span class="p">{</span> <span class="err">$</span><span class="mf">0.</span><span class="n">toViewModel</span><span class="p">()</span> <span class="p">}</span>
</span><span class="line">    <span class="p">.</span><span class="n">subscribeOn</span><span class="p">(</span><span class="n">BackgroundScheduler</span><span class="p">.</span><span class="n">sharedInstance</span><span class="p">)</span>
</span><span class="line">    <span class="p">.</span><span class="n">observeOn</span><span class="p">(</span><span class="n">MainScheduler</span><span class="p">.</span><span class="n">sharedInstance</span><span class="p">)</span>
</span><span class="line">    <span class="p">.</span><span class="n">subscribeNext</span> <span class="p">{</span> <span class="p">(</span><span class="n">viewModel</span><span class="p">)</span> <span class="k">in</span>
</span><span class="line">        <span class="c1">// UI バインディング</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line">    <span class="p">.</span><span class="n">addDisposeBag</span><span class="p">(</span><span class="n">disposeBag</span><span class="p">)</span>
</span></code></pre></td>
</tr></table></div></figure>


<h3>データソースの更新をリアルタイムに同期</h3>

<p>プログラムを書いていると、データソースの値を加工して別のところで使うという場面が多々あります。</p>

<p>このとき、何も考えずにプログラムすると、データソースが変更されても結果は変わらないという挙動になります。</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="swift"><span class="line"><span class="k">var</span> <span class="n">a</span> <span class="o">=</span> <span class="mi">1</span>
</span><span class="line"><span class="k">var</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">2</span>
</span><span class="line"><span class="k">var</span> <span class="n">c</span> <span class="o">=</span> <span class="s">""</span>
</span><span class="line">
</span><span class="line"><span class="k">if</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="p">{</span>
</span><span class="line">    <span class="n">c</span> <span class="o">=</span> <span class="s">"\(a + b) is positive"</span>
</span><span class="line"><span class="p">}</span>
</span><span class="line">
</span><span class="line"><span class="n">a</span> <span class="o">=</span> <span class="mi">4</span>
</span><span class="line">
</span><span class="line"><span class="n">print</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>        <span class="c1">// ""</span>
</span></code></pre></td>
</tr></table></div></figure>


<p>こういった挙動でかまわないという場合もあるでしょうが、ほとんどの場合データソースの変化に合わせて挙動が変わってくれたほうが嬉しかったりします。そんな時は全部 Observable にします。</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="swift"><span class="line"><span class="k">let</span> <span class="n">a</span> <span class="o">=</span> <span class="n">Variable</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</span><span class="line"><span class="k">let</span> <span class="n">b</span> <span class="o">=</span> <span class="n">Variable</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
</span><span class="line">
</span><span class="line"><span class="k">let</span> <span class="n">c</span> <span class="o">=</span> <span class="n">combineLatest</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span> <span class="err">$</span><span class="mi">0</span> <span class="o">+</span> <span class="err">$</span><span class="mi">1</span> <span class="p">}</span>
</span><span class="line">            <span class="p">.</span><span class="n">filter</span> <span class="p">{</span> <span class="err">$</span><span class="mi">0</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="p">}</span>
</span><span class="line">            <span class="p">.</span><span class="n">map</span> <span class="p">{</span> <span class="err">\</span><span class="p">(</span><span class="err">$</span><span class="mi">0</span><span class="p">)</span> <span class="kt">is</span> <span class="n">positive</span><span class="s">" }            </span>
</span><span class="line">
</span><span class="line"><span class="n">c</span><span class="p">.</span><span class="n">subscribeNext</span> <span class="p">{</span>
</span><span class="line">    <span class="n">print</span><span class="p">(</span><span class="err">$</span><span class="mi">0</span><span class="p">)</span>
</span><span class="line"><span class="p">}</span>
</span><span class="line">
</span><span class="line"><span class="n">a</span><span class="p">.</span><span class="n">value</span> <span class="o">=</span> <span class="mi">4</span>
</span></code></pre></td>
</tr></table></div></figure>


<h2>Operators</h2>

<p>Rx には、Stream を操作するためのいろいろな演算が用意されています。Stream を別の形に変換する <code>map</code> や、複数の Stream を結合する <code>merge</code> や <code>concat</code> がなどがあります。</p>

<p>Stream の合成は使いドコロとしては API 通信などの時間の掛かる処理とキャッシュデータを返すストリームとを合成するなどが考えられます。</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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="n">sequenceOf</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
</span><span class="line">    <span class="p">.</span><span class="n">map</span> <span class="p">{</span> <span class="err">$</span><span class="mi">0</span> <span class="o">*</span> <span class="err">$</span><span class="mi">0</span> <span class="p">}</span>
</span><span class="line">    <span class="p">.</span><span class="n">subscribeNext</span> <span class="p">{</span>
</span><span class="line">        <span class="n">print</span><span class="p">(</span><span class="err">$</span><span class="mi">0</span><span class="p">)</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line">    <span class="p">.</span><span class="n">scopedDispose</span><span class="p">()</span>
</span><span class="line">
</span><span class="line">
</span><span class="line"><span class="k">let</span> <span class="n">dataFromCache</span> <span class="o">=</span> <span class="n">CacheStore</span><span class="p">.</span><span class="n">fromCache</span><span class="p">()</span>
</span><span class="line"><span class="n">dataFromCache</span><span class="p">.</span><span class="n">concat</span><span class="p">(</span><span class="n">API</span><span class="p">.</span><span class="n">call</span><span class="p">())</span>
</span><span class="line">    <span class="p">.</span><span class="n">subscribeNext</span> <span class="p">{</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line">    <span class="p">.</span><span class="n">addDisposeBag</span><span class="p">(</span><span class="n">disposeBag</span><span class="p">)</span>
</span><span class="line"><span class="c1">// もしくは</span>
</span><span class="line"><span class="n">API</span><span class="p">.</span><span class="n">call</span><span class="p">()</span>
</span><span class="line">  <span class="p">.</span><span class="n">startWith</span><span class="p">(</span><span class="n">dataFromCache</span><span class="p">)</span>
</span><span class="line">  <span class="p">.</span><span class="n">subscribeNext</span> <span class="p">{</span>
</span><span class="line">  <span class="p">}</span>
</span><span class="line">  <span class="p">.</span><span class="n">addDisposeBag</span><span class="p">(</span><span class="n">disposeBag</span><span class="p">)</span>
</span></code></pre></td>
</tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[[Swift] RxSwift で iBeacon の RangeBeaconsInRegion を 5秒間隔で受け取る方法]]></title>
    <link href="http://hamasyou.com/blog/2015/11/25/rxswift-de-ibeacon-false-rangebeaconsinregion-wo-5miao-jian-ge-deshou-kequ-rufang-fa/"/>
    <updated>2015-11-25T15:25:47+09:00</updated>
    <id>http://hamasyou.com/blog/2015/11/25/rxswift-de-ibeacon-false-rangebeaconsinregion-wo-5miao-jian-ge-deshou-kequ-rufang-fa/</id>
    <content type="html"><![CDATA[<p>CoreLocation を使って iBeacon の Ranging を行う場合、iOS だと 1秒間隔で通知されます。</p>

<p><i class="fa fa-hand-o-right"></i> <a href="http://enamelsystems.com/0011/z" rel="external nofollow" title="[参考] iBeacon(3) - リージョン監視とレンジング - Enamel Systems">[参考] iBeacon(3) - リージョン監視とレンジング - Enamel Systems</a></p>

<p>そこで、1秒間隔だと通知間隔が短すぎるので、5秒間隔とか1分間隔とかに変えたい時にどうするかですが、<code>CLLocationManager</code> クラスに設定があればよかったのですが、特になさそうなので、<code>RxSwift</code> を使ってストリームのフィルタで対応する方法のメモです。</p>

<p><code>CLLocationManager</code> の初期設定とかは参考サイトを見てください。</p>

<p><i class="fa fa-hand-o-right"></i> <a href="https://github.com/ReactiveX/RxSwift/" rel="external nofollow" title="ReactiveX/RxSwift">ReactiveX/RxSwift</a></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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="n">locationManager</span><span class="p">.</span><span class="n">rx_didRangeBeaconsInRegion</span>
</span><span class="line">    <span class="p">.</span><span class="n">sample</span><span class="p">(</span><span class="n">interval</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="n">MainScheduler</span><span class="p">.</span><span class="n">sharedInstance</span><span class="p">))</span>
</span><span class="line">    <span class="p">.</span><span class="n">subscribeNext</span> <span class="p">{</span> <span class="p">(</span><span class="nl">tuple</span><span class="p">:</span> <span class="p">([</span><span class="bp">CLBeacon</span><span class="p">]</span><span class="o">!</span><span class="p">,</span> <span class="bp">CLBeaconRegion</span><span class="o">!</span><span class="p">))</span> <span class="k">in</span>
</span><span class="line">        <span class="n">debugPrint</span><span class="p">(</span><span class="s">"beacons: \(tuple.0), region: \(tuple.1)"</span><span class="p">)</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line">    <span class="p">.</span><span class="n">addDisposableTo</span><span class="p">(</span><span class="n">disposeBag</span><span class="p">)</span>
</span></code></pre></td>
</tr></table></div></figure>


<p><code>Rx</code> の <code>sample</code> を使って、ストリームを <code>interval</code> 毎にサンプリングしてやるだけです。</p>

<p><i class="fa fa-hand-o-right"></i> <a href="http://www.introtorx.com/content/v1.0.10621.0/13_TimeShiftedSequences.html#Sample" rel="external nofollow" title="Time-shifted sequences - Introduction to Rx">Time-shifted sequences - Introduction to Rx</a></p>

<p><code>RxSwift</code> も使いやすくて、めっちゃ便利です！</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[[iOS/Swift]ReactiveCocoa 3.0 で ViewModel から Signal をセルフ・コントロールするイディオム]]></title>
    <link href="http://hamasyou.com/blog/2015/08/13/ios-swift-reactivecocoa-signal-viewmodel/"/>
    <updated>2015-08-13T11:57:28+09:00</updated>
    <id>http://hamasyou.com/blog/2015/08/13/ios-swift-reactivecocoa-signal-viewmodel/</id>
    <content type="html"><![CDATA[<p><a href="https://github.com/ReactiveCocoa/ReactiveCocoa" rel="external nofollow" title="ReactiveCocoa">ReactiveCocoa</a> が v.3.0-RC.1 がでて、そろそろ製品に Swift で ReactiveCocoa が使えるようになりそうな感じになってきました。</p>

<p>いつも <code>Signal</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>
<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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="k">import</span> <span class="n">Foundation</span>
</span><span class="line"><span class="k">import</span> <span class="n">UIKit</span>
</span><span class="line"><span class="k">import</span> <span class="n">ReactiveCocoa</span>
</span><span class="line">
</span><span class="line"><span class="k">class</span> <span class="n">MyViewModel</span> <span class="p">{</span>
</span><span class="line">    <span class="k">let</span> <span class="p">(</span><span class="n">changed</span><span class="p">,</span> <span class="n">sink</span><span class="p">)</span> <span class="o">=</span> <span class="n">Signal</span><span class="o">&lt;</span><span class="n">Void</span><span class="p">,</span> <span class="n">NoError</span><span class="o">&gt;</span><span class="p">.</span><span class="n">pipe</span><span class="p">()</span>
</span><span class="line">
</span><span class="line">    <span class="k">func</span> <span class="n">doAction</span><span class="p">()</span> <span class="p">{</span>
</span><span class="line">        <span class="c1">// do something</span>
</span><span class="line">        <span class="n">sendNext</span><span class="p">(</span><span class="n">sink</span><span class="p">,</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><span class="line"><span class="k">class</span> <span class="nl">MyViewController</span> <span class="p">:</span> <span class="bp">UIViewController</span> <span class="p">{</span>
</span><span class="line">    <span class="k">let</span> <span class="n">viewModel</span> <span class="o">=</span> <span class="n">MyViewModel</span><span class="p">()</span>
</span><span class="line">
</span><span class="line">    <span class="kr">override</span> <span class="k">func</span> <span class="n">viewDidLoad</span><span class="p">()</span> <span class="p">{</span>
</span><span class="line">        <span class="nb">super</span><span class="p">.</span><span class="n">viewDidLoad</span><span class="p">()</span>
</span><span class="line">
</span><span class="line">        <span class="n">viewModel</span><span class="p">.</span><span class="n">changed</span> <span class="o">|&gt;</span> <span class="n">observe</span><span class="p">(</span><span class="nl">next</span><span class="p">:</span> <span class="n">debugPrintln</span><span class="p">)</span>
</span><span class="line">
</span><span class="line">        <span class="n">viewModel</span><span class="p">.</span><span class="n">doAction</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>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[[iOS]Swift の Dollar ライブラリの each 関数を SequenceType に対応する拡張]]></title>
    <link href="http://hamasyou.com/blog/2015/08/12/ios-swift-dollar-each-sequencetype/"/>
    <updated>2015-08-12T16:47:11+09:00</updated>
    <id>http://hamasyou.com/blog/2015/08/12/ios-swift-dollar-each-sequencetype/</id>
    <content type="html"><![CDATA[<p>Swift のメモ書きです。</p>

<p><a href="https://github.com/ankurp/Dollar.swift" rel="external nofollow" title="ankurp/Dollar.swift">ankurp/Dollar.swift</a> という JavaScript の Lo-Dash や Underscore と同じ感じでコレクションを扱うためのライブラリがありますが、 <code>each</code> が配列しか受け付けることが出来ないので、<code>SequenceType</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>
<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="swift"><span class="line"><span class="k">import</span> <span class="n">Dollar</span>
</span><span class="line">
</span><span class="line"><span class="k">extension</span> <span class="err">$</span> <span class="p">{</span>
</span><span class="line">    <span class="k">class</span> <span class="k">func</span> <span class="n">each</span><span class="o">&lt;</span><span class="nl">T</span><span class="p">:</span> <span class="n">SequenceType</span><span class="o">&gt;</span><span class="p">(</span><span class="nl">array</span><span class="p">:</span> <span class="n">T</span><span class="p">,</span> <span class="nl">callback</span><span class="p">:</span> <span class="p">(</span><span class="n">T</span><span class="p">.</span><span class="n">Generator</span><span class="p">.</span><span class="n">Element</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="p">())</span> <span class="o">-&gt;</span> <span class="n">T</span> <span class="p">{</span>
</span><span class="line">        <span class="k">for</span> <span class="n">elem</span> <span class="k">in</span> <span class="n">array</span> <span class="p">{</span>
</span><span class="line">            <span class="n">callback</span><span class="p">(</span><span class="n">elem</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">array</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="err">$</span><span class="p">.</span><span class="n">each</span><span class="p">([</span><span class="s">"a"</span><span class="p">,</span> <span class="s">"b"</span><span class="p">,</span> <span class="s">"c"</span><span class="p">])</span> <span class="p">{</span> <span class="p">(</span><span class="nl">s</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="k">in</span> <span class="n">println</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="p">}</span>
</span><span class="line"><span class="err">$</span><span class="p">.</span><span class="n">each</span><span class="p">([</span><span class="s">"key"</span><span class="o">:</span> <span class="s">"val"</span><span class="p">])</span> <span class="p">{</span> <span class="p">(</span><span class="nl">e</span><span class="p">:</span> <span class="p">(</span><span class="n">String</span><span class="p">,</span> <span class="n">String</span><span class="p">))</span> <span class="k">in</span> <span class="n">println</span><span class="p">(</span><span class="s">"\(e.0) = \(e.1)"</span><span class="p">)</span> <span class="p">}</span>
</span><span class="line"><span class="c1">// a</span>
</span><span class="line"><span class="c1">// b</span>
</span><span class="line"><span class="c1">// c</span>
</span><span class="line"><span class="c1">// key = val</span>
</span></code></pre></td>
</tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Swift の Array と Dictionary の Extension（each と map を実装した）]]></title>
    <link href="http://hamasyou.com/blog/2015/06/10/swift-array-dictionary-extension/"/>
    <updated>2015-06-10T12:01:16+09:00</updated>
    <id>http://hamasyou.com/blog/2015/06/10/swift-array-dictionary-extension/</id>
    <content type="html"><![CDATA[<h2>Array に each を実装してみた。</h2>

<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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="k">extension</span> <span class="n">Array</span> <span class="p">{</span>
</span><span class="line">    <span class="k">func</span> <span class="n">each</span><span class="p">(</span><span class="nl">block</span><span class="p">:</span> <span class="p">(</span><span class="n">T</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="p">())</span> <span class="p">{</span>
</span><span class="line">        <span class="k">for</span> <span class="n">item</span> <span class="k">in</span> <span class="nb">self</span> <span class="p">{</span>
</span><span class="line">            <span class="n">block</span><span class="p">(</span><span class="n">item</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="k">func</span> <span class="n">each</span><span class="o">&lt;</span><span class="n">U</span><span class="o">&gt;</span><span class="p">(</span><span class="nl">block</span><span class="p">:</span> <span class="p">(</span><span class="n">U</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="p">())</span> <span class="p">{</span>
</span><span class="line">        <span class="k">for</span> <span class="n">item</span> <span class="k">in</span> <span class="nb">self</span> <span class="p">{</span>
</span><span class="line">            <span class="n">block</span><span class="p">(</span><span class="n">item</span> <span class="kt">as</span><span class="o">!</span> <span class="n">U</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="k">func</span> <span class="n">eachWithIndex</span><span class="p">(</span><span class="nl">block</span><span class="p">:</span> <span class="p">(</span><span class="n">T</span><span class="p">,</span> <span class="n">Int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="p">())</span> <span class="p">{</span>
</span><span class="line">        <span class="k">for</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">item</span><span class="p">)</span> <span class="k">in</span> <span class="n">enumerate</span><span class="p">(</span><span class="nb">self</span><span class="p">)</span> <span class="p">{</span>
</span><span class="line">            <span class="n">block</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="n">i</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="k">func</span> <span class="n">eachWithIndex</span><span class="o">&lt;</span><span class="n">U</span><span class="o">&gt;</span><span class="p">(</span><span class="nl">block</span><span class="p">:</span> <span class="p">(</span><span class="n">U</span><span class="p">,</span> <span class="n">Int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="p">())</span> <span class="p">{</span>
</span><span class="line">        <span class="k">for</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">item</span><span class="p">)</span> <span class="k">in</span> <span class="n">enumerate</span><span class="p">(</span><span class="nb">self</span><span class="p">)</span> <span class="p">{</span>
</span><span class="line">            <span class="n">block</span><span class="p">(</span><span class="n">item</span> <span class="kt">as</span><span class="o">!</span> <span class="n">U</span><span class="p">,</span> <span class="n">i</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="p">}</span>
</span></code></pre></td>
</tr></table></div></figure>


<p>使い方はこんな感じ。</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="swift"><span class="line"><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">].</span><span class="n">each</span> <span class="p">{</span> <span class="p">(</span><span class="nl">n</span><span class="p">:</span> <span class="n">Int</span><span class="p">)</span> <span class="k">in</span> <span class="n">println</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="p">}</span>
</span><span class="line"><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">].</span><span class="n">each</span> <span class="p">{</span> <span class="n">println</span><span class="p">(</span><span class="err">$</span><span class="mi">0</span><span class="p">)</span> <span class="p">}</span>
</span><span class="line"><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">].</span><span class="n">eachWithIndex</span> <span class="p">{</span> <span class="p">(</span><span class="nl">n</span><span class="p">:</span> <span class="n">Int</span><span class="p">,</span> <span class="nl">i</span><span class="p">:</span> <span class="n">Int</span><span class="p">)</span> <span class="k">in</span> <span class="n">println</span><span class="p">(</span><span class="s">"index \(i), n \(n)"</span><span class="p">)</span> <span class="p">}</span>
</span><span class="line"><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">].</span><span class="n">eachWithIndex</span> <span class="p">{</span> <span class="n">println</span><span class="p">(</span><span class="s">"index \($1), n \($0)"</span><span class="p">)</span> <span class="p">}</span>
</span></code></pre></td>
</tr></table></div></figure>


<p>配列の中身が <code>AnyObject</code> だった時に、型指定するときとしない時でどっちも動くようにするのに、メソッドを2つ定義しました。</p>

<p>このへん、<em>Generics</em> の達人のかたに、もっといい書き方あるよって教えて欲しいです。</p>

<h2>Swift の Dictionary に map を実装してみた。</h2>

<p>ついでに <code>reduce</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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="k">extension</span> <span class="n">Dictionary</span> <span class="p">{</span>
</span><span class="line">    <span class="k">func</span> <span class="n">map</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="nl">transform</span><span class="p">:</span> <span class="p">(</span><span class="n">Key</span><span class="p">,</span> <span class="n">Value</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">T</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="p">{</span>
</span><span class="line">        <span class="k">return</span> <span class="n">Swift</span><span class="p">.</span><span class="n">map</span><span class="p">(</span><span class="nb">self</span><span class="p">,</span> <span class="n">transform</span><span class="p">)</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line">
</span><span class="line">    <span class="k">func</span> <span class="n">reduce</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="nl">initial</span><span class="p">:</span> <span class="n">T</span><span class="p">,</span> <span class="nl">combine</span><span class="p">:</span> <span class="p">(</span><span class="n">T</span><span class="p">,</span> <span class="p">(</span><span class="n">Key</span><span class="p">,</span> <span class="n">Value</span><span class="p">))</span> <span class="o">-&gt;</span> <span class="n">T</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">T</span> <span class="p">{</span>
</span><span class="line">        <span class="k">return</span> <span class="n">Swift</span><span class="p">.</span><span class="n">reduce</span><span class="p">(</span><span class="nb">self</span><span class="p">,</span> <span class="n">initial</span><span class="p">,</span> <span class="n">combine</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>使い方はこんな感じ。</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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="k">var</span> <span class="n">dict</span> <span class="o">=</span> <span class="p">[</span><span class="nl">String</span><span class="p">:</span> <span class="n">String</span><span class="p">]()</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="s">"hello"</span><span class="p">]</span> <span class="o">=</span> <span class="s">"world"</span>
</span><span class="line">
</span><span class="line"><span class="k">let</span> <span class="n">array</span> <span class="o">=</span> <span class="n">dict</span><span class="p">.</span><span class="n">map</span> <span class="p">{</span> <span class="p">(</span><span class="nl">k</span><span class="p">:</span> <span class="n">String</span><span class="p">,</span> <span class="nl">v</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">String</span> <span class="k">in</span>
</span><span class="line">    <span class="k">return</span> <span class="n">v</span>
</span><span class="line"><span class="p">}</span>
</span><span class="line"><span class="n">println</span><span class="p">(</span><span class="n">array</span><span class="p">)</span>      <span class="c1">// ["world"]</span>
</span><span class="line">
</span><span class="line">
</span><span class="line"><span class="n">dict</span> <span class="o">=</span> <span class="p">[</span><span class="nl">String</span><span class="p">:</span> <span class="n">Int</span><span class="p">]()</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="s">"a"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="s">"b"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">2</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="s">"c"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">3</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="s">"d"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">4</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="s">"e"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">5</span>
</span><span class="line"><span class="k">let</span> <span class="n">n</span> <span class="o">=</span> <span class="n">dict</span><span class="p">.</span><span class="n">reduce</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">d</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Int</span> <span class="k">in</span> <span class="n">n</span> <span class="o">+</span> <span class="n">d</span><span class="mf">.1</span> <span class="p">}</span>    <span class="c1">// 15</span>
</span></code></pre></td>
</tr></table></div></figure>


<p>Ruby の map っぽい感じで使えるにしたかったので。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[WEB+DB PRESS vol.85]]></title>
    <link href="http://hamasyou.com/blog/2015/02/22/web-plus-db-press-vol-dot-85/"/>
    <updated>2015-02-22T11:33:24+09:00</updated>
    <id>http://hamasyou.com/blog/2015/02/22/web-plus-db-press-vol-dot-85/</id>
    <content type="html"><![CDATA[<p>『<a href="http://www.amazon.co.jp/gp/product/4774171417?ie=UTF8&amp;camp=247&amp;creativeASIN=4774171417&amp;linkCode=xm2&amp;tag=sorehabooks-22" rel="external nofollow" title="WEB+DB PRESS vol.85">WEB+DB PRESS vol.85</a>』の特集2. <strong class="text-danger">速習 リアクティブプログラミング</strong> を寄稿しました。 <strong class="text-danger">リアクティブ</strong> という、去年辺りに盛り上がったキーワードを、Webプログラミングの観点から整理するとこういうものだよね？っていうふんわりした感じで解説しています。</p>

<p>定義や概念などは、語るコンテキストで捉え方が違ったり、論争の元になるので、今回はあえてこういう定義付けをさけ、実践で利用する場合にどういうメリットがあるのか、どういうふうに使えばいいのかに焦点を当てました。</p>

<p>一部、寝ぼけていたのかおかしな部分があったりもしますが（<em>React.js が Flux アーキテクチャに則っているとか変なこと書いてます。。。</em>）、今号はいろいろおもしろい話が満載ですので、是非読んでみてください。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[[iOS8対応]UITableViewのSeparatorInsetsをゼロにする方法]]></title>
    <link href="http://hamasyou.com/blog/2014/12/25/ios8-swift-uitableview-separatorinsets/"/>
    <updated>2014-12-25T11:03:14+09:00</updated>
    <id>http://hamasyou.com/blog/2014/12/25/ios8-swift-uitableview-separatorinsets/</id>
    <content type="html"><![CDATA[<h2>iOS8 から separatorInset だけだと区切り線が広がらない</h2>

<p>こんにちは。iOS8 から SeparatorInsets をゼロにする方法が変わりました。今までの <code>UITableView</code> の <code>separatorInset</code> に <code>UIEdgeInsetsZero</code> を入れるだけだと、iOS7 では効きますが、iOS8 では効かなくなりました。</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="swift"><span class="line"><span class="n">tableView</span><span class="p">.</span><span class="n">separatorInset</span> <span class="o">=</span> <span class="n">UIEdgeInsetsZero</span>
</span></code></pre></td>
</tr></table></div></figure>


<p><img src="http://hamasyou.com/images/2014-12-25-tableview.png" width="320" title='"図1"' alt='"図1"' class="img-thumbnail"></p>

<h2>iOS8 にも対応するには</h2>

<p>iOS8 からは <code>UIView</code> に追加された <code>layoutMargins</code> というプロパティにも <code>UIEdgeInsetsZero</code> をセットする必要があります。ただこのプロパティ、iOS8 以降でしか利用できないプロパティなので、分岐が必要になります。。</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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="n">tableView</span><span class="p">.</span><span class="n">layoutMargins</span> <span class="o">=</span> <span class="n">UIEdgeInsetsZero</span>
</span><span class="line"><span class="n">cell</span><span class="p">.</span><span class="n">layoutMargins</span> <span class="o">=</span> <span class="n">UIEdgeInsetsZero</span>
</span></code></pre></td>
</tr></table></div></figure>


<h3>全体に適用する簡単な例</h3>

<p>全体に適用するには UIAppearance を使うと便利です。iOS7 と iOS8 に対応したコードは次のように書けます。</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="swift"><span class="line"><span class="k">let</span> <span class="n">version</span> <span class="o">=</span> <span class="bp">NSString</span><span class="p">(</span><span class="nl">string</span><span class="p">:</span> <span class="bp">UIDevice</span><span class="p">.</span><span class="n">currentDevice</span><span class="p">().</span><span class="n">systemVersion</span><span class="p">).</span><span class="n">doubleValue</span>
</span><span class="line">
</span><span class="line"><span class="bp">UITableView</span><span class="p">.</span><span class="n">appearance</span><span class="p">().</span><span class="n">separatorInset</span> <span class="o">=</span> <span class="n">UIEdgeInsetsZero</span>
</span><span class="line"><span class="bp">UITableViewCell</span><span class="p">.</span><span class="n">appearance</span><span class="p">().</span><span class="n">separatorInset</span> <span class="o">=</span> <span class="n">UIEdgeInsetsZero</span>
</span><span class="line"><span class="k">if</span> <span class="n">version</span> <span class="o">&gt;=</span> <span class="mi">8</span> <span class="p">{</span>
</span><span class="line">    <span class="bp">UITableView</span><span class="p">.</span><span class="n">appearance</span><span class="p">().</span><span class="n">layoutMargins</span> <span class="o">=</span> <span class="n">UIEdgeInsetsZero</span>
</span><span class="line">    <span class="bp">UITableViewCell</span><span class="p">.</span><span class="n">appearance</span><span class="p">().</span><span class="n">layoutMargins</span> <span class="o">=</span> <span class="n">UIEdgeInsetsZero</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td>
</tr></table></div></figure>


<p><img src="http://hamasyou.com/images/2014-12-25-tableview2.png" width="320" title='"図2"' alt='"図2"' class="img-thumbnail"></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[[iOS] Auto Layout を使いこなす。UITableViewCell と UIScrollView 編]]></title>
    <link href="http://hamasyou.com/blog/2014/10/09/ios-autolayout-scrollview-tablecell/"/>
    <updated>2014-10-09T01:31:20+09:00</updated>
    <id>http://hamasyou.com/blog/2014/10/09/ios-autolayout-scrollview-tablecell/</id>
    <content type="html"><![CDATA[<p>iPhone6 と iPhone6 Plus が発売になり、本格的に iOS でも Android のように複数解像度に対応したやり方をしないといけなくなってきました。
iPhone5S までは、縦幅が伸びただけだったので、なんとなく <code>Auto Layout</code> を使っていても問題は表面化しづらかったのですが、
iPhone6 で横幅が伸びてしまったことで、適当に <code>Auto Layout</code> を使ってコーディングしていると残念なことになっているアプリが結構あります。</p>

<p>僕も iPhone アプリを開発しているのでこのあたりは結構気を使ってはいるんですが、いかんせん自分のやり方がほんとに正しいのか、やや疑問なところもあります。
そこで、今の自分のやり方を晒して、世の iPhone アプリ開発者の人に突っ込んでもらえればと思い記事を書くことにしました。</p>

<p>間違っている箇所もあると思いますので、ドンドンツッコミをお願いします！</p>

<!-- more -->


<h2>この記事で何が出来るようになりたいか</h2>

<p>このまとめ記事で、何が出来るようになりたいか。それは次の2点です。</p>

<ol>
<li>
<code>UITableViewCell</code> （可変長高さ）を <code>Auto Layout</code> を使ってキレイにつくりたい</li>
<li>
<code>UIScrollView</code> （可変コンテンツ）を <code>Auto Layout</code> を使ってキレイにつくりたい</li>
</ol>


<p>こんな感じのやつです。</p>

<p><img src="http://hamasyou.com/images/20141008/SS1.png" width="240" title='"可変長UITableViewCell"' alt='"可変長UITableViewCell"' class="img-thumbnail">
<img src="http://hamasyou.com/images/20141008/SS2.png" width="240" title='"Auto Layout を使った横スクロールの UIScrollView"' alt='"Auto Layout を使った横スクロールの UIScrollView"' class="img-thumbnail">
<img src="http://hamasyou.com/images/20141008/SS3.png" width="240" title='"Auto Layout を使った横スクロールの UIScrollView"' alt='"Auto Layout を使った横スクロールの UIScrollView"' class="img-thumbnail"></p>

<p><code>UILabel</code> の中身によって <code>UITableViewCell</code> の高さが変わるやつと、<code>UIScrollView</code> の中身をページングで切り替えるときに中身の個数を動的に差し替えるやつです。</p>

<p>それぞれ作り方をさらします。</p>

<p>ソースコードは</p>

<p><i class="fa fa-hand-o-right"></i> <a href="https://github.com/hamasyou/autolayout" rel="external nofollow" title="hamasyou/autolayout">hamasyou/autolayout</a></p>

<p>にあるので、参考にしたい方はどうぞ。</p>

<h2>iOS8 以降だけに対応するのであれば</h2>

<p>ちなみに、iOS8 以降だけに対応するのであれば、<code>TableViewCell.xib</code> で <code>ContentView</code> に対して何も考えずに Auto Layout でレイアウトして、<code>TableViewController</code> を継承したクラスで次のように <code>tableView.rowHeight</code> に <code>UITableViewAutomaticDimension</code> を設定し、<code>tableView:estimatedHeightForRowAtIndexPath:</code> で <code>UITableViewAutomaticDimension</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>
<span class="line-number">12</span>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="k">class</span> <span class="nl">MyViewClass</span> <span class="p">:</span> <span class="bp">UIViewController</span><span class="p">,</span> <span class="bp">UITableViewDelegate</span> <span class="p">{</span>
</span><span class="line">    <span class="p">@</span><span class="kt">IBOutlet</span> <span class="k">weak</span> <span class="k">var</span> <span class="nl">tableView</span><span class="p">:</span> <span class="bp">UITableView</span><span class="o">!</span>
</span><span class="line">
</span><span class="line">    <span class="kr">override</span> <span class="k">func</span> <span class="n">viewDidLoad</span><span class="p">()</span> <span class="p">{</span>
</span><span class="line">        <span class="nb">super</span><span class="p">.</span><span class="n">viewDidLoad</span><span class="p">()</span>
</span><span class="line">        <span class="n">tableView</span><span class="p">.</span><span class="n">rowHeight</span> <span class="o">=</span> <span class="n">UITableViewAutomaticDimension</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line">
</span><span class="line">    <span class="k">func</span> <span class="n">tableView</span><span class="p">(</span><span class="nl">tableView</span><span class="p">:</span> <span class="bp">UITableView</span><span class="p">,</span> <span class="n">estimatedHeightForRowAtIndexPath</span> <span class="nl">indexPath</span><span class="p">:</span> <span class="bp">NSIndexPath</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">CGFloat</span> <span class="p">{</span>
</span><span class="line">        <span class="k">return</span> <span class="n">UITableViewAutomaticDimension</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><code>tableView</code> に <code>estimatedRowHeight</code> というプロパティがありますが、これに <code>UITableViewAutomaticDimension</code> を設定して、<code>tableView:estimatedHeightForRowAtIndexPath:</code> を実装しない方法だと上手くいきません。バグなんじゃないか？？。。。</p>

<h2>Auto Layout のおさらい</h2>

<p>作り方を晒す前に、まずは <strong class="text-danger">Auto Layout</strong> のおさらいをしておきます。</p>

<p>Auto Layout は Storyboard やプログラムから「制約」を利用してレイアウトを組み立てるものです。基本的に Auto Layout に対応したアプリでは、
<code>UIView(frame: CGRectMake(xx, xx, xx, xx))</code> みたいな作成方法はしなくなります。</p>

<p>Auto Layout を使うと、”画面のこのコンポーネントから◯pxずらしてこのコンポーネントを配置する” や “このコンポーネントとこのコンポーネントのサイズを同じにする”
みたいなことをなんとなく直感的に記述（または、設定）できます。</p>

<p>Auto Layout を Strobyboard 上で設定すると、その制約が実際にコンポーネントに反映されるのは、<code>UIViewController#viewDidLayoutSubviews</code> のタイミングになるようです。</p>

<h2>UITableViewCell での Auto Layout の作用</h2>

<p>UITableViewCell で Auto Layout を使うときに注意しなければならないのは、<code>awakeFromNib</code> のタイミングでは、セルの Auto Layout が設定されていないということです。</p>

<p>まぁ、これは当然といえば当然で、カスタムの UITableViewCell は再利用を前提に作られるので、実際にセルのコンテンツが設定されるは <code>UITableViewDataSource#cellForRowAtIndexPath</code> の段階になるからです。
このメソッドの中でセルのコンテンツを設定するわけです。</p>

<h3>セルの高さが問い合わせられるのはセルのコンテンツを設定する前！！</h3>

<p>で、まぁ普通に UITableView を使っているとドハマリするのが、セルの高さを返す <code>UITableViewDelegate#heightForRowAtIndexPath</code> のメソッドが呼び出されるのが、<code>cellForRowAtIndexPath</code> の前ということです。
セルの高さを計算できるのはセルのコンテンツが設定された後なんじゃないの？って思うわけですが、高さの問い合わせが来るのはセルのコンテンツを設定する前なのです。。</p>

<p>じゃあ、どうするかというと、僕はもう割りきって、<code>heightForRowAtIndexPath</code> の中で <code>cellForRowAtIndexPath</code> を呼び出して、セルにコンテンツを設定した後にセルの高さを計算するようにしています。</p>

<figure class="code"><figcaption><span>UITableViewController</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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line">    <span class="c1">// MARK: - UITableViewDataSource</span>
</span><span class="line">
</span><span class="line">    <span class="k">func</span> <span class="n">tableView</span><span class="p">(</span><span class="nl">tableView</span><span class="p">:</span> <span class="bp">UITableView</span><span class="p">,</span> <span class="n">numberOfRowsInSection</span> <span class="nl">section</span><span class="p">:</span> <span class="n">Int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Int</span> <span class="p">{</span>
</span><span class="line">        <span class="k">return</span> <span class="mi">2</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line">
</span><span class="line">    <span class="k">func</span> <span class="n">tableView</span><span class="p">(</span><span class="nl">tableView</span><span class="p">:</span> <span class="bp">UITableView</span><span class="p">,</span> <span class="n">cellForRowAtIndexPath</span> <span class="nl">indexPath</span><span class="p">:</span> <span class="bp">NSIndexPath</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="bp">UITableViewCell</span> <span class="p">{</span>
</span><span class="line">        <span class="k">let</span> <span class="n">cell</span> <span class="o">=</span> <span class="n">tableView</span><span class="p">.</span><span class="n">dequeueReusableCellWithIdentifier</span><span class="p">(</span><span class="s">"customCell"</span><span class="p">)</span> <span class="kt">as</span> <span class="n">CustomTableViewCell</span>
</span><span class="line">
</span><span class="line">        <span class="k">switch</span> <span class="n">indexPath</span><span class="p">.</span><span class="n">row</span> <span class="p">{</span>
</span><span class="line">        <span class="k">case</span> <span class="mi">0</span><span class="o">:</span>
</span><span class="line">            <span class="n">cell</span><span class="p">.</span><span class="n">thumbView</span><span class="p">.</span><span class="n">image</span> <span class="o">=</span> <span class="bp">UIImage</span><span class="p">(</span><span class="nl">named</span><span class="p">:</span> <span class="s">"Image1"</span><span class="p">)</span>
</span><span class="line">            <span class="n">cell</span><span class="p">.</span><span class="n">labelView</span><span class="p">.</span><span class="n">text</span>  <span class="o">=</span> <span class="s">"いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす色はにほへど散りぬるを我が世たれぞ常ならむ有為の奥山今日越えて浅き夢見じ酔ひもせず"</span>
</span><span class="line">        <span class="k">case</span> <span class="mi">1</span><span class="o">:</span>
</span><span class="line">            <span class="n">cell</span><span class="p">.</span><span class="n">thumbView</span><span class="p">.</span><span class="n">image</span> <span class="o">=</span> <span class="bp">UIImage</span><span class="p">(</span><span class="nl">named</span><span class="p">:</span> <span class="s">"Image2"</span><span class="p">)</span>
</span><span class="line">            <span class="n">cell</span><span class="p">.</span><span class="n">labelView</span><span class="p">.</span><span class="n">text</span>  <span class="o">=</span> <span class="s">"Cozy lummox gives smart squid who asks for job pen."</span>
</span><span class="line">        <span class="k">default</span><span class="o">:</span>
</span><span class="line">            <span class="k">break</span>
</span><span class="line">        <span class="p">}</span>
</span><span class="line">        <span class="k">return</span> <span class="n">cell</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line">
</span><span class="line">    <span class="c1">// MARK: UITableViewDelegate</span>
</span><span class="line">
</span><span class="line">    <span class="k">func</span> <span class="n">tableView</span><span class="p">(</span><span class="nl">tableView</span><span class="p">:</span> <span class="bp">UITableView</span><span class="p">,</span> <span class="n">heightForRowAtIndexPath</span> <span class="nl">indexPath</span><span class="p">:</span> <span class="bp">NSIndexPath</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">CGFloat</span> <span class="p">{</span>
</span><span class="line">        <span class="k">let</span> <span class="n">cell</span> <span class="o">=</span> <span class="nb">self</span><span class="p">.</span><span class="n">tableView</span><span class="p">(</span><span class="n">tableView</span><span class="p">,</span> <span class="nl">cellForRowAtIndexPath</span><span class="p">:</span> <span class="n">indexPath</span><span class="p">)</span> <span class="kt">as</span> <span class="n">CustomTableViewCell</span>
</span><span class="line">        <span class="k">var</span> <span class="n">newBounds</span> <span class="o">=</span> <span class="n">cell</span><span class="p">.</span><span class="n">bounds</span>
</span><span class="line">        <span class="n">newBounds</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">width</span> <span class="o">=</span> <span class="n">tableView</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">width</span>
</span><span class="line">        <span class="n">cell</span><span class="p">.</span><span class="n">bounds</span> <span class="o">=</span> <span class="n">newBounds</span>
</span><span class="line">
</span><span class="line">        <span class="n">cell</span><span class="p">.</span><span class="n">setNeedsLayout</span><span class="p">()</span>
</span><span class="line">        <span class="n">cell</span><span class="p">.</span><span class="n">layoutIfNeeded</span><span class="p">()</span>
</span><span class="line">        <span class="k">return</span> <span class="n">cell</span><span class="p">.</span><span class="n">preferredView</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">height</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line">
</span><span class="line">    <span class="k">func</span> <span class="n">tableView</span><span class="p">(</span><span class="nl">tableView</span><span class="p">:</span> <span class="bp">UITableView</span><span class="p">,</span> <span class="n">estimatedHeightForRowAtIndexPath</span> <span class="nl">indexPath</span><span class="p">:</span> <span class="bp">NSIndexPath</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">CGFloat</span> <span class="p">{</span>
</span><span class="line">        <span class="k">return</span> <span class="n">UITableViewAutomaticDimension</span>
</span><span class="line">    <span class="p">}</span>
</span></code></pre></td>
</tr></table></div></figure>


<p>高さを計算するときに、<code>cellForRowAtIndexPath</code> を呼び出してセルにコンテンツを設定した後、セルの width にテーブルビューの width を設定してあげて、一度 cell のレイアウトを更新します。</p>

<p><strong class="text-danger">セルの width にテーブルビューの width を設定しているのがミソ</strong> です。</p>

<p>Storyboard 上ではカスタムセルの横幅がデフォルトで320pxで作成されるので、iPhone5S まではセルの横幅を気にしなくてもセルの <code>layoutIfNeeded</code> だけを呼び出せば勝手に中のコンテンツの高さ決まっているように錯覚していたのですが、
実は Storyboard 上で320pxでセルが作られているのでたまたま偶然いままではうまくいっていただけっぽいです。</p>

<p>本来は、セルの横幅が決まった上でセルのコンテンツの Auto Layout にしたがって <code>layoutIfNeeded</code> しないと行けないのです。セルの横幅を設定せずに <code>layoutIfNeeded</code> だけでコンテンツの高さに合わせてセルの高さを決めていると、
iPhone6 Plus になったときにセルの高さがおかしくなってしまいます。</p>

<h3>heightForRowAtIndexPath と estimatedHeightForRowAtIndexPath の違い</h3>

<p>セルの高さを計算するメソッドは <code>heightForRowAtIndexPath</code> ですが <code>estimatedHeightForRowAtIndexPath</code> というメソッドも用意されています。
このメソッドは何なのかというと、UITableView は大量のデータを表示する場合でも、表示領域+αの部分だけしかセルをインスタンス化しないという設計になっています。
ですので、<code>cellForRowAtIndexPath</code> は表示領域+αの部分分だけ呼び出されるのですが、セルの高さの計算メソッドは、そうではありません。</p>

<p>スクロールバーの範囲を計算したり色々するために、セルの高さの計算は、データがどれだけ大量にあっても全ての数分呼び出されてしまうのです。</p>

<p>で、<code>heightForRowAtIndexPath</code> と <code>estimatedHeightForRowAtIndexPath</code> の違いですが、<code>estimatedHeightForRowAtIndexPath</code> はセルの大まかなサイズを返すメソッドとして用意されています。</p>

<p><code>heightForRowAtIndexPath</code> と <code>estimatedHeightForRowAtIndexPath</code> が両方用意されている場合は、全てのセルの高さを一旦 <code>estimatedHeightForRowAtIndexPath</code> で計算したあと、
表示領域+α分の回数だけ <code>heightForRowAtIndexPath</code> が呼び出されるという形になります。</p>

<p><code>estimatedHeightForRowAtIndexPath</code> を定義しない場合は、全てのデータ分だけ <code>heightForRowAtIndexPath</code> が呼び出されるので、データが多い場合は結構きつくなります。
なので、忘れずに <code>estimatedHeightForRowAtIndexPath</code> も定義しておきます。</p>

<p>返す値はなんとなくの定数(44pxとか)でもいいですし、<code>UITableViewAutomaticDimension</code> を返すでもどちらでもよさそうです。</p>

<h3>setNeedsLayout と layoutIfNeeded は何？</h3>

<p><code>setNeedsLayout</code> はそのコンポーネントに、再レイアウトが必要なフラグを設定するメソッドになります。再レイアウトが必要なコンポネントは次のタイミングの <code>layoutSubviews</code> の呼び出しの時に再レイアウトされます。</p>

<p><code>layoutIfNeeded</code> はそのコンポーネントが再レイアウトが必要なフラグが立っているかを確認して、再レイアウトが必要であれば <code>layoutSubviews</code> を呼び出してくれるメソッドです。</p>

<p>コンポーネントのレイアウトを強制的に更新したい場合は</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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="n">view</span><span class="p">.</span><span class="n">setNeedsLayout</span><span class="p">()</span>
</span><span class="line"><span class="n">view</span><span class="p">.</span><span class="n">layoutIfNeeded</span><span class="p">()</span>
</span></code></pre></td>
</tr></table></div></figure>


<p>のコンボでレイアウトを更新します。この処理を行うと、Auto Layout にしたがってレイアウトが設定されます。</p>

<p>レイアウトを更新したらセルの高さが決まっているはずなので <code>bounds.height</code> を返します。</p>

<h3>preferredView って何？</h3>

<p>UIView 関連のコンポーネントには、推奨サイズというのが設定されているコンポーネントがあります。例えば UILabel であれば、ラベルの文字数をきっちり表示できるサイズが推奨サイズになりますし、
UIButton であればボタン名が表示できるサイズが推奨サイズになります。</p>

<p>コンポーネントの推奨サイズを取得するメソッドが <code>UIView#intrinsicContentSize</code> になります。実はこのメソッド、Auto Layout と深い関係があります。</p>

<p>例えば、UILabel の制約を次のように設定したとします。</p>

<p><img src="http://hamasyou.com/images/20141008/SS4.png" width="240" title='"UILabel の制約"' alt='"UILabel の制約"' class="img-thumbnail"></p>

<p>親のコンポーネントに対して、Top、Trailing、Leading を 0 に設定しています。こうすることで UILabel が親のコンポーネントの上左右の padding が 0 で表示されるわけです。</p>

<p>ここでのポイントは、bottom に制約を設定していないことです。bottom に制約を設定していないので、本来であればこのコンポーネントは高さが決まらずに ambiguity（曖昧）な状態なはずです。</p>

<p>でも UILabel や UIButton は ambiguity にはなりません。これは、コンポーネントに推奨サイズが設定されているので、そのサイズでコンポーネントが表示されるからです。</p>

<p>UILabel を使って、テキストがどれだけ多くなっても全て表示したいというときには、このように bottom に制約を設定せずに、<code>Lines</code> を 0 に、<code>Line Breaks</code> を <code>Character Wrap</code> に設定します。</p>

<p><img src="http://hamasyou.com/images/20141008/SS5.png" width="240" title='"Lines 0 Line Breaks Character Wrap"' alt='"Lines 0 Line Breaks Character Wrap"' class="img-thumbnail">
<img src="http://hamasyou.com/images/20141008/SS6.png" width="240" title='"Lines 0 Line Breaks Character Wrap"' alt='"Lines 0 Line Breaks Character Wrap"' class="img-thumbnail"></p>

<h4>推奨サイズを持たないコンポーネントがある</h4>

<p>コンポーネントの中には、推奨サイズを持たないコンポーネントが存在します。<code>UIView</code> がそうです。UIView は子のビューのサイズによって自身のサイズが変わるため、
推奨サイズを持ちません。</p>

<p>逆に考えると、中のコンテンツのサイズが動的に変わる場合でも、UIView が親にいる限り、子のコンポーネントは好きにサイズが変わってよく、子のサイズが決まった段階で UIView のサイズ（bounds）が決まるということです。</p>

<p>この性質を使うと、UITableViewCell の中身が複雑に Auto Layout される場合でも、セルの高さを簡単に計算できるようになります。</p>

<h3>セルの中に UIView を配置して、その中にコンテンツを並べる</h3>

<p>カスタムの UITableViewCell には、<code>ContentView</code> という UIView が予め用意されていますが、この ContentView 、いまいち上手く Auto Layout してくれません。。
やり方が悪いだけのような気もしますが、僕は ContentView の子に UIView を入れるようにして、この UIView の上左右の padding を 0 に設定してレイアウトを始めるようにしています。</p>

<p><img src="http://hamasyou.com/images/20141008/SS7.png" width="800" title='"preferredView"' alt='"preferredView"' class="img-thumbnail"></p>

<p>bottom の制約を設定しないのがミソです。bottom の制約を設定しないことで、UIView は縦方向に自由に伸び縮みして、子のコンポーネントのサイズに合わせて高さが勝手に変わるようになります。</p>

<p>最後のコンポーネントを配置し終えたら、そのコンポーネントの bottom を親に対して設定をすれば、UIView の高さが子のコンポーネントの Auto Layout から決まるようになります。</p>

<p><img src="http://hamasyou.com/images/20141008/SS9.png" width="800" class="img-thumbnail" title=""></p>

<h3>推奨サイズをもつコンポーネントで位置とサイズで矛盾が起きた場合</h3>

<p>上の画像では、最後の要素の UILabel の bottom を親の Preferred View に対して設定していますが、UILabel の推奨サイズの高さと Preferred View からの bottom の位置とでコンフリクトが起きます。</p>

<p>Storyboard 上では、コンフリクトが起きると、赤い矢印マークがでます。実際には UILabel の高さを bottom の位置にまでの高さに設定することで矛盾は起きないのですが、
コレだと、高さが結局 UIView の高さに依存してしまい、UIView の高さは bottom を設定していないことから曖昧なサイズになってしまいます。</p>

<p>これだと思った様なレイアウトになりません。で、こんな時に設定するのが制約の <strong class="text-danger">priority</strong> です。制約同士でコンフリクトが起きた場合に、どちらの制約を優先的に適用するかを決めるのが priority になります。</p>

<p>今回は、<em>ラベルの高さを推奨サイズで配置して、その位置を元に UIView の高さを決めたい</em> ので、UILabel の bottom の制約の priority を下げます。UILabel の推奨サイズが決まる priority (Content Hugging Priority) が 251 なので、bottom の priority を 250 以下に設定すれば、
UILabel の推奨サイズを優先的に設定して、その高さからの bottom の位置が決まるようになります。</p>

<p><img src="http://hamasyou.com/images/20141008/SS10.png" width="240" class="img-thumbnail" title="">
<img src="http://hamasyou.com/images/20141008/SS11.png" width="500" class="img-thumbnail" title=""></p>

<h4>高さが決まらない UIView を配置すると、Storyboard 上での作業がしずらい場合</h4>

<p>高さが決まらない UIView を使うと、Storyboard 上で制約に合わせてコンポーネントの位置を自動調整するときに困ることがあります。</p>

<p>そんな時は、高さ（height）を適当に設定して、制約のところの <em>Placeholder Remove at build time</em> にチェックを入れておきます。
こうすることで、Storyboard 上の作業のときだけ制約が設定されて、実行時には制約が削除される状況を作ることができます。</p>

<p><img src="http://hamasyou.com/images/20141008/SS8.png" width="240" title='"Remove at build time"' alt='"Remove at build time"' class="img-thumbnail"></p>

<h3>UIView を使って擬似的な Preferred View を作ると高さ可変のセルが簡単につくれる</h3>

<p>このように、セルの ContentView の子要素に Preferred View を用意して、コンテンツのサイズで UIView の高さが決まるようにすることで、
Auto Layout を使った配置の中でセルの高さを可変にすることが結構簡単にできるようになります。</p>

<p><img src="http://hamasyou.com/images/20141008/SS1.png" width="240" title='"iPhone5S"' alt='"iPhone5S"' class="img-thumbnail">
<img src="http://hamasyou.com/images/20141008/SS12.png" width="240" title='"iPhone6 Plus"' alt='"iPhone6 Plus"' class="img-thumbnail"></p>

<p>他にもっと良いやり方があるかと思いますが、参考になればと思います。</p>

<h2>UIScrollView で Auto Layout を上手く使う方法</h2>

<p>UIScrollView も UITableViewCell と考え方は同じで、中のコンテンツを Auto Layout するときには Preferred View を用意して、
こいつにサイズを計算させて UIScrollView の contentSize を決めてやるようにします。</p>

<h3>UIScrollView のまとめ</h3>

<p>UIScrollView はビュー自体の <code>frame</code> とコンテンツ部分の <code>contentSize</code> の二つの要素を持ちます。frame はスクロールビュー自身の位置やサイズを表します。
contentSize はスクロールビューが表示するコンテンツのサイズを表していて、スクロールビューのサイズよりも大きい contentSize の場合には、スクロールビューの中でスクロールが発生するということになります。</p>

<h3>UIScrollView と Auto Layout</h3>

<p>UIScrollView で気を付けないといけないのは、<strong class="text-danger">contentSize は中に含まれるコンポーネントの frame や bounds で決まるわけではない</strong> ということです。</p>

<p>UIScrollView の contentSize はコンポーネントの <code>intrinsicContentSize</code> によって決まります。ここが UIScrollView でハマる一番のポイントかなと思います。</p>

<p>つまり、intrinsicContentSize （推奨サイズ）が決まるコンポーネントのみをコンテンツとして表示する場合には contentSize は Auto Layout が自動で計算してくれるということです。</p>

<p>例えば UIImageView を UIScrollView の中に入れたとします。UIImageView の intrinsicContentSize は UIImageView の frame や bounds ではなく、表示する UIImage の size になります。
なので、UIImageView だけを UIScrollView に入れると、UIImageView のサイズをいくら Storyboard 上で設定しても、勝手にスクロールされてしまうのです。</p>

<p><img src="http://hamasyou.com/images/20141008/SS13.png" width="800" title='"UIScrollView の罠"' alt='"UIScrollView の罠"' class="img-thumbnail"></p>

<p><img src="http://hamasyou.com/images/20141008/SS14.png" width="240" title='"UIScrollView の罠"' alt='"UIScrollView の罠"' class="img-thumbnail">
<img src="http://hamasyou.com/images/20141008/SS15.png" width="240" title='"UIScrollView の罠"' alt='"UIScrollView の罠"' class="img-thumbnail">
<img src="http://hamasyou.com/images/20141008/SS16.png" width="240" title='"UIScrollView の罠"' alt='"UIScrollView の罠"' class="img-thumbnail"></p>

<h3>UIScrollView のサイズに合わせて画像をページングする方法</h3>

<p>UIScrollView の contentSize は intrinsicContentSize によって決まるというのは、上で書きました。
じゃあ、contentSize をプログラムで上書きしちゃえば上手くスクロールするんでは？ということで、さがすと出てくるのが大体 <code>viewDidLayoutSubviews</code> の中で
contentSize を設定すればいいじゃんっていうプログラム例です。</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="swift"><span class="line"><span class="kr">override</span> <span class="k">func</span> <span class="nf">viewDidLayoutSubviews</span><span class="p">()</span> <span class="p">{</span>
</span><span class="line">    <span class="nb">super</span><span class="p">.</span><span class="n">viewDidLayoutSubviews</span><span class="p">()</span>
</span><span class="line">
</span><span class="line">    <span class="k">let</span> <span class="n">contentWidth</span> <span class="o">=</span> <span class="n">CGFloat</span><span class="p">(</span><span class="n">preferredViews</span><span class="p">.</span><span class="n">count</span><span class="p">)</span> <span class="o">*</span> <span class="n">scrollView</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">width</span>
</span><span class="line">    <span class="k">let</span> <span class="n">contentHeight</span> <span class="o">=</span> <span class="n">scrollView</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">height</span>
</span><span class="line">    <span class="n">scrollView</span><span class="p">.</span><span class="n">contentSize</span> <span class="o">=</span> <span class="n">CGSizeMake</span><span class="p">(</span><span class="n">contentWidth</span><span class="p">,</span> <span class="n">contentHeight</span><span class="p">)</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td>
</tr></table></div></figure>


<p>ぶっちゃけ、僕もこの方法が結局妥当かなという結論に達しました。先に UIScrollView に画像を動的に追加して、ページングできるようにするコードを掲載します。</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>
<span class="line-number">68</span>
<span class="line-number">69</span>
<span class="line-number">70</span>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="k">import</span> <span class="n">UIKit</span>
</span><span class="line">
</span><span class="line"><span class="k">class</span> <span class="nl">SecondViewController</span><span class="p">:</span> <span class="bp">UIViewController</span> <span class="p">{</span>
</span><span class="line">
</span><span class="line">    <span class="p">@</span><span class="kt">IBOutlet</span> <span class="k">weak</span> <span class="k">var</span> <span class="nl">scrollView</span><span class="p">:</span> <span class="bp">UIScrollView</span><span class="o">!</span>
</span><span class="line">
</span><span class="line">    <span class="k">var</span> <span class="nl">preferredViews</span><span class="p">:</span> <span class="p">[</span><span class="bp">UIView</span><span class="p">]</span><span class="o">!</span>
</span><span class="line">
</span><span class="line">    <span class="kr">override</span> <span class="k">func</span> <span class="n">viewDidLoad</span><span class="p">()</span> <span class="p">{</span>
</span><span class="line">        <span class="nb">super</span><span class="p">.</span><span class="n">viewDidLoad</span><span class="p">()</span>
</span><span class="line">
</span><span class="line">        <span class="k">let</span> <span class="n">images</span> <span class="o">=</span> <span class="p">[</span><span class="bp">UIImage</span><span class="p">(</span><span class="nl">named</span><span class="p">:</span> <span class="s">"Image1"</span><span class="p">),</span> <span class="bp">UIImage</span><span class="p">(</span><span class="nl">named</span><span class="p">:</span> <span class="s">"Image2"</span><span class="p">),</span> <span class="bp">UIImage</span><span class="p">(</span><span class="nl">named</span><span class="p">:</span> <span class="s">"Image3"</span><span class="p">)]</span>
</span><span class="line">        <span class="nb">self</span><span class="p">.</span><span class="n">preferredViews</span> <span class="o">=</span> <span class="p">[</span><span class="bp">UIView</span><span class="p">]()</span>
</span><span class="line">
</span><span class="line">        <span class="k">for</span> <span class="n">image</span> <span class="k">in</span> <span class="n">images</span> <span class="p">{</span>
</span><span class="line">            <span class="k">let</span> <span class="n">preferredView</span> <span class="o">=</span> <span class="bp">UIView</span><span class="p">(</span><span class="nl">frame</span><span class="p">:</span> <span class="n">CGRectMake</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">image</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">width</span><span class="p">,</span> <span class="n">image</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">height</span><span class="p">))</span>
</span><span class="line">            <span class="k">let</span> <span class="n">imageView</span> <span class="o">=</span> <span class="bp">UIImageView</span><span class="p">(</span><span class="nl">frame</span><span class="p">:</span> <span class="n">CGRectMake</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">image</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">width</span><span class="p">,</span> <span class="n">image</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">height</span><span class="p">))</span>
</span><span class="line">            <span class="n">imageView</span><span class="p">.</span><span class="n">image</span> <span class="o">=</span> <span class="n">image</span>
</span><span class="line">            <span class="n">imageView</span><span class="p">.</span><span class="n">contentMode</span> <span class="o">=</span> <span class="p">.</span><span class="n">ScaleAspectFill</span>
</span><span class="line">            <span class="n">imageView</span><span class="p">.</span><span class="n">clipsToBounds</span> <span class="o">=</span> <span class="nb">true</span>
</span><span class="line">            <span class="n">preferredView</span><span class="p">.</span><span class="n">setTranslatesAutoresizingMaskIntoConstraints</span><span class="p">(</span><span class="nb">false</span><span class="p">)</span>
</span><span class="line">            <span class="n">imageView</span><span class="p">.</span><span class="n">setTranslatesAutoresizingMaskIntoConstraints</span><span class="p">(</span><span class="nb">false</span><span class="p">)</span>
</span><span class="line">            <span class="n">preferredView</span><span class="p">.</span><span class="n">addSubview</span><span class="p">(</span><span class="n">imageView</span><span class="p">)</span>
</span><span class="line">            <span class="n">scrollView</span><span class="p">.</span><span class="n">addSubview</span><span class="p">(</span><span class="n">preferredView</span><span class="p">)</span>
</span><span class="line">
</span><span class="line">            <span class="n">preferredViews</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">preferredView</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><span class="line">    <span class="kr">override</span> <span class="k">func</span> <span class="n">updateViewConstraints</span><span class="p">()</span> <span class="p">{</span>
</span><span class="line">        <span class="nb">super</span><span class="p">.</span><span class="n">updateViewConstraints</span><span class="p">()</span>
</span><span class="line">
</span><span class="line">        <span class="k">var</span> <span class="nl">prevView</span><span class="p">:</span> <span class="bp">UIView</span><span class="o">?</span> <span class="o">=</span> <span class="nb">nil</span>
</span><span class="line">        <span class="k">for</span> <span class="n">preferredView</span> <span class="k">in</span> <span class="n">preferredViews</span> <span class="p">{</span>
</span><span class="line">            <span class="k">let</span> <span class="n">imageView</span> <span class="o">=</span> <span class="n">preferredView</span><span class="p">.</span><span class="n">subviews</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="kt">as</span> <span class="bp">UIImageView</span>
</span><span class="line">            <span class="n">preferredView</span><span class="p">.</span><span class="n">addConstraints</span><span class="p">(</span><span class="bp">NSLayoutConstraint</span><span class="p">.</span><span class="n">constraintsWithVisualFormat</span><span class="p">(</span><span class="s">"H:|[imageView]|"</span><span class="p">,</span>
</span><span class="line">                <span class="nl">options</span><span class="p">:</span> <span class="nb">nil</span><span class="p">,</span> <span class="nl">metrics</span><span class="p">:</span> <span class="nb">nil</span><span class="p">,</span> <span class="nl">views</span><span class="p">:</span> <span class="p">[</span><span class="s">"imageView"</span><span class="o">:</span> <span class="n">imageView</span><span class="p">]))</span>
</span><span class="line">            <span class="n">preferredView</span><span class="p">.</span><span class="n">addConstraints</span><span class="p">(</span><span class="bp">NSLayoutConstraint</span><span class="p">.</span><span class="n">constraintsWithVisualFormat</span><span class="p">(</span><span class="s">"V:|[imageView]|"</span><span class="p">,</span>
</span><span class="line">                <span class="nl">options</span><span class="p">:</span> <span class="nb">nil</span><span class="p">,</span> <span class="nl">metrics</span><span class="p">:</span> <span class="nb">nil</span><span class="p">,</span> <span class="nl">views</span><span class="p">:</span> <span class="p">[</span><span class="s">"imageView"</span><span class="o">:</span> <span class="n">imageView</span><span class="p">]))</span>
</span><span class="line">
</span><span class="line">            <span class="k">if</span> <span class="n">prevView</span> <span class="o">==</span> <span class="nb">nil</span> <span class="p">{</span>
</span><span class="line">                <span class="n">scrollView</span><span class="p">.</span><span class="n">addConstraints</span><span class="p">(</span><span class="bp">NSLayoutConstraint</span><span class="p">.</span><span class="n">constraintsWithVisualFormat</span><span class="p">(</span><span class="s">"H:|[preferredView(==scrollView)]"</span><span class="p">,</span>
</span><span class="line">                    <span class="nl">options</span><span class="p">:</span> <span class="nb">nil</span><span class="p">,</span> <span class="nl">metrics</span><span class="p">:</span> <span class="nb">nil</span><span class="p">,</span> <span class="nl">views</span><span class="p">:</span> <span class="p">[</span><span class="s">"scrollView"</span><span class="o">:</span> <span class="n">scrollView</span><span class="p">,</span> <span class="s">"preferredView"</span><span class="o">:</span> <span class="n">preferredView</span><span class="p">]))</span>
</span><span class="line">            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class="line">                <span class="n">scrollView</span><span class="p">.</span><span class="n">addConstraints</span><span class="p">(</span><span class="bp">NSLayoutConstraint</span><span class="p">.</span><span class="n">constraintsWithVisualFormat</span><span class="p">(</span><span class="s">"H:[prevView][preferredView(==scrollView)]"</span><span class="p">,</span>
</span><span class="line">                    <span class="nl">options</span><span class="p">:</span> <span class="nb">nil</span><span class="p">,</span> <span class="nl">metrics</span><span class="p">:</span> <span class="nb">nil</span><span class="p">,</span> <span class="nl">views</span><span class="p">:</span> <span class="p">[</span><span class="s">"scrollView"</span><span class="o">:</span> <span class="n">scrollView</span><span class="p">,</span> <span class="s">"prevView"</span><span class="o">:</span> <span class="n">prevView</span><span class="o">!</span><span class="p">,</span> <span class="s">"preferredView"</span><span class="o">:</span> <span class="n">preferredView</span><span class="p">]))</span>
</span><span class="line">            <span class="p">}</span>
</span><span class="line">            <span class="n">scrollView</span><span class="p">.</span><span class="n">addConstraints</span><span class="p">(</span><span class="bp">NSLayoutConstraint</span><span class="p">.</span><span class="n">constraintsWithVisualFormat</span><span class="p">(</span><span class="s">"V:|[preferredView(==scrollView)]"</span><span class="p">,</span>
</span><span class="line">                <span class="nl">options</span><span class="p">:</span> <span class="nb">nil</span><span class="p">,</span> <span class="nl">metrics</span><span class="p">:</span> <span class="nb">nil</span><span class="p">,</span> <span class="nl">views</span><span class="p">:</span> <span class="p">[</span><span class="s">"scrollView"</span><span class="o">:</span> <span class="n">scrollView</span><span class="p">,</span> <span class="s">"preferredView"</span><span class="o">:</span> <span class="n">preferredView</span><span class="p">]))</span>
</span><span class="line">
</span><span class="line">            <span class="n">prevView</span> <span class="o">=</span> <span class="n">preferredView</span>
</span><span class="line">        <span class="p">}</span>
</span><span class="line">
</span><span class="line">    <span class="p">}</span>
</span><span class="line">
</span><span class="line">
</span><span class="line">    <span class="kr">override</span> <span class="k">func</span> <span class="n">viewDidLayoutSubviews</span><span class="p">()</span> <span class="p">{</span>
</span><span class="line">        <span class="nb">super</span><span class="p">.</span><span class="n">viewDidLayoutSubviews</span><span class="p">()</span>
</span><span class="line">
</span><span class="line">        <span class="k">let</span> <span class="n">contentWidth</span> <span class="o">=</span> <span class="n">CGFloat</span><span class="p">(</span><span class="n">preferredViews</span><span class="p">.</span><span class="n">count</span><span class="p">)</span> <span class="o">*</span> <span class="n">scrollView</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">width</span>
</span><span class="line">        <span class="k">let</span> <span class="n">contentHeight</span> <span class="o">=</span> <span class="n">scrollView</span><span class="p">.</span><span class="n">bounds</span><span class="p">.</span><span class="n">height</span>
</span><span class="line">        <span class="n">scrollView</span><span class="p">.</span><span class="n">contentSize</span> <span class="o">=</span> <span class="n">CGSizeMake</span><span class="p">(</span><span class="n">contentWidth</span><span class="p">,</span> <span class="n">contentHeight</span><span class="p">)</span>
</span><span class="line">    <span class="p">}</span>
</span><span class="line">
</span><span class="line">    <span class="kr">override</span> <span class="k">func</span> <span class="n">didReceiveMemoryWarning</span><span class="p">()</span> <span class="p">{</span>
</span><span class="line">        <span class="nb">super</span><span class="p">.</span><span class="n">didReceiveMemoryWarning</span><span class="p">()</span>
</span><span class="line">        <span class="c1">// Dispose of any resources that can be recreated.</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><img src="http://hamasyou.com/images/20141008/SS17.png" width="800" class="img-thumbnail" title=""></p>

<p><img src="http://hamasyou.com/images/20141008/SS18.png" width="240" class="img-thumbnail" title="">
<img src="http://hamasyou.com/images/20141008/SS19.png" width="240" class="img-thumbnail" title=""></p>

<p>UIScrollView の中に画像を3つ表示して、それをページングスクロールするコードになります。Paging Enabled のオプションは Storyboard 上で設定しています。</p>

<p>画像を直接 UIScrollView にいれてしまうと、intrinsicContentSize の問題で表示が意図したとおりにならないので、UIImageView をラップする PreferredView を作成しています。</p>

<p>PreferredView の中に UIImageView を隙間なく配置し、PreferredView を ScrollView の縦横のサイズと同じサイズにして、Auto Layout で左から順番に配置しています。
ぶっちゃけ、この処理であれば、<code>UICollectionView</code> を使うほうが早いし楽だし美しいと思います。</p>

<p>UIScrollView で Auto Layout を使って頑張ってスクロールコンテンツを配置したいときに、参考になるといいと思っています。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[[iOS] ReactiveCocoa の RACCommand で、実行中にローディングを出す方法]]></title>
    <link href="http://hamasyou.com/blog/2014/09/19/reactivecocoa-raccommand-executing/"/>
    <updated>2014-09-19T18:13:11+09:00</updated>
    <id>http://hamasyou.com/blog/2014/09/19/reactivecocoa-raccommand-executing/</id>
    <content type="html"><![CDATA[<p>最近 <a href="https://github.com/ReactiveCocoa/ReactiveCocoa" rel="external nofollow" title="ReactiveCocoa">ReactiveCocoa</a> を使いまくってます。そのなかで調べた Signal の使い方イディオムのメモです。</p>

<p>RACCommand で検索処理とかしてるときに、ローディング画面やインジケータを表示したいということがあると思います。そういうときに使える Signal のイディオムです。コードは Swift で書いています。</p>

<p><em>MVVM</em> で viewModel が searchCommand を実装しているとします。また、ローディングインジケータの表示には <a href="https://github.com/jdg/MBProgressHUD" rel="external nofollow" title="MBProgressHUD">MBProgressHUD</a> を使っているとします。</p>

<figure class="code"><figcaption><span>MyViewController#viewDidLoad</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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="n">searchButton</span><span class="p">.</span><span class="n">rac_command</span> <span class="o">=</span> <span class="n">viewModel</span><span class="p">.</span><span class="n">searchCommand</span>
</span><span class="line"><span class="n">searchButton</span><span class="p">.</span><span class="n">rac_command</span><span class="p">.</span><span class="n">executing</span>
</span><span class="line">    <span class="p">.</span><span class="n">subscribeNext</span><span class="p">({</span> <span class="p">[</span><span class="k">weak</span> <span class="nb">self</span><span class="p">]</span> <span class="p">(</span><span class="n">executing</span><span class="p">)</span> <span class="k">in</span>
</span><span class="line">        <span class="k">if</span> <span class="k">let</span> <span class="n">weakSelf</span> <span class="o">=</span> <span class="nb">self</span> <span class="p">{</span>
</span><span class="line">            <span class="k">if</span> <span class="n">executing</span> <span class="kt">as</span> <span class="n">Bool</span> <span class="p">{</span>
</span><span class="line">                <span class="n">MBProgressHUD</span><span class="p">.</span><span class="n">showHUDAddedTo</span><span class="p">(</span><span class="n">weakSelf</span><span class="p">.</span><span class="n">view</span><span class="p">,</span> <span class="nl">animated</span><span class="p">:</span> <span class="nb">true</span><span class="p">)</span>
</span><span class="line">            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class="line">                <span class="n">MBProgressHUD</span><span class="p">.</span><span class="n">hideHUDForView</span><span class="p">(</span><span class="n">weakSelf</span><span class="p">.</span><span class="n">view</span><span class="p">,</span> <span class="nl">animated</span><span class="p">:</span> <span class="nb">true</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="p">})</span>
</span><span class="line"><span class="n">searchButton</span><span class="p">.</span><span class="n">rac_command</span><span class="p">.</span><span class="n">errors</span>
</span><span class="line">    <span class="p">.</span><span class="n">subscribeNext</span><span class="p">({</span> <span class="p">(</span><span class="n">error</span><span class="p">)</span> <span class="k">in</span>
</span><span class="line">        <span class="c1">// エラー時のメッセージ表示処理</span>
</span><span class="line">        <span class="n">println</span><span class="p">(</span><span class="n">error</span><span class="p">.</span><span class="n">localizedDescription</span><span class="p">)</span>
</span><span class="line">    <span class="p">})</span>
</span></code></pre></td>
</tr></table></div></figure>


<p><code>executing</code> Signal はこういう風につかうんですね。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[[Swift] 多次元配列の定義の謎]]></title>
    <link href="http://hamasyou.com/blog/2014/09/12/swift-mysterious-multi-dimensional-array/"/>
    <updated>2014-09-12T11:21:20+09:00</updated>
    <id>http://hamasyou.com/blog/2014/09/12/swift-mysterious-multi-dimensional-array/</id>
    <content type="html"><![CDATA[<p>Xcode6 GM でましたね！ Beta1 の頃から Swift 触ってますが、まぁ言語仕様がよく変わること（笑。</p>

<p>で、いつか直るだろうと思ってたけど、GM でも直っていない Swift の多次元配列の定義の謎に関してです。だれか理由分かる人いたら教えてください。。</p>

<p>下のようなコードがあるとします。</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="swift"><span class="line"><span class="k">typealias</span> <span class="n">NameAndValue</span> <span class="o">=</span> <span class="n">Dictionary</span><span class="o">&lt;</span><span class="n">String</span><span class="p">,</span> <span class="n">String</span><span class="o">&gt;</span>
</span><span class="line">
</span><span class="line"><span class="k">let</span> <span class="nl">dict</span><span class="p">:</span> <span class="p">[[</span><span class="n">NameAndValue</span><span class="p">]]</span> <span class="o">=</span> <span class="p">[</span>
</span><span class="line">  <span class="p">[</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</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="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">  <span class="p">]]</span>
</span></code></pre></td>
</tr></table></div></figure>


<p><code>typealias</code> で別名つけて2次元配列を定義しているだけです。要素が <code>Dictionary</code> になっています。ここまでは普通にコンパイルが通ります。</p>

<p>ですが、これをこんなふうに…</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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="k">let</span> <span class="nl">dict</span><span class="p">:</span> <span class="p">[[</span><span class="n">NameAndValue</span><span class="p">]]</span> <span class="o">=</span> <span class="p">[</span>
</span><span class="line">  <span class="p">[</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">     <span class="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</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="p">[</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">],</span>
</span><span class="line">  <span class="p">]]</span>
</span></code></pre></td>
</tr></table></div></figure>


<p>配列の要素を増やしていきます。そうするとだいたい <strong class="text-danger">10件くらい</strong> からコンパイルが遅くなり、<strong class="text-danger">15件過ぎたくらいから</strong> コンパイルエラーが出るようになります。</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="swift"><span class="line"><span class="n">Cannot</span> <span class="n">convert</span> <span class="n">the</span> <span class="n">expression</span><span class="err">'</span><span class="n">s</span> <span class="n">type</span> <span class="err">'</span><span class="p">[[</span><span class="n">NameAndValue</span><span class="p">]]</span><span class="err">'</span> <span class="n">to</span> <span class="n">type</span> <span class="err">'</span><span class="n">StringLiteralConvertible</span><span class="err">'</span>
</span></code></pre></td>
</tr></table></div></figure>


<p>意味がわからんです。。</p>

<p>仕方ないので</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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="k">var</span> <span class="nl">dict</span><span class="p">:</span> <span class="p">[[</span><span class="n">NameAndValue</span><span class="p">]]</span> <span class="o">=</span> <span class="p">[[],[]]</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line">
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span><span class="line"><span class="n">dict</span><span class="p">[</span><span class="mi">1</span><span class="p">].</span><span class="n">append</span><span class="p">([</span><span class="s">"name"</span><span class="o">:</span> <span class="s">""</span><span class="p">,</span>    <span class="s">"value"</span><span class="o">:</span> <span class="s">""</span><span class="p">])</span>
</span></code></pre></td>
</tr></table></div></figure>


<p></p>

<p>こうやって、プログラムでデータ登録するようにしました。。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[APIデザインの極意 Java/NetBeansアーキテクト探究ノート]]></title>
    <link href="http://hamasyou.com/blog/2014/08/30/484433591x/"/>
    <updated>2014-08-30T12:40:36+09:00</updated>
    <id>http://hamasyou.com/blog/2014/08/30/484433591x/</id>
    <content type="html"><![CDATA[<p>本書は <strong class="text-danger">プログラミング API</strong> の設計本です。Web API の設計極意に関して知りたい人は 『<a href="http://www.amazon.co.jp/gp/product/4873113539?ie=UTF8&amp;camp=247&amp;creativeASIN=4873113539&amp;linkCode=xm2&amp;tag=sorehabooks-22" rel="external nofollow" title="RESTful Webサービス">RESTful Webサービス</a>』や『<a href="http://www.amazon.co.jp/gp/product/4774142042?ie=UTF8&amp;tag=sorehabooks-22&amp;linkCode=xm2&amp;camp=247&amp;creativeASIN=4774142042" rel="external nofollow" title="Webを支える技術 -HTTP、URI、HTML、そしてREST">Webを支える技術 -HTTP、URI、HTML、そしてREST</a>』を読むのがいいと思います。本書は <a href="http://www.amazon.co.jp/gp/product/4797311126?ie=UTF8&amp;camp=247&amp;creativeASIN=4797311126&amp;linkCode=xm2&amp;tag=sorehabooks-22" rel="external nofollow" title="GoF のデザインパターン">GoF のデザインパターン
</a> や <a href="http://www.amazon.co.jp/gp/product/4621066056?ie=UTF8&amp;camp=247&amp;creativeASIN=4621066056&amp;linkCode=xm2&amp;tag=sorehabooks-22" rel="external nofollow" title="EFFECTIVE JAVA">EFFECTIVE JAVA</a> を読んだ開発者が次に読むべき本として紹介されています。</p>

<p><a href="http://www.amazon.co.jp/gp/product/4873113539?ie=UTF8&amp;camp=247&amp;creativeASIN=4873113539&amp;linkCode=xm2&amp;tag=sorehabooks-22" rel="external nofollow" title=""><img src="http://ecx.images-amazon.com/images/I/51ojIhXBP3L._SS140_.jpg" alt="RESTful Webサービス" class="img-thumbnail" title="RESTful Webサービス"></a>
<a href="http://www.amazon.co.jp/gp/product/4774142042?ie=UTF8&amp;tag=sorehabooks-22&amp;linkCode=xm2&amp;camp=247&amp;creativeASIN=4774142042" rel="external nofollow" title=""><img src="http://ecx.images-amazon.com/images/I/51qo6pgjaSL._SS140_.jpg" alt="Webを支える技術 -HTTP、URI、HTML、そしてREST" class="img-thumbnail" title="Webを支える技術 -HTTP、URI、HTML、そしてREST"></a>
<a href="http://www.amazon.co.jp/gp/product/4797311126?ie=UTF8&amp;camp=247&amp;creativeASIN=4797311126&amp;linkCode=xm2&amp;tag=sorehabooks-22" rel="external nofollow" title=""><img src="http://ecx.images-amazon.com/images/I/61YX3ZDFIwL._SS140_.jpg" alt="オブジェクト指向における再利用のためのデザインパターン" class="img-thumbnail" title="オブジェクト指向における再利用のためのデザインパターン"></a>
<a href="http://www.amazon.co.jp/gp/product/4621066056?ie=UTF8&amp;camp=247&amp;creativeASIN=4621066056&amp;linkCode=xm2&amp;tag=sorehabooks-22" rel="external nofollow" title=""><img src="http://ecx.images-amazon.com/images/I/91tYrFpKmLL._SS140_.jpg" alt="EFFECTIVE JAVA 第2版" class="img-thumbnail" title="EFFECTIVE JAVA 第2版"></a></p>

<p>本書は、NetBeans API を構築した筆者がデザインパターンやコーディング作法だけではうまくいかない問題、後方互換性を維持したままライブラリを発展させる方法、を重点的に解説しています。なるほど、 <strong class="text-danger">デザインパターンや設計方法を学んだ次に読むべき本</strong> として挙げられている理由がよくわかる内容になっています。</p>

<!-- more -->


<h3>社内ライブラリと API 設計は別物</h3>

<p>本書で扱う API という言葉は、例えばオープンソースライブラリのような、多くの人に共有されるものという位置づけになっています。社内で使うようなライブラリなどの API とはニュアンスが違う感じがしました。</p>

<p>一度リリースしたら、後方互換性を維持して発展させていかなければならない、そういった類のライブラリや API を作る開発者向けの本です。</p>

<h2>本書のテーマ</h2>

<p>本書のテーマは、次の2つに集約されると思います。</p>

<ul>
<li>後方互換性を維持する API のデザインパターン</li>
<li>優れた API であるためにどうするか</li>
</ul>


<p>NetBeans API で培った経験則を余す所なく記載してくれているため、ボリュームがスゴイことになっています。また、作って終わりの API の作り方を教えているわけではないので、おそらくほとんどの開発者には <em>なんとなくわかった気になるだけか難しくて後回しにする</em> ような内容かもしれません。</p>

<p>はっきり言って、本書が役に立った！と感じる開発者は少ないかもしれませんが、少なくとも GitHub でソースコードを公開している開発者は頑張って読んでもらうのがいいと思いました。それくらい内容が濃く、経験者しかわからないことが書いてあります。</p>

<h3>後方互換性を維持する API のデザインパターン</h3>

<blockquote>
<p>開発者は、API の現在のバージョンをコーディングしている場合に、未来について考えることが求められます。私に言えることは、それは、今までの API 設計でよく行われた方法ではないということです。また、今日までに書かれた書籍やその中の助言は、この種の思考にはあまり役に立ちません。それらには、単一バージョンの場合のデザインパターンが説明されていることがほとんどです。</p>
<footer><strong>本書</strong></footer>
</blockquote>


<p>これが、<strong class="text-danger">新しいデザイン本が必要な理由</strong> です。今日のシステムはコンポーネントの組み合わせで出来ています。おそらく今後もこの傾向は変わらないと思います。コンポーネント利用者の経験（投資）をムダにしない為に、よりよい発展を目指す上で、後方互換性を維持することは重要なことになります。これが、<strong class="text-danger">本書を読む理由</strong> です。</p>

<h3>優れた API であるためにどうするか</h3>

<p>では、どのように API 設計をすればいいか。その方法も本書に書かれています。</p>

<ul>
<li>メソッドとフィールドの優れたシグニチャ</li>
<li>ファイル操作</li>
<li>環境変数とコマンドラインオプション</li>
<li>API としてのテキストメッセージ</li>
<li>（ネットワーク）プロトコル</li>
<li>API の振る舞い</li>
<li>I18N と L10N のサポート</li>
<li>API の品質検査方法（正しさの証明）</li>
<li>理解しやすさ</li>
<li>一貫性</li>
<li>やりたいことが満たせる API を発見できること</li>
<li>単純なことを簡単に行えること</li>
<li>投資の保全（利用者を尊重すること）</li>
</ul>


<p>API に優れた名前をつけることや <strong class="text-danger">驚き最小の法則</strong>、シンプルで一貫性のある I/F にするというのは基本的にな事になります。こういったことを踏まえた上で、この API を利用してくれているユーザを尊重すること（次のバージョンでメソッド名を変更するなんてとんでもない！）が大切だと書かれています。</p>

<p>後方互換性を保ち、API のユーザの投資をムダにしない設計の方法を学びたい人、新しい視点を身につけたい人に本書はおすすめです。</p>

<blockquote><p>- オブジェクト指向アプリケーションフレームワークには、伝統的なデザインパターンとは異なるスキルが必要<br>- クラスを API として扱って、頭痛の種を軽減<br>- 将来、改善できるように API の発展計画を準備</p></blockquote>


<h2>目次</h2>

<ul>
<li>【第1部　理論と正当性】

<ul>
<li>第1章　 現代的なソフトウェア構築の技芸</li>
<li>第2章　 APIを作成する動機</li>
<li>第3章　 優れたAPIを決定づけるもの</li>
<li>第4章　 絶え間なく変わる標的</li>
</ul>
</li>
<li>【第2部　実践的設計】

<ul>
<li>第5章　 必要以上に公開しない</li>
<li>第6章　 実装ではなく、インタフェースに対してコーディングする</li>
<li>第7章　 モジュール方式アーキテクチャの使用</li>
<li>第8章　 クライアント用とプロバイダ用のAPIを分離</li>
<li>第9章　 テストの容易性に留意する</li>
<li>第10章　他のAPIとの協調</li>
<li>第11章　APIの実行時の側面</li>
<li>第12章　宣言型プログラミング</li>
</ul>
</li>
<li>【第3部　日々の生活】

<ul>
<li>第13章　有害で極端な助言</li>
<li>第14章　API設計のパラドックス</li>
<li>第15章　API宇宙の発展</li>
<li>第16章　チームワーク</li>
<li>第17章　ゲームでAPI設計スキルを向上させる</li>
<li>第18章　拡張可能なビジターパターンのケーススタディ</li>
<li>第19章　終焉の手続き</li>
</ul>
</li>
<li>終章：将来</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[[ReactiveCocoa] catchTo の使いどころ]]></title>
    <link href="http://hamasyou.com/blog/2014/08/29/reactivecocoa-catchto/"/>
    <updated>2014-08-29T19:44:49+09:00</updated>
    <id>http://hamasyou.com/blog/2014/08/29/reactivecocoa-catchto/</id>
    <content type="html"><![CDATA[<p><strong class="text-danger">ReactiveCocoa</strong> で <code>catchTo</code> の使い方を覚えたのでメモ。</p>

<p><i class="fa fa-hand-o-right"></i> <a href="https://github.com/ReactiveCocoa/ReactiveCocoa" rel="external nofollow" title="ReactiveCocoa">ReactiveCocoa</a></p>

<p>リアクティブプログラミングの詳細は省くとして、<code>RACSignal</code> のイベントには <code>next</code> と <code>completed</code> と <code>error</code> があります。それぞれ、<code>subscribeNext</code>、<code>subscribeCompleted</code>、<code>subscribeError</code> でハンドリングできるやつです。</p>

<p>で、HTTP API 等を呼び出す際に API 呼び出しの結果を JSON にパースして、結果をモデルに設定するみたいなことをやりたい時に、次のように行います。（Swift で記述しています。）</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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="n">RAC</span><span class="p">(</span><span class="nb">self</span><span class="p">,</span> <span class="s">"model"</span><span class="p">)</span> <span class="o">&lt;~</span> <span class="n">API</span><span class="p">.</span><span class="n">loadData</span><span class="p">()</span>
</span><span class="line">
</span><span class="line"><span class="k">class</span> <span class="n">API</span> <span class="p">{</span>
</span><span class="line">    <span class="k">class</span> <span class="k">func</span> <span class="n">loadData</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">RACSignal</span> <span class="p">{</span>
</span><span class="line">        <span class="k">return</span> <span class="n">RACSignal</span><span class="p">.</span><span class="n">createSignal</span><span class="p">({</span> <span class="p">(</span><span class="nl">subscriber</span><span class="p">:</span> <span class="n">RACSubscriber</span><span class="o">!</span><span class="p">)</span> <span class="k">in</span>
</span><span class="line">            <span class="k">let</span> <span class="n">url</span> <span class="o">=</span> <span class="bp">NSURL</span><span class="p">(</span><span class="nl">string</span><span class="p">:</span> <span class="s">"http://localhost:300/search"</span><span class="p">)</span>
</span><span class="line">            <span class="k">let</span> <span class="n">configuration</span> <span class="o">=</span> <span class="bp">NSURLSessionConfiguration</span><span class="p">.</span><span class="n">defaultSessionConfiguration</span><span class="p">()</span>
</span><span class="line">            <span class="n">configuration</span><span class="p">.</span><span class="n">HTTPAdditionalHeaders</span> <span class="o">=</span> <span class="p">[</span><span class="s">"Accept"</span><span class="o">:</span> <span class="s">"application/json"</span><span class="p">]</span>
</span><span class="line">            <span class="k">let</span> <span class="nl">session</span><span class="p">:</span> <span class="bp">NSURLSession</span> <span class="o">=</span> <span class="bp">NSURLSession</span><span class="p">(</span><span class="nl">configuration</span><span class="p">:</span> <span class="n">configuration</span><span class="p">)</span>
</span><span class="line">            <span class="k">let</span> <span class="nl">task</span><span class="p">:</span> <span class="bp">NSURLSessionDataTask</span> <span class="o">=</span> <span class="n">session</span><span class="p">.</span><span class="n">dataTaskWithURL</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="nl">completionHandler</span><span class="p">:</span> <span class="p">{</span> <span class="p">(</span><span class="nl">data</span><span class="p">:</span> <span class="bp">NSData</span><span class="o">!</span><span class="p">,</span> <span class="nl">response</span><span class="p">:</span> <span class="bp">NSURLResponse</span><span class="o">!</span><span class="p">,</span> <span class="nl">error</span><span class="p">:</span> <span class="bp">NSError</span><span class="o">!</span><span class="p">)</span> <span class="k">in</span>
</span><span class="line">                <span class="k">if</span> <span class="n">error</span> <span class="o">==</span> <span class="nb">nil</span> <span class="p">{</span>
</span><span class="line">                    <span class="c1">// data をパースしてモデル化</span>
</span><span class="line">                    <span class="n">subscriber</span><span class="p">.</span><span class="n">sendNext</span><span class="p">(</span><span class="n">model</span><span class="p">)</span>
</span><span class="line">                    <span class="n">subscriber</span><span class="p">.</span><span class="n">sendCompleted</span><span class="p">()</span>
</span><span class="line">                <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class="line">                    <span class="n">subscriber</span><span class="p">.</span><span class="n">sendError</span><span class="p">(</span><span class="n">error</span><span class="p">)</span>
</span><span class="line">                <span class="p">}</span>
</span><span class="line">                <span class="n">session</span><span class="p">.</span><span class="n">invalidateAndCancel</span><span class="p">()</span>
</span><span class="line">            <span class="p">})</span>
</span><span class="line">            <span class="n">task</span><span class="p">.</span><span class="n">resume</span><span class="p">()</span>
</span><span class="line">            <span class="k">return</span> <span class="nb">nil</span>
</span><span class="line">        <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>こうすると、API の呼び出しが成功した場合には <code>subscriber.sendNext</code> の結果がきちんと <code>self.model</code> に設定されるわけですが、API の呼び出しが失敗して <code>subscriber.sendError</code> が呼び出されてしまうと、例外がなげられます。</p>

<p>ではどうするか。</p>

<h3>catchTo を使って sendError に備える</h3>

<p>そこで <code>catchTo</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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="n">RAC</span><span class="p">(</span><span class="nb">self</span><span class="p">,</span> <span class="s">"model"</span><span class="p">)</span> <span class="o">&lt;~</span> <span class="n">API</span><span class="p">.</span><span class="n">loadData</span><span class="p">().</span><span class="n">catchTo</span><span class="p">(</span><span class="n">RACSignal</span><span class="p">.</span><span class="n">empty</span><span class="p">())</span>
</span></code></pre></td>
</tr></table></div></figure>


<p><code>catchTo</code> は <code>sendError</code> が呼び出された場合に代わりに投げる <code>RACSignal</code> を指定します。そうすることで、ネットワークエラー等で API の呼び出しが失敗した場合には、<code>RACSignal.empty()</code> で何も起きなかったことになる（正確には sendCompleted が呼び出される）ようになります。</p>

<p>sendError 時に処理を行いたい場合には <code>catch</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="swift"><span class="line"><span class="n">RAC</span><span class="p">(</span><span class="nb">self</span><span class="p">,</span> <span class="s">"model"</span><span class="p">)</span> <span class="o">&lt;~</span> <span class="n">API</span><span class="p">.</span><span class="n">loadData</span><span class="p">()</span>
</span><span class="line">    <span class="p">.</span><span class="n">catch</span><span class="p">({</span> <span class="p">(</span><span class="nl">error</span><span class="p">:</span> <span class="bp">NSError</span><span class="o">!</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">RACSignal</span><span class="o">!</span> <span class="k">in</span>
</span><span class="line">        <span class="k">return</span> <span class="n">RACSignal</span><span class="p">.</span><span class="n">empty</span><span class="p">()</span>
</span><span class="line">    <span class="p">})</span>
</span></code></pre></td>
</tr></table></div></figure>


<p>以上です。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Swift での Dictionary<String, AnyObject> の扱いメモ]]></title>
    <link href="http://hamasyou.com/blog/2014/08/28/swift-dictionary-anyobject/"/>
    <updated>2014-08-28T00:12:25+09:00</updated>
    <id>http://hamasyou.com/blog/2014/08/28/swift-dictionary-anyobject/</id>
    <content type="html"><![CDATA[<p>Swift で <code>Dictionary</code> を扱うときのメモです。API 呼び出しのレスポンスを JSON で扱いたい時に <code>Dictionary&lt;String, AnyObject&gt;</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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="k">typealias</span> <span class="n">JSONDictionary</span> <span class="o">=</span> <span class="n">Dictionary</span><span class="o">&lt;</span><span class="n">String</span><span class="p">,</span> <span class="n">AnyObject</span><span class="o">&gt;</span>
</span><span class="line"><span class="k">let</span> <span class="n">json</span> <span class="o">=</span> <span class="bp">NSJSONSerialization</span><span class="p">.</span><span class="n">JSONObjectWithData</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="nl">options</span><span class="p">:</span> <span class="p">.</span><span class="n">MutableContainers</span><span class="p">,</span> <span class="nl">error</span><span class="p">:</span> <span class="nb">nil</span><span class="p">)</span> <span class="kt">as</span> <span class="n">JSONDictionary</span>
</span><span class="line">
</span><span class="line"><span class="k">let</span> <span class="n">str1</span> <span class="o">=</span> <span class="n">json</span><span class="p">[</span><span class="s">"foobar"</span><span class="p">]</span><span class="o">!</span> <span class="kt">as</span> <span class="n">String</span>    <span class="c1">// String</span>
</span><span class="line"><span class="k">let</span> <span class="n">str2</span> <span class="o">=</span> <span class="n">json</span><span class="p">[</span><span class="s">"foobar"</span><span class="p">]</span> <span class="kt">as</span> <span class="n">AnyObject</span><span class="o">?</span> <span class="kt">as</span><span class="o">?</span> <span class="n">String</span>  <span class="c1">// String?</span>
</span><span class="line">
</span><span class="line"><span class="k">let</span> <span class="n">str3</span> <span class="o">=</span> <span class="n">json</span><span class="p">[</span><span class="s">"foobar"</span><span class="p">]</span> <span class="kt">as</span> <span class="n">String</span>     <span class="c1">// これはコンパイルエラー '(String, AnyObject)' is not convertible to 'String'</span>
</span></code></pre></td>
</tr></table></div></figure>


<p>最後のはなぜコンパイルエラーになるかというと、<code>Dictionary</code> の <code>subscript</code> が2種類定義されていて、期待したのと違う方が呼び出されているからです。</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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="k">struct</span> <span class="n">Dictionary</span><span class="o">&lt;</span><span class="nl">Key</span> <span class="p">:</span> <span class="n">Hashable</span><span class="p">,</span> <span class="n">Value</span><span class="o">&gt;</span> <span class="o">:</span> <span class="n">CollectionType</span><span class="p">,</span> <span class="n">DictionaryLiteralConvertible</span> <span class="p">{</span>
</span><span class="line">    <span class="p">...</span>
</span><span class="line">    <span class="k">subscript</span> <span class="p">(</span><span class="nl">i</span><span class="p">:</span> <span class="n">DictionaryIndex</span><span class="o">&lt;</span><span class="n">Key</span><span class="p">,</span> <span class="n">Value</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="p">(</span><span class="n">Key</span><span class="p">,</span> <span class="n">Value</span><span class="p">)</span> <span class="p">{</span> <span class="kr">get</span> <span class="p">}</span>
</span><span class="line">    <span class="k">subscript</span> <span class="p">(</span><span class="nl">key</span><span class="p">:</span> <span class="n">Key</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Value</span><span class="o">?</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><code>json["foobar"]</code> の戻り値は <code>(Key, Value)</code> か <code>Value?</code> のどちらかですが、<code>as String</code> を付けた際に Optional ではないと判断されてしまい <code>(Key, Value)</code> が戻り値の型と判定されます。それでコンパイルエラーになるわけですね。</p>

<p>期待した通りに取得するには、<code>json["foobar"]</code> の戻り値を <code>Value?</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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="n">json</span><span class="p">[</span><span class="s">"foobar"</span><span class="p">]</span><span class="o">!</span>
</span><span class="line"><span class="n">json</span><span class="p">[</span><span class="s">"foobar"</span><span class="p">]</span> <span class="kt">as</span> <span class="n">AnyObject</span><span class="o">?</span>
</span></code></pre></td>
</tr></table></div></figure>


<p>のどちらかでアクセスする必要があるわけです。<code>!</code> を付けると unwrap されるので <code>nil</code> が入っていると実行時エラーになります。逆に <code>as AnyObject? as? String</code> でアクセスすると Optional 型になってしまいます。</p>

<p>API のインターフェースと相談して、どちらの型で処理するか決めるといいんじゃないかと思います。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[SwiftでForce Unwrapping型の配列に値を追加できない]]></title>
    <link href="http://hamasyou.com/blog/2014/07/31/swift-array-force-unwrapping/"/>
    <updated>2014-07-31T11:28:11+09:00</updated>
    <id>http://hamasyou.com/blog/2014/07/31/swift-array-force-unwrapping/</id>
    <content type="html"><![CDATA[<p>この記事は Xcode6 beta4 を元に記述しています。</p>

<h3>Swift の配列は mutable か immutable</h3>

<p>Swift では配列を <strong class="text-danger">mutable/immutable</strong> の区別なく定義することができるようになりました。</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="swift"><span class="line"><span class="k">var</span> <span class="n">numbers</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
</span><span class="line"><span class="n">numbers</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
</span><span class="line"><span class="n">println</span><span class="p">(</span><span class="n">numbers</span><span class="p">)</span>    <span class="c1">// [0, 2, 3]</span>
</span></code></pre></td>
</tr></table></div></figure>


<p><code>let</code> で定義すると <strong class="text-danger">immutable</strong>、<code>var</code> で定義すると <strong class="text-danger">mutable</strong> になり、配列の代入はすべてコピーで行われるようになっています。</p>

<h3>Force UnWrapping 型!</h3>

<p>で、ハマったのが次のようなコードです。</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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="k">var</span> <span class="nl">numbers</span><span class="p">:</span> <span class="p">[</span><span class="n">Int</span><span class="p">]</span><span class="o">!</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
</span><span class="line"><span class="n">numbers</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>    <span class="c1">// error: '@lvalue $T7' is not identical to 'Int'</span>
</span></code></pre></td>
</tr></table></div></figure>


<p>Force Unwrapping 型とでも言うんでしょうかね？変数に必ず値が入ってることを保証するために <code>!</code> が付いた型です。
この型で定義した配列には、値の追加や変更ができなくなっています。。</p>

<p>これで何が困るかというと、<code>UIKit</code> 使って <code>UIViewController</code> のサブクラスにプロパティを定義する際に
初期化を <code>viewDidLoad</code> で行う時には、<code>!</code> をつけないと <code>initializer</code> が必要になってしまうので、プロパティの定義には <code>!</code> を付けていました。</p>

<p>そうすると、<em>mutable</em> で扱いたかったプロパティなのに、変更できないという問題にぶち当たったわけです。。どうすんだこれ。。。</p>

<h4>コンパイルエラーの例</h4>

<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>
</pre></td>
<td class="code"><pre><code class="swift"><span class="line"><span class="k">class</span> <span class="nl">MyViewController</span><span class="p">:</span> <span class="bp">UIViewController</span> <span class="p">{</span>
</span><span class="line">
</span><span class="line">  <span class="k">var</span> <span class="nl">numbers</span><span class="p">:</span> <span class="p">[</span><span class="n">Int</span><span class="p">]</span><span class="o">!</span>
</span><span class="line">
</span><span class="line">  <span class="kr">override</span> <span class="k">func</span> <span class="n">viewDidLoad</span><span class="p">()</span> <span class="p">{</span>
</span><span class="line">    <span class="nb">super</span><span class="p">.</span><span class="n">viewDidLoad</span><span class="p">()</span>
</span><span class="line">
</span><span class="line">    <span class="nb">self</span><span class="p">.</span><span class="n">numbers</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
</span><span class="line">  <span class="p">}</span>
</span><span class="line">
</span><span class="line">
</span><span class="line">  <span class="k">func</span> <span class="n">myFunc</span><span class="p">()</span> <span class="p">{</span>
</span><span class="line">    <span class="nb">self</span><span class="p">.</span><span class="n">numbers</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>     <span class="c1">// コンパイルエラー</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>


<h4>うまくいく例</h4>

<p>対応としては、一旦変数で受けて、変更後に元に戻すっていうので何とかなりますが、コンパイラの方でなんとかならんもんですかね。。</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="swift"><span class="line">  <span class="k">func</span> <span class="nf">myFunc</span><span class="p">()</span> <span class="p">{</span>
</span><span class="line">    <span class="k">var</span> <span class="nl">nums</span><span class="p">:</span> <span class="p">[</span><span class="n">Int</span><span class="p">]</span> <span class="o">=</span> <span class="nb">self</span><span class="p">.</span><span class="n">numbers</span>
</span><span class="line">    <span class="n">nums</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
</span><span class="line">    <span class="nb">self</span><span class="p">.</span><span class="n">numbers</span> <span class="o">=</span> <span class="n">nums</span>
</span><span class="line">  <span class="p">}</span>
</span></code></pre></td>
</tr></table></div></figure>



]]></content>
  </entry>
  
</feed>
