<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>ミツエーリンクス Apps Blog</title>
    <link rel="alternate" type="text/html" href="https://www.mitsue.co.jp/knowledge/blog/apps/" />
    <link rel="self" type="application/atom+xml" href="https://www.mitsue.co.jp/knowledge/blog/apps/atom.xml" />
    <id>tag:www.mitsue.co.jp,2015-07-10:/knowledge/blog/apps//13</id>
    <updated>2019-02-22T01:41:25Z</updated>
    
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro</generator>

<entry>
    <title>Fusetoolsを紹介します</title>
    <link rel="alternate" type="text/html" href="https://www.mitsue.co.jp/knowledge/blog/apps/201612/08_2036.html" />
    <id>tag:www.mitsue.co.jp,2016:/knowledge/blog/apps//13.407</id>

    <published>2016-12-08T11:36:24Z</published>
    <updated>2019-02-22T01:41:25Z</updated>

    <summary>近年のアプリ開発では、プロジェクトの早い段階から簡単なプロトタイプをつくり、実際...</summary>
    <author>
        <name>インタラクションアーキテクト　黄</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.mitsue.co.jp/knowledge/blog/apps/">
        <![CDATA[<p>近年のアプリ開発では、プロジェクトの早い段階から簡単なプロトタイプをつくり、実際に実機で操作しながらテストを行うことで、課題を早期発見・解決し、制作を効率化することが求められるようになってきています。Prott、Invision、Adobe XDなど、市場には様々なプロトタイピングツールが存在しています。</p>

<p>その中から今回は<a href="https://www.fusetools.com/">Fusetools</a>(以下、Fuse)というアプリケーションを紹介します。プロトタイピングはディレクターやデザイナーが行うことが多いので、GUIベースのものが主流ですが、Fuseはコードベースで作成する、どちらかというとエンジニア向けのツールです。</p>
]]>
        <![CDATA[<p>アプリを立ち上げると、下記の画像のようなダッシュボード画面が表示されます。</p>

<div class="lyt_image_3">
<img alt="Fuseのスタート画面" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161208_01.png" width="520" height="339">
</div>

<p>エディターとして、Sublime Textが推奨されており、公式のプラグインも提供されています。Fuseを立ち上げると、Sublime Textのセットアップも行ってくれます。</p>

<p>Fuseの最大の特徴は<strong>UX Markup</strong>という、独自の記述方法にあります。下記にそのサンプルを掲載しました。</p>

<pre><code>&lt;App&gt;
&lt;DockPanel Padding="10,10,10,10"&gt;
    &lt;ScrollView ClipToBounds="true"&gt;
        &lt;StackPanel&gt;
            &lt;Text FontSize="30"&gt;Hello, world!&lt;/Text&gt;
            &lt;Slider /&gt;
            &lt;Button Text="Button" /&gt;
            &lt;Switch Alignment="Left" /&gt;
        &lt;/StackPanel&gt;
    &lt;/ScrollView&gt;
&lt;/DockPanel&gt;
&lt;/App&gt;
</code></pre>

<p>ご覧の通り、XMLベースの記述方法となっています。</p>

<p>ダッシュボードの「Start app preview」をクリックするとプレビューを実行することができます。スマートフォンがUSB接続されていれば実機での確認も可能です。先ほどのコードを実行すると、下記の画像のように表示されます。</p>

<div class="lyt_image_3">
<img alt="サンプル実行画面" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161208_02.png" width="320" height="520">
</div>

<p>Fuseのすごいところはその実行スピードにあります。プレビューを実行している間は、コード側に変更があるとリアルタイムでプレビュー側に適用されます。実機で動きを確認しつつ、その場でフィードバックを適用することができるので、評価の回数を増やし、開発スピードを上げることができます。</p>

<h4>リアルタイムプレビューの様子</h4>

<div class="lyt_youtube"><div class="youtube"><iframe width="520" height="293" src="https://www.youtube-nocookie.com/embed/5nY5nS9QiM0?rel=0" frameborder="0" allowfullscreen></iframe></div></div>

<p>内部的には実行時に、UX Markupがネイティブコードにコンパイルされます。そのため、iOS,Android用にコードを書き分ける必要がなく、当然デバイスの表示や処理はネイティブで行われるので、実行後のアニメーションやインタラクションも滑らかで、とても快適です。</p>

<p>また、個人的にWeb開発者にオススメしたい理由として、コードの中にJavaScriptを記述できる点があげられます。ボタンがクリックされたら表示を変える、スライダーが動かされた分サイズを大きくする、といったような簡単なデータドリブン開発を行うこともできます。</p>

<p>公式サイトにたくさんの<a href="https://www.fusetools.com/examples">サンプル</a>が掲載されており、そのコードもダウンロードできるようになっています。まずはそれを見ながら、いかに簡単に作れるかを実感していただければと思います。</p>

<p>以上、手軽なプロトタイプツールとして、ご紹介しましたが、実はFuseのトップページには、<q>Build native apps on iOS and Android. Simpler. Faster.</q>と書かれています。つまり、Fuseはプロトタイプツールではなく、ネイティブアプリを作るツールとして提供されているのです。しかし、最新バージョンが0.30（12/06現在）ということもあり、未実装な部分もありますので、今回はプロトタイピングツールとして、ご紹介させていただきました。</p>

<p>とはいえ、現在安定している機能だけでも、十分使えるツールであると感じています。弊社の<a href="https://www.mitsue.co.jp/service/app_development/prototype_production.html">プロトタイプ制作サービス</a>にも活用し、スピード感のある制作をしていきたいと思います。</p>
]]>
    </content>
</entry>

<entry>
    <title>iOSアプリでFirebase Analyticsを試してみました</title>
    <link rel="alternate" type="text/html" href="https://www.mitsue.co.jp/knowledge/blog/apps/201610/31_1612.html" />
    <id>tag:www.mitsue.co.jp,2016:/knowledge/blog/apps//13.377</id>

    <published>2016-10-31T07:12:55Z</published>
    <updated>2016-10-31T10:17:59Z</updated>

    <summary>Googleが運営しているmBaaSサービス「Firebase」が高機能になり、...</summary>
    <author>
        <name>インタラクションアーキテクト　黄</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.mitsue.co.jp/knowledge/blog/apps/">
        <![CDATA[<p>Googleが運営しているmBaaSサービス「<a href="https://firebase.google.com/">Firebase</a>」が高機能になり、最近ますます注目されています。 <br />
このFirebaseが提供している機能の中で、簡単にモバイルアプリに組み込むことができ、利用状況の解析まで行えるのが「Firebase Analytics」です。
Firebase Analyticsではどのような値が取れて、どのような解析ができるのかをiOSアプリに組み込んで試してみました。</p>
]]>
        <![CDATA[<h4>Firebase Analyticsの組み込み方法</h4>

<h5>1. Firebaseプロジェクトを作成する</h5>

<p>Firebaseを利用するには、Firebaseアカウントが必要になります。</p>

<p>アカウント作成してログインし、Firebaseプロジェクトの作成を行います。 <br />
Firebaseプロジェクトの作成中に丁寧な説明が出るので迷わず作れます。 <br />
Firebaseプロジェクトの作成で設定する主な内容は下記です。</p>

<ul>
<li><strong>プロジェクト名(サンプルの場合は適当で問題ありません)</strong>  </li>
<li><strong>公開名(ユーザーがアプリでアカウントを作った際に送られるメールに表示される名称です)</strong>  </li>
<li><strong>バンドルID(iOSアプリで設定したものと同じものを指定)</strong>  </li>
<li><strong>App Store ID(ない場合は空白で問題ありません)</strong>  </li>
</ul>

<p>Firebaseプロジェクト設定が完了すると「GoogleService-Info.plist」ファイルがダウンロードできますので、適当な場所にダウンロードしておきます。</p>

<h5>2. iOSアプリでFirebaseの設定を行う</h5>

<p>Firebaseプロジェクト作成後はiOSアプリ側での作業になります。</p>

<ol start='1'>
<li><p>最初に<strong>Firebaseプロジェクトでダウンロードした「GoogleService-Info.plist」ファイルをiOSアプリに追加</strong>します。</p></li>
<li><p>次にiOSアプリに<strong>Firebaseライブラリを追加</strong>します。 <br />
ライブラリのインストールは「CocoaPods」を使用すると簡単です。</p></li>
<li><p>最後に<strong>Firebase用のコードを2行追加</strong>します。  </p></li>
</ol>

<p>上記3工程でiOSアプリ側の設定は完了です。 <br />
これだけでFirebase Analyticsでの計測が可能になります。</p>

<p>Firebaseプロジェクト設定からiOSアプリにライブラリを追加するまでの工程は<a href="https://firebase.google.com/docs/ios/setup" title="Firebase を iOS プロジェクトに追加する">公式ドキュメント</a>に詳しく書かれています。　　</p>

<h4>どのような値が計測できるのか？</h4>

<p>個人で作成したiOSアプリにFirebaseを組み込み、どのようなデータが取れるのか確認した結果が以下になります。(今回計測したアプリは利用ユーザー数が少ないので、計測して得られた情報の幅は大したものではありませんでした。)</p>

<p>Firebaseを組み込むだけで自動計測できる値は主に下記です。</p>

<h5>アクティブユーザー</h5>

<p>指定した期間のアクティブユーザー数です。日別、週別、月別で表示されます。今回計測したアプリでは、日別の違いは見られませんでした。</p>

<div class="lyt_image_3">
<img alt="アクティブユーザーの表" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161031_01.png" width="600" height="274">
</div>

<h5>収益情報(アプリ内課金の情報)</h5>

<p>ユーザーあたりの平均収益額（ARPU）と有料ユーザーあたりの平均収益額（ARPPU）が表示されます。今回計測したアプリには課金機能はないので、すべて0ドルで表示されています。</p>

<div class="lyt_image_3">
<img alt="収益情報のスクリーンショット" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161031_02.png" width="300" height="404">
</div>

<h5>first_openの情報</h5>

<p>アプリが初めて起動された回数とアプリを起動したユーザーのライフタイムバリューの値です。 <br />
インストール数ではないので、インストール数は「iTunes Connect」で確認します。 <br />
インストールしてもアプリを立ち上げない人もいるので、インストール数よりもこちらの数字の方が正確なアプリ利用者数がわかるかもしれません。</p>

<div class="lyt_image_3">
<img alt="first_openの情報のスクリーンショット" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161031_03.png" width="600" height="409">
</div>

<h5>維持率コホート</h5>

<p>アプリ利用の定着率が示されます。継続的にアプリを使用している人がどのくらいの割合でいるのかなどがわかります。
今回計測したアプリでは、インストール後2週目で利用しているユーザーの割合が10%なので、継続的に利用しているユーザーが少ないということがわかりました。</p>

<div class="lyt_image_3">
<img alt="維持率コホートのスクリーンショット" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161031_04.png" width="600" height="400">
</div>

<h5>ユーザーエンゲージメント</h5>

<p>エンゲージメントとはユーザーがアプリを利用した時間です。今回計測したアプリでは、アプリ利用時間が平均3分ととても短いので、アプリ内のコンテンツの量などに問題があるということがわかりました。</p>

<div class="lyt_image_3">
<img alt="ユーザーエンゲージメントのスクリーンショット" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161031_05.png" width="600" height="399">
</div>

<h5>アプリのバージョン</h5>

<p>上位3つの各アプリバージョンのユーザー数と、その他すべてのアプリバージョンとの合計ユーザー数が表示されます。新しいバージョンに移行した人がどのくらいいるのかがわかります。</p>

<div class="lyt_image_3">
<img alt="アプリのバージョンのスクリーンショット" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161031_06.png" width="600" height="408">
</div>

<h5>デバイス</h5>

<p>上位3つの各デバイスモデルのユーザーの割合と、その他すべてのデバイスを合計したユーザーの割合が表示されます。どのデバイスのどのバージョンで利用されているかがわかります。今回計測したアプリでは、OSバージョン10以上で利用している人が70%以上だということがわかりました。古いOSバージョンの対応をやめるタイミングなどに利用できそうです。</p>

<div class="lyt_image_3">
<img alt="デバイスのスクリーンショット" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161031_07.png" width="600" height="409">
</div>

<h5>場所</h5>

<p>各地域のセッション数の割合が表示されます。今回計測したアプリでは、イギリスで利用している方が最も多いということがわかりました。全く利用されていない地域なども確認できますので、アプリをローカライズする際などは参考にできそうです。</p>

<div class="lyt_image_3">
<img alt="利用場所のスクリーンショット" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161031_08.png" width="600" height="430">
</div>  

<p>下記項目はiOSの広告識別子ID(IDFA)から取得しますので、iOSアプリに「GoogleIDFASupport」ライブラリを追加しないと取得できません。</p>

<h5>ユーザー属性</h5>

<p>年齢層別のユーザーの性別の割合が表示されます。今回計測したアプリでは、男性の利用者が多いということがわかりました。</p>

<div class="lyt_image_3">
<img alt="利用場所のスクリーンショット" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161031_09.png" width="600" height="360">
</div>

<h5>インタレスト</h5>

<p>ユーザーが興味のあるカテゴリが表示されます。今後アプリを改良する際などは参考になりそうです。</p>

<div class="lyt_image_3">
<img alt="利用場所のスクリーンショット" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161031_10.png" width="600" height="174">
</div>

<h4>計測できるイベントについて</h4>

<p>Firebaseを組み込むと自動で計測されるイベントは<a href="https://support.google.com/firebase/answer/6317485" title="自動的に収集されるイベント">こちら</a>で確認できます。  </p>

<p>その他のイベントについてはFirebaseライブラリ内の「FIREventNames.h」で確認できます。
コード内のコメントは英語ですが、どのようなシーンで利用すべきかなどが書かれていますので参考にして設定してください。  </p>

<p>下記画像は「select_content」イベントで得た情報です。 <br />
今回はアプリ内の画面が切り替わるタイミングでイベントを取得しました。 <br />
パラメータ「kFIRParameterContentType」には画面名を指定しています。 <br />
どの画面がよく見られているのかがわかります。</p>

<div class="lyt_image_3">
<img alt="select_contentイベントのスクリーンショット" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161031_11.png" width="600" height="459">
</div>

<h4>まとめ</h4>

<p>iTunes ConnectにはAppアナリティクスというアプリ利用解析サービスがあります。 <br />
単純にアクティブ数や利用デバイス情報などが知りたい場合はAppアナリティクスで十分だと思います。  </p>

<p>しかし、より詳しくアプリ独自の利用解析が行いたい場合や、Appleが出しているアプリ内課金の情報が正しいのか2重チェックする際などには
Firebase Analyticsは使えます。</p>

<p>少ない手間で豊富な情報が得られますので、Firebase Analyticsを組み込んでおいて損はないと思いました。</p>
]]>
    </content>
</entry>

<entry>
    <title>Firebase Test Labを試してみました</title>
    <link rel="alternate" type="text/html" href="https://www.mitsue.co.jp/knowledge/blog/apps/201610/25_1045.html" />
    <id>tag:www.mitsue.co.jp,2016:/knowledge/blog/apps//13.375</id>

    <published>2016-10-25T01:45:04Z</published>
    <updated>2016-10-25T10:03:34Z</updated>

    <summary>ご存知の通りAndroid端末の種類は毎年増えており、そのサイズや解像度は多岐に...</summary>
    <author>
        <name>インタラクションアーキテクト　黄</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.mitsue.co.jp/knowledge/blog/apps/">
        <![CDATA[<p>ご存知の通りAndroid端末の種類は毎年増えており、そのサイズや解像度は多岐に渡ります。端末の種類が増えると大変になるのがAndroid開発時のテストです。サポートする端末を決めたところで、毎回手元にない端末を購入していたらキリがありませんし、たくさんの端末でアプリを手動で確認する、というのは大変な手間となってしまいます。そこで有用なのが「Firebase Test Lab」(以下Test Lab)です。</p>
]]>
        <![CDATA[<p>Test LabはFirebaseのサービスの1つです。Googleが用意している主要な端末をバージョンごとに試すことができ、その結果を様々な形で提供してくれます。実際の端末でアプリを実行しているので、端末を購入しなくとも実機テストが可能になります。主に、用意されている端末は<a href="https://firebase.google.com/docs/test-lab/overview#header">こちら</a>のほかに、Sony Xperia Z3, Xperia Z5 Compactが追加されています。</p>

<p>Firebaseの基本的な機能は無料で使用することができますが、Test Labを使うにはプロジェクトのプランを従量課金制のBlazeプランにアップグレードする必要があります。料金体系については、<a href="https://firebase.google.com/pricing/">Firebaseの価格設定のページ</a>をご覧ください。</p>

<p>Test Labで実行できるテストには、Roboテストと、インストゥルメンテーションテストの２種類があります。</p>

<p>Roboテストはapkファイルをアップロードすると、アプリのUIの構造を分析し、一通りの操作を自動でシミュレートしてくれるテストです。テストコードが不要なので、大変お手軽です。ボタンをクリックして次の画面に進むといったような単純なアプリには向いていますが、入力欄にテキストを入力するような複雑な操作には向いていません。</p>

<p>インストゥルメンテーションテストは、どのようなテストを行うかを自分で実装するテストです。Test Labでは下記３種類のテストフレームワークに対応しています。</p>

<ul>
<li>Espresso</li>
<li>UI Automator 2.0</li>
<li>Robotium</li>
</ul>

<p>今回はAndroidの公式IDEでもあるAndroid Studioと相性がいいEspressoを使いながら、簡単なテストコードの作成から、インストゥルメンテーションテストを実行するところまでをご紹介します。 アプリができ上がっていて、Firebase上にアプリのプロジェクトが作成されている前提で進めたいと思います。プロジェクトをまだ作成していない場合は<a href="https://firebase.google.com/docs/android/setup">Firebaseのセットアップガイド</a>を参考にしてください。</p>

<p>簡単ですが、下記のように入力したテキストを次のアクティビティで表示するアプリをテストします。</p>

<div class="lyt_image_3">
<img src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161025_01.png" alt="テキスト欄に入力された名前を画面に表示するテスト用アプリ" width="600" height="530">
</div>

<p>Espressoのテストコードを生成します。Android Studioを使えば、Espressoを知らなくてもテストコードを書くことができます。 ツールバー内にある、「Run」項目から、「Record Espresso Test」を選択します。実行する端末を選ぶと、エミュレーターと下記のような画面が立ち上がります。</p>

<div class="lyt_image_3">
<img src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161025_02.png" alt="Espressoで実施するテスト内容をマクロで記録できる画面。「Add Assertion」ボタン押下でマクロを追加したり、「Complete Recording」ボタン押下で記録を完了することができる" width="474" height="638">
</div>

<p>エミュレーター側でテキストを入力するなどのアクションを行うと、そのアクションが自動的に記録されていきます。動作が非常に重たいので、あせらずじっくり操作していきましょう。最後に、評価する部分を設定するため、「Add Assetion」をクリックします。</p>

<div class="lyt_image_3">
<img src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161025_03.png" alt="記録したマクロ内容をエミュレーターで自動に実施している画面" width="821" height="638">
</div>

<p>ここで、入力されたテキストを表示している部分をクリックすると、自動で評価を作成してくれます。</p>

<p>一通りのテストが終わったら、「Complete Recording」をクリックし、テストの名前を設定して保存します。作成したテストコードはプロジェクトフォルダ内のandroidTestフォルダに保存されます。以上でEspressoのテストコードの作成は終了です。</p>

<p>続いて、作成したテストをTest Labで実行します。Tools内のFirebaseからTest Labの項目を開くと、手順が記載されているので、それに沿って進めます。アプリとFirebaseのプロジェクトを連携させ、プロジェクトのプランがまだBlazeプラン以外の場合はプランを変更しましょう。</p>

<p>ツールバーの「Run」から「Edit Configurations」を開き、テストの設定をします。左上の「＋」アイコンをクリックすると、細かい設定ができます。「Matrix configuration」をクリックするとテストしたい端末を決めることができます。</p>

<div class="lyt_image_3">
<img src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161025_04.png" alt="テストを実施する環境（端末、OSバージョン、地域、向き）が選択できる画面" width="841" height="513">
</div>

<p>端末（Googleにホスティングされている端末のみ選択可）とAPIレベル（4.4以降）と言語と端末の向きを組み合わせて、テストする環境を決定します。</p>

<p>このとき、端末とAPIレベルの組み合わせに互換性がないものも選択できてしまいます。選択したAPIレベルは選択した端末すべてに適用されてしまうので、APIレベル21の設定ファイル、23の設定ファイル、といったように、APIレベルを基準に設定ファイルを作成するとよいでしょう。互換性がない組み合わせはテスト時にはじかれますが、その分もしっかり課金されます（約2秒程）ので注意が必要です。</p>

<p>実行結果をFirebase Consoleで見てみると、下記のように結果が表示されます。</p>

<div class="lyt_image_3">
<img src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161025_05.png" alt="テスト実施時に生成された端末のログが確認できる画面" width="933" height="614">
</div>

<p>結果の内容として見ることができるのは、実行したテスト、ログ、動画です。動画は下記のように、テストのキャプチャを見ることができます。</p>

<div class="lyt_image_3">
<img src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20161025_06.gif" alt="テスト実施時に自動に生成される動画キャプチャー。これを使ってエラー発生時にどの状況でエラーが発生したか確認できる。" width="436" height="773">
</div>

<p>以上でインストゥルメンテーションテストは終了です。テストの実行はコマンドラインからの実行も可能ですので、もちろん自動化もできます。テストはどうしても開発の終了段階で行ってしまいがちですが、開発初期段階からプロセスに組み込み、品質の高いアプリ開発を目指しましょう。</p>

<p>参考:<a href="https://googledevjp.blogspot.jp/2016/07/firebase-test-lab-for-android.html">Firebase Test Lab for Android のご紹介</a></p>
]]>
    </content>
</entry>

<entry>
    <title>Yahoo!ローカルサーチAPIを利用してPokémon GOのポケストップっぽい場所にピンを刺す</title>
    <link rel="alternate" type="text/html" href="https://www.mitsue.co.jp/knowledge/blog/apps/201607/29_1909.html" />
    <id>tag:www.mitsue.co.jp,2016:/knowledge/blog/apps//13.335</id>

    <published>2016-07-29T10:09:25Z</published>
    <updated>2016-09-29T05:36:54Z</updated>

    <summary>位置情報を使用したスマホゲーム「Pokémon GO」が世界中で大流行しています...</summary>
    <author>
        <name>インタラクションアーキテクト　黄</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.mitsue.co.jp/knowledge/blog/apps/">
        <![CDATA[<p>位置情報を使用したスマホゲーム「Pokémon GO」が世界中で大流行しています。</p>

<p>Pokémon GOの特徴にはモンスターを捕まえるほかに、ポケストップと呼ばれるアイテムが補給できるポイントに実際に足を運び、アイテムを取得するというものがあります。</p>

<p>Pokémon GOのように位置情報と連動したゲームやアプリを作成する場合、実際の地図上に存在する「ポケストップ的」な場所情報が必要不可欠になると思いますが、今現在、Pokémon GOで表示されるポケストップの情報を一般の開発者が利用することはできませんし、自前でポケストップのような場所情報データを作ることは個人では難しいです。</p>

<p>しかし、「Yahoo!ローカルサーチAPI」を使えば、ポケストップになっていそうな場所(公園、お寺、神社、駅、マクドナルドなどのチェーン店)を位置情報から取得できます。</p>
]]>
        <![CDATA[<h4>Yahoo!ローカルサーチAPIとは</h4>

<p>Yahoo! JAPANが提供しているAPIで、位置情報を引数にして、その周辺にある施設やお店の情報を返してくれるものです。</p>

<p>Yahoo!ローカルサーチAPIの主な機能は以下です。</p>

<ul>
<li>地域・拠点情報の名称および業種をキーワードや緯度経度から検索が出来る</li>
<li>欲しい施設のコードを指定して検索が出来る</li>
<li>中心位置を指定して円範囲で絞り込む</li>
</ul>

<p>Yahoo!ローカルサーチAPIを使用するためにはアプリケーションIDを取得する必要があります。
24時間中1アプリケーションIDにつき50000件のリクエストが上限となっています。</p>

<p>詳しくは<a href="http://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/localsearch.html" title="Yahoo!ローカルサーチAPI">Yahoo!ローカルサーチAPI</a>を確認してください。</p>

<h4>サンプルコード</h4>

<h5>マップと位置情報を取得するための準備</h5>

<p>iOSアプリにマップを表示させるには「MKMapView」を使用します。
位置情報を取得するには「CLLocationManager」を使用します。</p>

<pre><code>// MapViewの生成
self.mapView = MKMapView()

// LocationManagerの生成
self.lm = CLLocationManager()
// 取得精度の設定
self.lm.desiredAccuracy = kCLLocationAccuracyBest
// 位置情報取得間隔(m)ここで指定した間隔移動したら「locationManager」の位置情報更新処理が呼ばれます
self.lm.distanceFilter = 40
// 精度.
self.lm.desiredAccuracy = kCLLocationAccuracyHundredMeters
// Delegateの設定.
self.lm.delegate = self

// セキュリティ認証のステータスを取得
let status = CLLocationManager.authorizationStatus()
// 認証が得られていない場合は、認証ダイアログを表示
if(status == CLAuthorizationStatus.NotDetermined) {
    // 承認が得られていない場合は、認証ダイアログを表示
    self.lm.requestWhenInUseAuthorization();
}

// 位置情報の更新を開始.
self.lm.startUpdatingLocation()

// 位置情報のトラッキングをする
self.mapView.setUserTrackingMode(MKUserTrackingMode.Follow, animated: true)
self.mapView.delegate = self</code></pre>

<h5>Yahoo!ローカルサーチAPIで現在地周辺の施設情報取得</h5>

<p>事前にYahoo!のサイトでアプリケーションIDを取得してください。
SwiftでJSONを扱いやすくするために<a href="https://github.com/SwiftyJSON/SwiftyJSON" title="SwiftyJSON">SwiftyJSON</a>ライブラリを使っています。
APIを叩きやすくするために<a href="https://github.com/Alamofire/Alamofire" title="Alamofire">Alamofire</a>ライブラリを使っています。</p>

<pre><code>func setMapPin() {
    // 現在地から緯度経度取得
    let latitude = String(format: "%.06f", self.nowLocation.coordinate.latitude)
    let longitude = String(format: "%.06f", self.nowLocation.coordinate.longitude)
    let parameters = [
        "appid": "Yahooで取得したアプリケーションID",
        "lat": latitude,     // 緯度
        "lon": longitude,    // 経度
        "dist": 2,           // 現在位置を中心とした検索距離（km）
        "sort": "dist",      // 直線距離順にソート
        "results": 100,      // 取得件数（最大100）
        "output": "json",    // JSON形式で返してもらいます
        "gc": "0424,0305007",// 取得する業種コード(ここでは「神社・寺」「公園」を指定しています)
        "group": "gid"       // 名寄せされた同一店舗をまとめて表示
    ]

    // API呼び出し
    Alamofire.request(.GET,
        "http://search.olp.yahooapis.jp/OpenLocalPlatform/V1/localSearch?",
        parameters: parameters as? [String : AnyObject])
        .validate(contentType: ["application/json"])
        .responseJSON
        { request, response, result in

            switch result {
            // 成功の場合
            case .Success(let data):
                if JSON(data)["Feature"] != nil {
                    for count in 0 ..< JSON(data)["Feature"].count {
                        print(String(JSON(data)["Feature"][count]["Name"]))
                        print(String(JSON(data)["Feature"][count]["Geometry"]["Coordinates"]))

                        let coord = String(JSON(data)["Feature"][count]["Geometry"]["Coordinates"]).componentsSeparatedByString(",")
                        let mapPoint : CLLocationCoordinate2D = CLLocationCoordinate2DMake(
                            double_t(coord[1])!,
                            double_t(coord[0])!
                        )
                        let annotation = MKPointAnnotation()
                        annotation.coordinate = mapPoint
                        annotation.title = String(JSON(data)["Feature"][count]["Name"])
                        // ピンを地図上に追加
                        self.mapView.addAnnotation(annotation)
                    }
                }
                else {
                    // エラー
                }
            // 失敗の場合
            case .Failure(_, _):
                // エラー
            }
    }
}</code></pre>

<h5>Yahoo!ローカルサーチAPIの結果をマップ上に示す</h5>

<pre><code>// アノテーション表示の管理
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
    if annotation.isKindOfClass(MKUserLocation) {
        // 現在地を示すアノテーションの場合はデフォルトのまま
        return nil
    }
    else {
        // 再利用可能オブジェクト取得
        var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier("pin") as! MKPinAnnotationView!

        // 再利用可能オブジェクト有無判定
        if annotationView == nil {
            annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "pin")
            annotationView.animatesDrop = true
            annotationView.canShowCallout = true
            annotationView.draggable = true

            // ピンの色変える
            annotationView.pinTintColor = UIColor.redColor()
            // ピンのボタン設定
            let pinButton = UIButton(type: UIButtonType.Custom) as UIButton
            pinButton.frame.size.width = 50
            pinButton.frame.size.height = 51
            pinButton.backgroundColor = UIColor.greenColor()
            pinButton.setImage(UIImage(named: "money"), forState: .Normal)
            annotationView.leftCalloutAccessoryView = pinButton
        }
        return annotationView
    }
}</code></pre>

<h5>実行結果</h5>

<p>Yahoo!ローカルサーチAPIの結果(施設名と緯度経度)</p>

<div class="lyt_image_3"><img alt="結果コンソール" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160729_01.png" width="1134" height="300"><span class="caption">結果コンソール</span></div>

<p>西新宿駅半径１キロの「神社・お寺」「公園」の位置を表示</p>

<div class="lyt_image_3"><img alt="結果画面1" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160729_02.png" width="636" height="992"><span class="caption">結果画面1</span></div>

<div class="lyt_image_3"><img alt="結果画面2" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160729_03.png" width="632" height="900"><span class="caption">結果画面2</span></div>

<h4>まとめ</h4>

<p>Yahoo!ローカルサーチAPIのアプリケーションIDをアプリ内のコードに記述するのには抵抗があると思いますので、実際に使う際にはYahoo!ローカルサーチAPIの呼び出しはサーバ側で行った方が良いと思います。</p>

<p>位置情報が更新されるたびにマップに刺したピンとの距離を計算して、ある程度近づいたらアイテムが取得できるというような機能をつくればポケストップと同じようなことができます。Yahoo!ローカルサーチAPIを利用すれば、Pokémon GOのように実際の施設と位置情報を連動したゲームなどが作れそうですね。</p>
]]>
    </content>
</entry>

<entry>
    <title>WKWebViewを使ってNativeとWebページで情報をやり取りする方法</title>
    <link rel="alternate" type="text/html" href="https://www.mitsue.co.jp/knowledge/blog/apps/201605/30_1721.html" />
    <id>tag:www.mitsue.co.jp,2016:/knowledge/blog/apps//13.308</id>

    <published>2016-05-30T08:21:52Z</published>
    <updated>2019-02-12T03:12:22Z</updated>

    <summary>iOS8から使えるようになったWKWebViewはUIWebViewよりもJav...</summary>
    <author>
        <name>インタラクションアーキテクト　黄</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.mitsue.co.jp/knowledge/blog/apps/">
        <![CDATA[<p>iOS8から使えるようになったWKWebViewはUIWebViewよりもJavaScriptとの連携が強化されています。
WKWebViewを使うことでアプリ側独自のJavaScriptを既存Webページに読み込ませ、実行させるということが簡単にできるようになりました。
(ブラウザでユーザースクリプトを実行させるというようなことがNativeでもできる)
WKWebViewを使ったユーザースクリプト実行方法のサンプルを紹介します。</p>
]]>
        <![CDATA[<h2>ATS（App Transport Security）を無効にするInfo.plistの設定</h2>

<p>iOS9からhttpでリクエストを送るとhttpsに置き換わってしまいます。
テストをするためにinfo.plistに下記を追加してhttpsに置き換わるのを無効にします。</p>

<pre><code>&lt;key>NSAppTransportSecurity&lt;/key>
&lt;dict>
    &lt;key>NSAllowsArbitraryLoads&lt;/key>
    &lt;true/>
&lt;/dict></code></pre>

<h2>Swiftコード</h2>

<p>WKWebViewを使うために「WebKit Framework」インポートします。
Swift上でJavaScriptコードを文字列として記述するのは大変なので別ファイルで用意(test.js)しました。
ユーザースクリプト（WKUserScript）を作成する際のinjectionTimeでJavaScriptの注入タイミングを指定できます。
JavaScriptで実行した結果を受け取りたい場合はWKUserContentControllerのaddScriptMessageHandlerで設定します。
WKWebViewのデリゲートWKScriptMessageHandlerのuserContentControllerメソッドを追加します。
このuserContentControllerメソッドでJavaScriptからのメッセージが受け取れます。
下記のコードでは受け取ったメッセージをコンソールに出しています。</p>

<pre><code>import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler {

    var webView : WKWebView?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        var jsSource = ""
        // JavaScriptコードはtest.jsという名前で別ファイルに用意します
        let path = NSBundle.mainBundle().pathForResource("test", ofType: "js")!
        if let data = NSData(contentsOfFile: path){
            jsSource = String(NSString(data: data, encoding: NSUTF8StringEncoding)!)
        }
        // WKUserScriptを作成、injectionTimeにJavaScriptを実行するタイミングを指定します
        let userScript1 = WKUserScript(source: jsSource, injectionTime: WKUserScriptInjectionTime.AtDocumentEnd, forMainFrameOnly: true)

        // JavaScript側の実行結果などを受け取りたい場合はコールバックを設定します
        let controller = WKUserContentController()
        controller.addUserScript(userScript1)
        controller.addScriptMessageHandler(self, name: "callbackHandler")

        let configuration = WKWebViewConfiguration()
        configuration.userContentController = controller

        self.webView = WKWebView(frame: view.bounds, configuration: configuration)

        self.view = self.webView
        let urlString = "https://www.mitsue.co.jp/"
        let encodedUrlString = urlString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
        let url = NSURL(string: encodedUrlString!)
        let request = NSURLRequest(URL: url!)
        self.webView!.loadRequest(request)
    }

    func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
        // addScriptMessageHandlerで指定したコールバック名を判断して処理を分岐させることができます
        if(message.name == "callbackHandler") {
            print(message.body)
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}</code></pre>

<h2>JavaScriptコード</h2>

<p>jQueryを使っていないサイトの場合に備えてjQueryを読み込ませる処理を行っています。
このスクリプトでは「www.mitsue.co.jp」内のお知らせとキャンペーン情報を取得し、Native側に送っています。
JavaScriptで「webkit.messageHandlers.Native側で設定したコールバック名.postMessage("Native側に送りたい情報");」とするだけでNative側にメッセージを送ることができます。</p>

<pre><code>(function (callback) {
    // jQueryを使っていないサイトの場合用にjQueryを読み込みます
    var script = document.createElement("script");
    script.setAttribute("src", "//code.jquery.com/jquery-2.0.0.min.js");
    script.addEventListener('load', function() {
        var script = document.createElement("script");
        script.textContent = "(" + callback.toString() + ")(jQuery.noConflict(true));";
        document.body.appendChild(script);
    }, false);
    document.body.appendChild(script);
})(function ($) {
    $('div.news').each(function() {
        // www.mitsue.co.jp内のお知らせとキャンペーンの情報を取得してNative側に送ります
        // webkit.messageHandlers.Native側で設定したコールバック名.postMessage("Native側に送りたい情報");
        webkit.messageHandlers.callbackHandler.postMessage($(this).find('a').html());
    });
});</code></pre>

<h2>実行結果</h2>

<p>eachの中で連続して送ってもNative側では正常に受け取ることができます。</p>

<div class="lyt_image_3"><img alt="WKWebView上のJavaScriptから送信したデータをNative側で読み取るコードを実行した画面" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160530_01.png" width="1182" height="230"></div>

<p>この技術を使うことで既存Webページ上の必要な情報のみをNative側に取り込み、アプリ独自の見せ方をさせるというようなことができるようになります。</p>
]]>
    </content>
</entry>

<entry>
    <title>A-Frameを使ってVR空間を作る</title>
    <link rel="alternate" type="text/html" href="https://www.mitsue.co.jp/knowledge/blog/apps/201605/12_1345.html" />
    <id>tag:www.mitsue.co.jp,2016:/knowledge/blog/apps//13.301</id>

    <published>2016-05-12T04:45:21Z</published>
    <updated>2019-02-12T03:12:22Z</updated>

    <summary> A-Frameとは？ A-FrameとはWebブラウザ上で簡単にVR空間を作れ...</summary>
    <author>
        <name>インタラクションアーキテクト　黄</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.mitsue.co.jp/knowledge/blog/apps/">
        <![CDATA[<div class="lyt_image_3"><img alt="A-Frameのトップ画面" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160512_01.png" width="520" height="390"></div>

<h2>A-Frameとは？</h2>

<p><a href="https://aframe.io/">A-Frame</a>とはWebブラウザ上で簡単にVR空間を作れてしまうフレームワークです。開発しているのはFirefoxでもおなじみ、Mozilla内のVRチーム<a href="http://mozvr.com/">「MozVR」</a>です。WebVRをまだ体験したことがない方は、このMozVRのサイトを（最新のブラウザで）訪れてみてください。アニメーションしている背景をマウスでドラッグすると周りを見渡せるのが分かると思います。</p>

<p>Oculus Riftのような、VRヘッドセットをお持ちの方は、開発版のブラウザ（<a href="https://nightly.mozilla.org/">Firefox Nightly</a>か、<a href="http://beadored.com/chromium-download-update/">Chromium</a>）と組み合わせるとWebVRを体験することができます。接続するだけで、トラッキングまでしてくれる優れものです。</p>

<p>VRヘッドセットなどをお持ちでない方にはWebGLのコンテンツとして提供しており、スマートフォンで見ることもできます。こちらももちろん、ページを読み込むだけでジャイロセンサーとの連携まで行ってくれます。つまり、<a href="https://www.google.com/get/cardboard/">Google Cardboard</a>と組み合わせればVRを体験することができます。</p>

<p>また、MITライセンスで<a href="https://github.com/aframevr">Github</a>にてまるまる公開されているので、どのように動いているのかもコードから解析することができ、欲しい機能があれば、プルリクエストをおくることも可能です。</p>
]]>
        <![CDATA[<h2>インストール</h2>

<p>それでは、環境を作ってみましょう。</p>

<ul class="list_u_1">
<li>node.js</li>
<li>npm</li>
</ul>

<p>がインストールされている前提で進めたいと思います。</p>

<p>今回は<a href="https://github.com/aframevr/aframe-boilerplate">こちら</a>からBolierplateをダウンロードしました。</p>

<ul class="list_notice_1">
<li><span class="marker">※</span>ローカルに環境を作るのが嫌だなという方は、jsファイルを直接ダウンロードすることもできます。（<a href="https://aframe.io/releases/latest/aframe.min.js">aframe.min.js</a>）</li>
</ul>

<p>リンクからzipをダウンロード、展開し、npmを実行します。</p>

<pre><code>$ npm installl</code></pre>

<p>インストールが終わったら、そのまま実行します。</p>

<pre><code>$ npm start</code></pre>

<p>するとブラウザが勝手に立ち上がります。VR環境が整っていない場合はWebGLコンテンツとして下記のように表示されているはずです。</p>

<div class="lyt_image_3"><img alt="VR環境が整っていない場合の表示画面" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160512_02.png" width="520" height="390"></div>

<p>右下のカードボードアイコンにカーソルを合わせると、VR環境が整っているかどうかを確認することができます。</p>

<h2>コードを見てみる</h2>

<p>HTMLを見てみましょう。デフォルトでシーンが1つ、3Dオブジェクトが４つ、最後に空間の色を決めるオブジェクトが配置されています。</p>

<ul class="list_u_1">
<li>a-scene 全体を囲むシーン</li>
<li>a-sphere 球体</li>
<li>a-cube 四角ブロック</li>
<li>a-cylinder 円柱</li>
<li>a-plane 床</li>
<li>a-sky 空（空間の内側）</li>
</ul>

<p>どの要素がどのオブジェクトを示しているか、なんとなく想像がつきますね。各要素に指定されている属性を見てみましょう。</p>

<dl class="list_d_1">
<dt>position</dt>
<dd>position属性はスペース区切りで、<strong>[x y z]</strong>を指定します。
<div class="lyt_image_3"><img alt="XYZ軸を正しく表示した画面" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160512_03.png" width="520" height="342"></div>
緑の線がx軸で右が正、青い線がy軸で上が正、赤い線がz軸で手前が正となっています。単位は「メートル」です。青いキューブがちょうど1m x 1mのサイズとなります。</dd>
<dt>radius</dt>
<dd>sphereやcylinderなど、オブジェクトに円形が含まれているものにはradius属性、つまり半径を指定できます。</dd>
<dt>color</dt>
<dd>色を指定します。指定の仕方は16進数ですが、material.redのようなプロパティを使うこともできます。</dd>
<dt>width, height, depth</dt>
<dd>幅、高さ、奥行きです。</dd>
<dt>rotation</dt>
<dd>こちらもスペース区切りで<strong>各軸を基準にどのくらい回すか</strong>を定めています。角度の単位は「度」です。</dd>
<dt>a-sky</dt>
<dd>a-skyはオブジェクトが囲まれている空間の内側の色を定めています。VR空間と言っても、無限に続く空間というわけではなく、この空間も１つのオブジェクトです。イメージ画像を作りました。
<div class="lyt_image_3"><img alt="a-skyを表示した画面" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160512_04.png" width="520" height="472"></div>
この外側をかこっている空間の内側の灰色を指定しているのが下記のコードです。
<pre><code>&lt;a-sky color="#ECECEC">&lt;/a-sky></code></pre>
</dd>
</dl>

<p>A-Frameを使えば、誰でも簡単にWebVRコンテンツを作ることができます。さらに作られたコンテンツはWeb上で誰でも簡単に体験することができます。VRの波に乗り遅れないよう、体験しておきましょう。</p>
]]>
    </content>
</entry>

<entry>
    <title>CES 2016参加レポート</title>
    <link rel="alternate" type="text/html" href="https://www.mitsue.co.jp/knowledge/blog/apps/201601/13_2040.html" />
    <id>tag:www.mitsue.co.jp,2016:/knowledge/blog/apps//13.228</id>

    <published>2016-01-13T11:40:01Z</published>
    <updated>2019-02-12T03:12:22Z</updated>

    <summary>1月6日から米国のラスベガスで開催された世界最大級の家電製品を中心とした展示会「...</summary>
    <author>
        <name>インタラクションアーキテクト 大室</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.mitsue.co.jp/knowledge/blog/apps/">
        <![CDATA[<p>1月6日から米国のラスベガスで開催された世界最大級の家電製品を中心とした展示会「<a href="https://www.cesweb.org/">CES 2016</a>」に参加して来ました。</p>

<div class="lyt_image_3"><img alt="" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160113_01.png" width="300" height="398"></div>

<p>このイベントで、ハイテク各社は現在開発している最も意欲的な製品を披露します。この記事では、CES2016の会場の雰囲気をご紹介します。</p>]]>
        <![CDATA[<h2>電子家電</h2>

<p>去年に続けて今年もディスプレーやPC、冷蔵庫、洗濯機などの電子製品は新しい機能を持って発表されました。 8Kの画質を持っているディスプレーはもちろん、洗濯物を自動で畳んでくれるデバイスやスマホで温度や加熱時間調整ができる電子レンジもありました。</p>

<div class="lyt_image_3"><img alt="" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160113_02.png" width="400" height="265"></div>

<h2>VR（バーチャルリアリティ）</h2>

<p>今回のCESでは、特にVR関連製品やサービス、ソリューションが多くみられました。 VRデバイス市場をリードしているOculusは正式版の<a href="https://www.oculus.com/en-us/rift/">Oculus Rift</a>を、Sonyは<a href="http://www.jp.playstation.com/psvr/">PlayStation VR</a>を、SamsungとHTCも<a href="https://www.oculus.com/en-us/gear-vr/">Gear VR</a>と<a href="http://www.htcvive.com/us/">HTC Vive</a>をそれぞれ発表しました。 会場でOculus RiftとGear VRを体験しましたが、優れた没入感をもとにリアルで動いているような体験ができました。これからのVR市場の成長元はコンテンツになるのではないかと予測します。</p>

<div class="lyt_image_3"><img alt="" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160113_03.png" width="400" height="342"></div>

<h2>スマートカー</h2>

<p>去年までのスマートカーが従来の自動車にスマホと連動したり多様な情報を提供するインフォテインメントシステムがメインだったとしたら、今年のトレンドは電気自動車と自律走行と言えるでしょう。<a href="http://www.faradayfuture.com/">Faraday Future</a>社のように新しい電気自動車会社はもちろん、BMWやメルセデス・ベンツ、フォード・モーターのような昔からの自動車会社も自律走行機能を持っている電気自動車を発表しました。自律走行は、もう、SF映画だけの話ではないと思いました。</p>

<div class="lyt_image_3"><img alt="" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160113_04.png" width="400" height="653"><span class="caption">展示されたコンセプトカー。上からFaraday Future、フォード・モーター、三菱電気、トヨタ</span></div>

<h2>ドローン</h2>

<p>自律走行の電気自動車に加えて、人が乗れる自律走行するドローンも紹介されました。EHANG社で発表したこのドローンは体重が100kgの人も乗せられるらしく、操作パネルから目的地を設定すると自動で移動するシステムになっていました。</p>

<div class="lyt_image_3"><img alt="" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160113_05.png" width="400" height="266"></div>

<h2>何でもIoT</h2>

<p>今回のCESでたくさんの出展製品を見て感じた共通点の一つは「何でもIoT」ということでした。 すなわち、今までITや家電と全く関係のなかったビジネスが、IoTを通して情報を収集・加工し、コンテンツを通してユーザーに適切な情報をフィードバックすることで完全に新しいタイプのビジネスになっていました。 ともに、我々が提供しているサービスも合わせて進化が必要で、価値のあるUX&UIを提供するコンテンツに関する研究も必要だと感じました。</p>

<div class="lyt_image_3"><img alt="" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160113_06.png" width="400" height="525"></div>]]>
    </content>
</entry>

<entry>
    <title>iPadのマルチタスク機能と、AdaptiveなUIの重要性</title>
    <link rel="alternate" type="text/html" href="https://www.mitsue.co.jp/knowledge/blog/apps/201601/07_1130.html" />
    <id>tag:www.mitsue.co.jp,2016:/knowledge/blog/apps//13.227</id>

    <published>2016-01-07T02:30:34Z</published>
    <updated>2019-02-12T03:12:58Z</updated>

    <summary>iOS9と一部のiPadの組み合わせで使えるようになった、マルチタスク機能につい...</summary>
    <author>
        <name>インタラクションアーキテクト 大室</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.mitsue.co.jp/knowledge/blog/apps/">
        <![CDATA[<p>iOS9と一部のiPadの組み合わせで使えるようになった、マルチタスク機能について紹介します。<br />
マルチタスク機能を使うことで、アプリを切り替えることなく、2つのアプリを画面上に表示・操作することが可能になります。<br />
</p>]]>
        <![CDATA[<h2>Slide Over</h2>

<p>Slide Overは、いま使っているアプリの上に一時的に覆い被さる形で、もう1つのアプリを使うことができる機能です。<br />
画面の左端からスワイプすることで、もう1つのアプリが出てきます。</p>

<p>左側にデモアプリ、右側にSafariで弊社のWebサイトを表示してみました。<br />
Slide Overはモーダルウィンドウのような形になるため、デモアプリ側は黒い半透過の処理が自動で入り操作はできません。また、レイアウトも通常モードと変化はありません。</p>

<ul class="list_notice_1">
<li><span class="marker">※</span> Slide Overは、iPad Pro、iPad Air以降、およびiPad mini 2以降で利用可能です。（2016月1月現在）</li>
</ul>

<div class="lyt_image_3">
<img src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160107_01.png" alt="" width="520" height="390">
</div>

<h2>Split View</h2>

<p>Split Viewは、1つの画面で2つのアプリを同時に使える機能です。<br />
Slide Overの状態から、さらに左にスワイプすることで、Split Viewになります。</p>

<p>Slide Overと大きく異なる点として、2つのアプリを同時に操作が可能な点と、それぞれのアプリが分割された状態で表示される点があります。<br />
モーダルウィンドウのような形ではなく、分割された状態で同時に表示されるため、レイアウトにも大きく影響が出ます。</p>

<ul class="list_notice_1">
<li><span class="marker">※</span> Split Viewは、iPad Pro、iPad Air 2、およびiPad mini 4で利用可能です。（2016月1月現在）</li>
</ul>

<h3>Landscapeかつ画面サイズの1/3でSplit Viewで表示</h3>

<div class="lyt_image_3">
<img src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160107_02.png" alt="" width="520" height="390">
</div>

<h3>Landscapeかつ画面サイズの半分でSplit Viewで表示</h3>

<div class="lyt_image_3">
<img src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160107_03.png" alt="" width="520" height="390">
</div>

<h3>Portraitかつ画面サイズの半分でSplit Viewで表示</h3>

<div class="lyt_image_3">
<img src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160107_04.png" alt="" width="520" height="693">
</div>

<p>今回のデモアプリは、AdaptiveなUIの考え方を取り入れ、iOS6から使える「Auto Layout」やiOS8から使える「Size Classes」を使っています。<br />
そのため、様々な画面サイズや比率に応じた適切なレイアウトになっています。<br />
（余談ですが、当社のWebサイトはレスポンシブWebデザインのため、Safariの幅に応じて、最適なレイアウトで表示されています）</p>

<p>もし、デモアプリを固定のUIにしていた場合、以下のようなレイアウトになってしまいます。<br />
これでは、Split Viewで2つのアプリを同時に使えるようになっても、ユーザー体験が向上することはないでしょう。</p>

<h3>Landscapeかつ画面サイズの半分でSplit Viewで表示（固定UI）</h3>

<div class="lyt_image_3">
<img src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20160107_05.png" alt="" width="520" height="390">
</div>

<h2>AdaptiveなUIの重要性</h2>

<p>ここ数年、iPhone 5S/iPhone 6/Phone6 Plus/Apple Watch/iPad/iPad Proなど、iOSを搭載するデバイスの画面サイズが多様になりました。<br />
さらに前述した、Split Viewの状態とフルスクリーンの状態とでは、使える画面サイズや縦横比も変わります。<br />
各画面サイズに応じた最適なUIのアプリを提供することは、すでに必須になっていると言えるでしょう。<br />
そのため、AppleはAdaptiveなUIを提供するための考え方やTipsを、<a href="https://developer.apple.com/design/adaptivity/">Adaptive User Interfaces</a>として公開しています。</p>

<p>Adaptive User Interfacesを取り入れ、よい良いユーザー体験が提供できるアプリを作っていきましょう！</p>]]>
    </content>
</entry>

<entry>
    <title>Electronでプロセス間通信をする</title>
    <link rel="alternate" type="text/html" href="https://www.mitsue.co.jp/knowledge/blog/apps/201512/08_1724.html" />
    <id>tag:www.mitsue.co.jp,2015:/knowledge/blog/apps//13.222</id>

    <published>2015-12-08T08:24:51Z</published>
    <updated>2019-02-12T03:12:58Z</updated>

    <summary>前回は、Electronを使って一番簡単なアプリを作ってみました。今回は、Nod...</summary>
    <author>
        <name>インタラクションアーキテクト 大室</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.mitsue.co.jp/knowledge/blog/apps/">
        <![CDATA[<p><a href="/knowledge/blog/apps/201512/07_1615.html">前回</a>は、Electronを使って一番簡単なアプリを作ってみました。今回は、Node.jsと連携させる方法について紹介します。</p>

<h2>メインプロセスとレンダラプロセス</h2>

<p>Electronは、起動時にNode.js側で実行するJavaScriptと、そのNode.jsから立ち上げたBrowserWindow（HTML）で実行するJavaScriptの、2つのJavaScriptが存在し、それぞれ別のプロセスがあります。<br />
前者を「メインプロセス」、後者を「レンダラプロセス」と呼んでいます。</p>

<p>レンダラプロセスからメインプロセスへ必要に応じて処理を依頼することで、ブラウザのJavaScriptだけではできなかった様々なことが実現可能になります。<br />
そして、Electronではそのプロセス間通信を行うためのモジュールとして、ipcモジュールがあらかじめ定義されています。</p>

<p>例えばブラウザで実行されるJavaScriptはセキュリティ上、ファイルが設置されているドメイン以外のURLにあるファイルを取得することはできません。しかし、Electronのメインプロセスを担っているNode.jsはサーバサイドで使うことを想定した技術のため、ブラウザの制限を受けず、通信することが可能になります。</p>]]>
        <![CDATA[<h2>非同期通信の実装例</h2>

<p>まずは、レンダラプロセスとメインプロセス間で非同期通信をするサンプルを紹介します。<br />
レンダラプロセスからメインプロセスへ値を送り、メインプロセスでその値を2倍にしてレンダラプロセスへ返し、HTMLで表示するというサンプルです。</p>

<p>非同期通信は、レンダラプロセスからメインプロセスへ処理を依頼し、メインプロセスで処理が終わったら値を返します。 非同期のため、レンダラプロセスはメインプロセスから値が帰ってくることを待たずに次の処理に進みます。 そのため、レンダラプロセスにメインプロセスからの処理結果用のコールバック関数をあらかじめ定義する必要があります。</p>

<h3>pakckage.json</h3>

<pre><code>{
  "name"    : "async-app",
  "version" : "0.1.0",
  "main"    : "async.js"
}</code></pre>

<h3> HTML（レンダラプロセス） </h3>

<pre><code>&lt;!DOCTYPE html>
&lt;html>
&lt;head>
&lt;meta charset="UTF-8">
&lt;title>Async Test&lt;/title>
&lt;script>
  // IPC通信を行う
  var ipc = require('ipc');
  var info;
  window.onload = function () {
    info = document.getElementById('info');
    testAsync();
  };
  // 非同期に通信を行う
  function testAsync() {
    // 非同期通信の結果を受けたときのコールバック
    ipc.on('async-reply', function(arg) {
      insertMsg("result = " + arg);
    });
    // メインプロセスに引数を送信
    ipc.send('async', { value:200 });
  }
  function insertMsg(msg) {
    info.innerHTML += msg + "&lt;br>";
  }
&lt;/script>
&lt;/head>
&lt;body>
&lt;h1>Async Test&lt;/h1>
&lt;p id="info">&lt;/p>
&lt;/body>
&lt;/html>
</code></pre>

<h3>JavaScript（メインプロセス）</h3>

<pre><code>var app = require('app');
var BrowserWindow = require('browser-window');
var ipc = require('ipc');
var mainWindow = null;
// 起動
app.on('ready', function(){
    mainWindow = new BrowserWindow({ width:600, height:600 });
    mainWindow.loadUrl('file://' + __dirname + '/async.html');
    mainWindow.on('closed', function(){
        mainWindow = null;
    });
});
// 非同期プロセス通信
ipc.on('async', function( event, args ){
    console.log( args );
    var result = args.value * 2;
    // レンダラプロセスへsend
    event.sender.send('async-reply', result);
});
</code></pre>

<p>ターミナル（Windowsならコマンドプロンプト）で上記ファイルのあるディレクトリへ移動し、electronコマンドを実行すると、以下のようになるはずです。<br />
レンダラプロセスから送った値が、2倍になって表示されていれば成功です。<br />
<div class="lyt_image_3"><br />
<img alt="" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20151208_01.png" width="520" height="217"><br />
</div></p>

<h2>実用例</h2>

<p>冒頭で述べたとおりブラウザで実行されるJavaScriptから別ドメインにあるファイルをAjaxで取得しようとすると、クロスドメイン制約のため取得できません。<br />
しかし、Node.jsが使えるElectronでは、レンダラプロセスのJavaScriptからメインプロセスのJavaScript（Node.js）を実行できるため、ブラウザのセキュリティを考慮する必要がなく通信可能になります。</p>

<p>ここで、小さなサンプルアプリを作ってみたので紹介します。<br />
任意のWebサイトのHTMLファイルを動的に取得し、その中にあるすべてのAタグのhref属性に入っている値を抽出するアプリです。<br />
今回は当社のWebサイトからリンク先を抽出してみたいと思います。</p>

<ul>
<li><a href="https://www.mitsue.co.jp/knowledge/">https://www.mitsue.co.jp/knowledge/</a></li>
</ul>

<h3>pakckage.json</h3>

<pre><code>{
  "name"    : "linkExtraction-app",
  "version" : "0.1.0",
  "main"    : "linkExtraction.js"
}</code></pre>

<h3> HTML（レンダラプロセス） </h3>

<pre><code>&lt;!DOCTYPE html>
&lt;html>
&lt;head>
&lt;meta charset="UTF-8">
&lt;title>リンク抽出&lt;/title>
&lt;script>
  // IPC通信を行う
  var ipc = require('ipc');
  var result;
  // onloadのタイミングで実行
  window.onload = function () {
    result = document.getElementById('result');
    getLink();
  };
  // 非同期通信の関数
  function getLink() {
    // 非同期通信の結果用のコールバック
    ipc.on('link-extraction-reply', function( args ) {
      if( args === null ){
        return;
      }
      var len = args.length;
      var resultStr = '&lt;ul>';
      for(var i = 0; i < len; i++){
        var text = args[i]['text'];
        var href = args[i]['href'];
        resultStr += '&lt;li>' + text + ' : ' + href + '&lt;/li>';
      }
      resultStr += '&lt;/ul>';
      insertResult( resultStr );
    });
  }
  // メインプロセスに引数を送信
  ipc.send('link-extraction-async', { target: 'https://www.mitsue.co.jp/knowledge/'} );
  // 返却値をHTMLに挿入
  function insertResult( msg ) {
    result.innerHTML += msg;
  }
&lt;/script>
&lt;/head>
&lt;body>
&lt;div id="result">&lt;/div>
&lt;/body>
&lt;/html>
</code></pre>

<h3>JavaScript（メインプロセス）</h3>

<pre><code>var app = require('app');
var BrowserWindow = require('browser-window');
var ipc = require('ipc');
var client = require('cheerio-httpcli');
var URL = require('url');
var mainWindow = null;
// 起動
app.on('ready', function(){
    mainWindow = new BrowserWindow({width:600, height:600});
    mainWindow.loadUrl('file://' + __dirname + '/linkExtraction.html');
    mainWindow.on('closed', function(){
        mainWindow = null;
    });
});
// 非同期プロセス通信
ipc.on('link-extraction-async', function( event, arg ){
    var target = arg['target'];
    client.fetch( target, {}, function(err, $, res) {
        if( err ){
            // エラーの場合、レンダラプロセスへnullを返す
            event.sender.send('link-extraction-reply', null);
            return;
        }
        // 一時保存用のArray
        var resulrObjArr = [];
        $("a").each(function( idx ) {
            var text = $(this).text();
            var href = $(this).attr('href');
            if( !href ){
                return;
            }
            // URLモジュールを使い、絶対パスに変換
            var href2 = URL.resolve( target, href );
            // Objectにする
            var tempObj = {
                text : text,
                href : href2
            };
            // 保存しておく
            resulrObjArr.push( tempObj );
        });
        // レンダラプロセスへ返す
        event.sender.send('link-extraction-reply', resulrObjArr);
    });
});</code></pre>

<p>以下のようになれば成功です。</p>

<div class="lyt_image_3">
<img alt="" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20151208_02.png" width="520" height="577">
</div>

<p>Electronは、Web技術がベースになっているため、SassのようなCSSプリプロッサも使えますし、AngularJSやReactなどのJavaScriptフレームワークも使えます。<br />
さらにそこにNode.jsの強力なモジュールを組み合わせることで、業務効率化を図るちょっとしたアプリでも、Visual Studio Codeのような大規模なアプリでも、用途にあった様々なアプリをWeb技術で作ることが可能になります。</p>

<p>今回は触れていませんが、ElectronやNode.jsを使うことでユーザーのローカルにあるファイルの読み書きや操作など、できることがとても多くなるため、モラルやセキュリティにもこれまで以上に配慮する必要があります。また、アプリは操作感も大切になるため、UXにもこだわるとより良いアプリになるのではないでしょうか。<br />
こういった部分は、大変ではありますが、制作者としては非常に面白い部分でもあると思います。<br />
ぜひ、試してみてください。</p>]]>
    </content>
</entry>

<entry>
    <title>Hello Electron!</title>
    <link rel="alternate" type="text/html" href="https://www.mitsue.co.jp/knowledge/blog/apps/201512/07_1615.html" />
    <id>tag:www.mitsue.co.jp,2015:/knowledge/blog/apps//13.221</id>

    <published>2015-12-07T07:15:32Z</published>
    <updated>2019-02-12T03:12:58Z</updated>

    <summary>Electron（エレクトロン）について Electronは、Github社が提...</summary>
    <author>
        <name>インタラクションアーキテクト 大室</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.mitsue.co.jp/knowledge/blog/apps/">
        <![CDATA[<h2>Electron（エレクトロン）について</h2>

<p><a href="http://electron.atom.io/">Electron</a>は、Github社が提供している、1つのソースでWindowsでもMacでもLinuxでも動作可能なクロスプラットフォームなデスクトップアプリの実行環境です。<br />
Chromiumブラウザを内蔵しているため、Webのフロントエンド技術の基本となっているHTML/CSS/JavaScript（Node.js）でアプリを作ることができるのが特徴です。<br />
なお、Chromiumブラウザは、Google ChromeやOperaのベースとなっているオープンソースのブラウザです。</p>

<p>自動アップデートやWindowsインストーラー、クラッシュレポートなど、ネイティブアプリに役立つさまざまな機能のAPIも提供されており、しかもライセンスはMITなので商用利用も無料で可能となっています。<br />
AtomやSlack、Visual Studio Codeなどアプリケーションでも使われていることで最近なにかと話題なっています。</p>

<p>同じクロスプラットフォームなデスクトップアプリ実行環境としては、Adobe AIRやUnity、NW.jsなどがあります。</p>

<p>今回は、Hello Electron!を表示するElectronアプリの制作をしてみようと思います。</p>

<h2>制作環境の準備</h2>

<p>前提として、Node.jsとnpmはインストールされているものとします。</p>

<p>Electron本体をインストール<br />
<pre><code>$ npm install electron-prebuilt -g</code></pre></p>

<p>Electronをアプリとしてパッケージングするための、electron-packagerをインストール<br />
<pre><code>$ npm install electron-packager -g</code></pre></p>

<h2>Hello Electron!</h2>

<p>Electronアプリにするためには、アプリの基本的な設定を行うpakckage.jsonとJavaScript（Node.js）ファイルが最低限必要となります。<br />
また、今回は表示用としてHTMLファイルも追加します。</p>

<h3>pakckage.jsonの用意</h3>

<pre>{
  "name"    : "hello-app",
  "version" : "0.1.0",
  "main"    : "hello.js"
}<code>
</code></pre>

<h3>JavaScriptファイルの用意</h3>

<pre><code>// Electronの準備
var app = require('app');
var BrowserWindow = require('browser-window');
// ブラウザを保管しておく変数
// ガベージコレクションの対象外にするため、グローバルに定義
var mainWindow = null;
// Electronの初期化が終わってから実行
app.on('ready', function () {
    // ブラウザ(Chromium)の起動させ、初期画面のロード
    mainWindow = new BrowserWindow({ width:800, height:600 });
    mainWindow.loadUrl('file://' + __dirname + '/index.html');
    // closedしたときに変数を初期化
    mainWindow.on('closed', function(){
        mainWindow = null;
    });
});
</code></pre>

<h3>HTMLファイルの用意</h3>

<pre><code>&lt;!DOCTYPE html>
&lt;html>
&lt;head>
&lt;meta charset="UTF-8">
&lt;title>Hello Electron!&lt;/title>
&lt;script>
window.onload = function () {
var infoEle = document.getElementById("info");
  infoEle.innerHTML =
    "Node ver." + process.version + "&lt;br>" +
    "atom ver." + process.versions['electron'];
};
&lt;/script>
&lt;/head>
&lt;body>
&lt;h1>Hello Electron!&lt;/h1>
&lt;p id="info">&lt;/p>
&lt;/body>
&lt;/html>
</code></pre>

<h3>確認してみる</h3>

<p>ターミナル（Windowsならコマンドプロンプト）で、pakckage.jsonがあるディレクトリへ移動し、electronコマンドを実行。<br />
<pre><code>$ electron .</code></pre></p>

<h2>アプリとしてパッケージング</h2>

<p>パッケージングの実行<br />
<pre><code>$ electron-packager ディレクトリ アプリ名 --platform=darwin,win32 --arch=x64 --version=0.1.0 --overwrite</code></pre></p>

<p>パラメータの詳細については、<a href="https://github.com/maxogden/electron-packager#usage">electron-packager#usage</a>を参照してください。</p>

<p>以下のようになれば成功です。<br />
<div class="lyt_image_3"><img alt="" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20151207_01.png" width="832" height="754"></div></p>

<h2>メリット/デメリット</h2>

<p>冒頭にも述べたとおり、ElectronはブラウザとしてChroniumをそのまま同梱します。<br />
そのため、HTML/CSS/JavaScript（Node.js）といった基本的なWeb技術でネイティブで動作するアプリが簡単に作成できるのがメリットとしてある反面、Chronium本体もそのまま同梱されるので、パッケージングしたアプリの容量は大きく、このような簡単なアプリであっても数十〜数百MBになってしまいます。</p>

<h2>Node.jsの活用</h2>

<p>いかがでしょうか。<br />
思いの外簡単に作れることが実感できたと思います。</p>

<p>ただ、今回はHTMLファイルに記述したHello Electron!を表示させただけなので、Node.jsと連携できることの恩恵はほぼないアプリになっています。<br />
次回はブラウザだけではできない、ElectronがNode.jsを実行できる環境を持っていることの恩恵を活用したアプリの制作を紹介します。</p>]]>
        
    </content>
</entry>

<entry>
    <title>ES2015による継承の方法</title>
    <link rel="alternate" type="text/html" href="https://www.mitsue.co.jp/knowledge/blog/apps/201511/25_1638.html" />
    <id>tag:www.mitsue.co.jp,2015:/knowledge/blog/apps//13.214</id>

    <published>2015-11-25T07:38:56Z</published>
    <updated>2019-02-12T03:12:22Z</updated>

    <summary>2015年6月17日、最新のJavaScriptの標準仕様となるECMA-262...</summary>
    <author>
        <name>インタラクションアーキテクト 大室</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.mitsue.co.jp/knowledge/blog/apps/">
        <![CDATA[<p>2015年6月17日、最新のJavaScriptの標準仕様となるECMA-262 6th Edition (ECMAScript 6, ES6, ECMAScript 2015, ES2015など複数の呼称がありますが、本記事では以降ES2015と略します) が正式に承認されました。  <br />
ES2015は、クラスやModules、Generatorや非同期処理のPromise、taple、Allow関数など、他にもたくさんの開発者にとって嬉しい新機能が加わりました。</p>

<p>今回は個人的に一番待ち望んでいたクラスを使って、オブジェクト指向プログラミングの基礎である継承の方法について、ES3/ES5/ES2015といった各バージョンごと説明したいと思います。</p>

<p>なお、JavaScriptは柔軟な書き方ができるのがひとつの特徴であるため、ここにあげた例が唯一無二の正解というわけではなく、あくまでひとつの例と考えてください。<br />
また、ES3/ES5にクラスはありませんが本記事では説明の都合上、「クラスに相当するオブジェクト」のことを「クラス」と表現しています。</p>

<h2>ES3</h2>

<pre><code>// ES3は、Object.create が使えないため、代理クラスを使用する
function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}
// スーパークラス
function Animal(bay) {
    this.bay = bay;
}
Animal.prototype.greet = function() {
    return this.bay;
};
// サブクラス
function Dog(name) {
    Animal.call( this, name );
}
// サブクラスにスーパークラスを継承させる
Dog.prototype = object( Animal.prototype );
Dog.prototype.constructor = Dog;
// サブクラスのメソッドを新たに定義
Dog.prototype.superGreet = function() {
    return this.bay + '!!!';
};
// クラスをインスタンス化
var dog = new Dog('bow wow');
console.log( dog.greet() );
console.log( dog.superGreet() );
</code></pre>

<p>まずはES3に対応した一例です。<br />
特徴は以下の部分です。<br />
<pre><code>Dog.prototype = object( Animal.prototype );</code></pre></p>

<p> 事前に定義したobject関数を使って、サブクラスのprototypeに追加しています。   <br />
ここで、<br />
<pre><code>Dog.prototype = new Animal();</code></pre></p>

<p>とすると、newした段階でコンストラクタが呼ばれてしまい、さらにサブクラスをnewする段階でももう一度コンストラクタが呼ばれてしまいます。<br />
これは無駄なコストですし、バグの温床にもなります。なによりコンストラクタとして期待する挙動と異なります。<br />
そのため、上記のような方法をとっています。</p>

<h2>ES5</h2>

<pre><code>// スーパークラス
function Animal(bay) {
    this.bay = bay;
}
Animal.prototype.greet = function() {
    return this.bay;
};
// サブクラス
function Dog(name) {
    Animal.call( this, name );
}
// サブクラスにスーパークラスを継承させる
Dog.prototype = Object.create( Animal.prototype );
Dog.prototype.constructor = Dog;
// サブクラスのメソッドを新たに定義
Dog.prototype.superGreet = function() {
    return this.bay + '!!!';
};
// クラスをインスタンス化
var dog = new Dog('bow wow');
console.log( dog.greet() );
console.log( dog.superGreet() );
</code></pre>

<p>ES5になると、<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create()</a>が使えるため、少しスッキリします。</p>

<p>このようにES5までは、prototypeチェーンに継承させたいprototypeオブジェクトを追加することで、（個人的な意見ですが、やや強引な方法で）継承を実現していました。</p>

<h2>ES2015</h2>

<pre><code>// スーパークラス
class Animal {
    constructor(bay) {
        this.bay = bay;
    }
    greet() {
        return this.bay;
    }
}
// サブクラス
// extends キーワードで継承
class Dog extends Animal {
    constructor(bay) {
        super(bay);
    }
    superGreet() {
        return this.bay + "!!!"
    }
}
// クラスをインスタンス化
let dog = new Dog("bow wow");
console.log( dog.greet() );
console.log( dog.superGreet() );
</code></pre>

<p>ES2015になると、継承を行うための機能である extends キーワードがそのまま使えるためとてもスッキリ書くことができます。</p>

<h2>ES2015を使うべきか</h2>

<p>ES2015はまだ、<a href="http://kangax.github.io/compat-table/es6/">対応ブラウザ</a>が少ない状況です。（2015年11月現在）<br />
しかし、<a href="https://babeljs.io/">Babel</a>のようなトランスパイラや、<a href="https://github.com/paulmillr/es6-shim/">es6-shim</a>といったpolyfillも出てきているため、これらを使うことでES2015で書けるようにもなってきています。</p>

<p>Webアプリやシングルページアプリケーションを実装するときは、必要となるコードの量も必然的に多くなります。<br />
そのときに、ES2015から使えるクラスやその他の便利な機能などを駆使することで、コードが書きやすくなったり可読性があがりコンテンツ制作そのものに今まで以上に集中でき、コンテンツの質も上がるため、私は積極的に使っていきたいと考えています。</p>]]>
        
    </content>
</entry>

<entry>
    <title>シーグラフアジア2015 参加レポート</title>
    <link rel="alternate" type="text/html" href="https://www.mitsue.co.jp/knowledge/blog/apps/201511/06_0917.html" />
    <id>tag:www.mitsue.co.jp,2015:/knowledge/blog/apps//13.206</id>

    <published>2015-11-06T00:17:42Z</published>
    <updated>2016-09-29T05:36:54Z</updated>

    <summary>私は、先日、11月2日から5日の4日間、神戸国際会議場・神戸国際展示場にて開催さ...</summary>
    <author>
        <name>インタラクションアーキテクト 大室</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.mitsue.co.jp/knowledge/blog/apps/">
        <![CDATA[<p>私は、先日、11月2日から5日の4日間、神戸国際会議場・神戸国際展示場にて開催された「<a href="http://sa2015.siggraph.org/jp/">第8回ACMシーグラフアジア2015</a>（The 8th ACM SIGGRAPH Conference and Exhibition on Computer Graphics and Interactive Techniques in Asia、以下シーグラフアジア2015）」に参加してきました。</p>

<p>アメリカをベースとするコンピュータ科学の学会であるACM（Association for Computing Machinery）が主催していることからも分かるように、ジーグラフアジアはアジアにおけるコンピュータグラフィックスとインタラクティブ技術のカンファレンスと展示が行われるイベントです。<br />
<div class="lyt_image_3"><img alt="シーグラフアジア2015案内とパスポート" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20151106_01.png" width="520" height="390"></div></p>

<p>自分は、インタラクティブテクノロジーに関する発表や展示が行われる「Exhibition」と「Emerging Technologies」、映像・サウンド・パフォーマンス・インスタレーションなどのデジタル技術を活用した作品を展示した「Art Gallery」、CGやインタラクティブ応用技術などのテーマをもとに参加者たちが議論する「Symposium」を中心に参加し、最新のインタラクション・コンテンツの研究動向を確認することにしました。</p>

<p>この記事では、写真を交えてインタラクション・コンテンツと関係の高い「Exhibition」「Emerging Technologies」の風景を紹介します。</p>

<p>毎年発展されて少しずつ実用化されているAR、VRなどの研究領域に支えられて、今回のイベントでは従来のPCモニターを超えて、様々な方法で映像や画像を表示する技術がたくさん紹介されていました。</p>

<p>まず、代表的なヘッドアップディスプレイ「<a href="https://www.oculus.com/en-us/">Oculus</a>」を用いたコンテンツを紹介するところが多く見られました。<br />
<div class="lyt_image_3"><img alt="ヘッドアップディスプレイ「Oculus」を用いたデモンストレーション" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20151106_02.png" width="520" height="390"></div></p>

<p>車運転のシミュレーション、他人の目線を体験など、主に疑似体験を目的としたゲーミフィケーション要素が含まれているコンテンツが多かったです。</p>

<p>画像認識とプロジェクションマッピングを組み合わせて、高速で動いているボールをリアルタイムで認識して映像を映す「<a href="http://sa2015.demoserver.sg/en/attendees/emerging-technologies.html?view=event&type=etech&event=92">Ballumiere</a>」技術もありました。<br />
<div class="lyt_image_3"><img alt="高速で動いているボールをリアルタイムで認識して、プロジェクションマッピングする" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20151106_03.png" width="520" height="208"></div></p>

<p>新しい素材を利用したディスプレイもありました。結露を使って情報を提示するディスプレイ「<a href="http://sa2015.demoserver.sg/en/attendees/emerging-technologies.html?view=event&type=etech&event=120">Ketsuro-Graffiti</a>」がそれです。</p>

<div class="lyt_image_3"><img alt="結露を使って情報を提示するディスプレイ「Ketsuro-Graffiti」" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20151106_04.png" width="520" height="347"><span class="caption">PCで設定した図（左）がPVCミラー（右）に写っている姿</span></div>

<p>曇っても表示が可能なため、シャワー室に本日の天気を表示したりするところに活用できそうですね。</p>

<p>最後に紹介するのは、再帰性反射（Retro-Reflection）用いて空中に映像を映す「<a href="http://sa2015.demoserver.sg/en/attendees/emerging-technologies.html?view=event&type=etech&event=95">R2D2 w/ AIRR</a>」です。<br />
<div class="lyt_image_3"><img alt="Retro-Reflection技術を用いた空中ディスプレイ「R2D2 w/ AIRR」" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20151106_05.png" width="520" height="290"></div></p>

<p>両手を認知して、その間に太陽の映像を表示します。両手の間の距離を広げたり、狭めると太陽の大きさが変わります。</p>

<p>他にも、3Dモニターに2つの映像を送出して偏光メガネで見たら別の映像が映せる富士通SSLの<a href="http://www.ssl.fujitsu.com/release/2015/08/4.html">ExPixel</a>技術も注目されていました。</p>

<p>「Symposium」セッションのテーマもそうでしたが、「Emerging Technologies」の主な内容も従来のPCメインの技術を超えて、IoTデバイスのように実生活で活用することを目的にして、馴染んでいるアナログ経験をデジタル化する研究やデモが多かったと思います。</p>

<p>シーグラフアジア2016は、マカオで開催されます。来年はどのような技術が発表されて注目されるか楽しみです。</p>]]>
        
    </content>
</entry>

<entry>
    <title>THETA Sの開発用SDKを使ってみる</title>
    <link rel="alternate" type="text/html" href="https://www.mitsue.co.jp/knowledge/blog/apps/201510/30_1154.html" />
    <id>tag:www.mitsue.co.jp,2015:/knowledge/blog/apps//13.204</id>

    <published>2015-10-30T02:54:29Z</published>
    <updated>2019-02-12T03:12:57Z</updated>

    <summary>RICOH THETA（以下、THETA）は、株式会社リコー（以下、Ricoh）...</summary>
    <author>
        <name>インタラクションアーキテクト 大室</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.mitsue.co.jp/knowledge/blog/apps/">
        <![CDATA[<p>RICOH THETA（以下、THETA）は、株式会社リコー（以下、Ricoh）から発売されている、一度の撮影で360度の全天球の写真や動画が撮れるユニークなデジカメです。  <br />
<a href="https://support.google.com/youtube/answer/6178631?hl=ja">YouTube</a>や<a href="https://newsroom.fb.com/news/2015/09/introducing-360-video-on-facebook/">Facebook</a>も360度動画の対応を始めたりと、何かと話題になっています。</p>

<p>以下はTHETAの公式サイトにあるものですが、こういったものが作れます。<br />
<blockquote data-width="500" data-height="375" class="ricoh-theta-spherical-image" >Milky Way from an Norikura Observatory in Mt. Marishiten-dake, Japan - <a href="https://theta360.com/spheres/samples/90a7fb12-3c00-11e5-a50c-22000b598462-1">Spherical Image - RICOH THETA</a></blockquote><br />
<script async src="https://theta360.com/widgets.js" charset="utf-8"></script></p>

<p>機能やコンセプトも面白いのですが、開発用SDKも公開されているので、今回は10月23日に発売されたTHETA Sを使って、そのSDKを試してみました。<br />
SDKは、iOS用とAndroid用があります。私は、iOS用で試しました。</p>

<p>以前から発売されている、RICOH THETAとRICOH THETA m15は、API v1でしたが、THETA SからはAPI v2になっています。<br />
API v2は、Google社の<a href="https://developers.google.com/streetview/open-spherical-camera/">Open Spherical Camera API Version 1.0</a>に準拠し、v1とは使い方が大きく変わっていました。<br />
なお、SDK本体は、<a href="https://developers.theta360.com/ja/">THETA DEVELOPERS</a>のサイトからダウンロードします。</p>

<h2>環境</h2>

<ul>
<li>Swift:2.1</li>
<li>XCode:7.1</li>
<li>iPhone6 & iOS9.1</li>
<li>THETA S & firmware 01.11 & API v2</li>
</ul>

<h2>セッションIDを取得する</h2>

<p>iPhoneとTHETA S間の通信には無線LANからHTTP接続し、GET/POSTリクエストでAPIを叩いていくイメージとなります。戻り値はJSONです。<br />
リクエスト先は、IPアドレスとポートは以下になります。<br />
192.168.1.1:80</p>

<p>iOS用のSDKはObjective-Cで書かれているため、詳細は割愛しますがBridgingHeaderさせる必要があります。<br />
まず、セッションIDを取得してみます。</p>

<h3>リクエスト</h3>

<pre><code>func getSessionId() {
    // URLリクエスト
    let urlStr = "http://192.168.1.1/osc/commands/execute"
    let request = NSMutableURLRequest(URL: NSURL(string: urlStr)!)
    // POST通信
    request.HTTPMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    // パラメータ
    let params: [String: AnyObject] = [
        "name":"camera.startSession",
        "parameters": ""
    ]
    do {
        request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions.init(rawValue: 2))
    } catch {
        print("NSJSONSerialization Error")
        return
    }
    // APIを叩く
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {data, response, error in
        if (error == nil) {
            let result = NSString(data: data!, encoding: NSUTF8StringEncoding)!
            print(result)
        } else {
            print(error)
        }
    })
    task.resume()
}
</code></pre>

<h3>レスポンス</h3>

<pre><code>{
    "name":"camera.startSession",
    "state":"done",
    "results":{ 
        "sessionId":"SID_0008",
        "timeout":180
    }
}
</code></pre>

<p>撮影をするAPIや写真をiPhoneに取り込むAPIを使うときは、ここで取得したセッションIDをパラメータに含んでそれぞれのAPIを叩いていきます。</p>

<h2>静止画撮影用API</h2>

<p>つぎに、上記で取得したセッションIDを使って静止画撮影をしてみます。</p>

<h3>リクエスト</h3>

<pre><code>func takePicture( sessionId:String ) {
    let urlString = "http://192.168.1.1/osc/commands/execute"
    let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
    request.HTTPMethod = "POST"
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")  
    let params: [String: AnyObject] = [
        "name":"camera.takePicture",
        "parameters": ["sessionId": sessionId]
    ]    
    do {
        request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(params, options: NSJSONWritingOptions.init(rawValue: 2))
    } catch {
        print("NSJSONSerialization Error")
        return
    }
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {data, response, error in
        if (error == nil) {
            let result = NSString(data: data!, encoding: NSUTF8StringEncoding)!
            print(result)
        } else {
            print(error)
        }
    })
    task.resume()
}
</code></pre>

<h3>レスポンス</h3>

<pre><code>{
    "name":"camera.takePicture",
    "state":"inProgress",
    "id":"1",
    "progress":{
        "completion":0.0
    }
}
</code></pre>

<p>これで撮影成功です。<br />
撮影した画像はTHETA本体に記録されています。</p>

<h2>使ってみた印象</h2>

<p>この他にも、撮影した画像をiPhoneに転送するAPIやTHETA本体の設定情報のAPIなど、一通りのAPIは揃っており、特別クセもなくすんなり使える印象でした。</p>

<p>あとはアイディア次第で色々な展開できると思います。<br />
例えば、星空をTHETAでインターバル撮影し、iOSの機能で比較明合成（コンポジット）をした360度の星空撮影など、今までにない新しい体験ができます。</p>

<p>ぜひ試してみてください。<br />
</p>]]>
        
    </content>
</entry>

<entry>
    <title>IoT2015 現地レポート</title>
    <link rel="alternate" type="text/html" href="https://www.mitsue.co.jp/knowledge/blog/apps/201510/27_1142.html" />
    <id>tag:www.mitsue.co.jp,2015:/knowledge/blog/apps//13.200</id>

    <published>2015-10-27T02:42:49Z</published>
    <updated>2016-09-29T05:36:54Z</updated>

    <summary>私は、韓国のソウルで開催されているInternational conferenc...</summary>
    <author>
        <name>インタラクションアーキテクト 大室</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.mitsue.co.jp/knowledge/blog/apps/">
        <![CDATA[<p>私は、韓国のソウルで開催されている<a href="http://www.iot-conference.org/iot2015/">International conference on the Internet of Things 2015</a>（以下、IoT 2015）に参加しています。<br />
IoT 2015は「モノのインターネット」をテーマとする国際学術会議です。</p>

<div class="lyt_image_3"><img src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20151027_01.jpg" alt="IoT 2015参加バッジと参加者たちの論文サマリー" width="520" height="390"><span class="caption">IoT 2015参加バッジと参加者たちの論文サマリー</span></div>

<p>2008年から始まって２年に１回開催れてきたIoT 2015は、今年からは毎年開催される予定で５回目を迎えることになります。この学会では、米国のMITや韓国のKAISTなど、世界各地の優秀な学校が研究している論文が発表され、論文採択率（Accepted rate）は毎年約25%程度と言われています。もちろん、関連産業の会社や学界の関係者たちの研究結果も発表されます。</p>

<div class="lyt_image_3"><img src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20151027_02.jpg" alt="IoT 2015のプログラムテーブル" width="480" height="640"><span class="caption">IoT 2015のプログラムテーブル</span></div>

<p>この学会の主な発表分野は、モノのインターネットのためのプラットフォーム、ネットワーク・ソリューション、アーキテクチャーモデル、ビックデータ、クライドコン・ピューティング、モノのウェブ（Web of Thnigs）、サービス、アプリケーションなど、モノのインターネットの全般的な内容が含まれています。</p>

<div class="lyt_image_3"><img src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20151027_03.jpg" alt="IoT 2015のセッション雰囲気" width="520" height="390"><span class="caption">IoT 2015のセッション雰囲気</span></div>

<p>この学会はキーノートセッション、テクニカルセッション、ワークショップセッション、ポスターセッション、デモセッションに分かれていて、各セッションは細かいテーマにまた分かれて進行されます。私は、テクニカルセッションをメインにして、ポスターセッションとデモセッションに参加し、世界で行っているモノのインターネットの研究動向を情報収集する予定です。<br />
</p>]]>
        
    </content>
</entry>

<entry>
    <title>Adobe MAX 2015 レポート3</title>
    <link rel="alternate" type="text/html" href="https://www.mitsue.co.jp/knowledge/blog/apps/201510/08_0929.html" />
    <id>tag:www.mitsue.co.jp,2015:/knowledge/blog/apps//13.192</id>

    <published>2015-10-08T00:29:20Z</published>
    <updated>2019-02-12T03:12:21Z</updated>

    <summary>今回はAdobe MAXの現地に行かないと体験できない、ちょっとした小ネタを紹介...</summary>
    <author>
        <name>インタラクションエンジニア 藤本</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.mitsue.co.jp/knowledge/blog/apps/">
        <![CDATA[<p>今回はAdobe MAXの現地に行かないと体験できない、ちょっとした小ネタを紹介します。</p>

<h2>落書き</h2>

<p>会場に入ると、まず縦2m 横15mほどの大きな黒板があります。  <br />
これはAdobe MAX恒例となっている落書き用の黒板です。  <br />
オリジナルのキャラクターや会社のロゴなど、世界中のクリエイター達が油性マジックを使い、思い思いに落書きしています。</p>

<div class="lyt_image_3"><img alt="" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20151008_01.jpg" width="520" height="390"></div>

<p>もちろん、私たちも落書きしておきました。</p>

<div class="lyt_image_3"><img alt="" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20151008_02.jpg" width="520" height="390"></div>

<h2>MAX STORE</h2>

<p>Adobe MAX開催中に会場内にだけオープンするMAX STOREがあります。  <br />
ここは、Tシャツやクッション・グラスや文房具など、Adobe製品を元にしたちょっとしたグッズが販売されています。  <br />
数量限定のものや珍しいものがあり、毎年楽しみにしているものの一つなので、1日目の基調講演後にすぐに行ってみました。</p>

<div class="lyt_image_3"><img alt="" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20151008_03.jpg" width="520" height="520"></div>

<div class="lyt_image_3"><img alt="" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20151008_04.jpg" width="520" height="520"></div>

<h2>メインビジュアルを裏から見ると・・・</h2>

<p>メイン会場であるLos Angeles Convention Centerに入ると一番はじめにとても大きなビジュアルが目に入ります。</p>

<div class="lyt_image_3"><img alt="" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20151008_05.jpg" width="520" height="390"></div>

<p>これ、実は裏側から見ると、次回のAdobe MAXの予告が書いてあるんです。<br />
この6年間はずっとLos Angeles Convention Centerで開催されていましたが、なんと次回はサンディエゴ！！<br />
次回は場所も変わってどんな発表やセッションがあるのか、今から非常に楽しみです。</p>

<div class="lyt_image_3"><img alt="" src="https://www.mitsue.co.jp/knowledge/blog/apps/img/20151008_06.jpg" width="520" height="390"></div>]]>
        
    </content>
</entry>

</feed>
