<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://organizeseries.com/"
	>

<channel>
	<title>NativeScript &#8211; HTML5Experts.jp</title>
	<atom:link href="/tag/nativescript/feed/" rel="self" type="application/rss+xml" />
	<link>https://html5experts.jp</link>
	<description>日本に、もっとエキスパートを。</description>
	<lastBuildDate>Sat, 07 Jul 2018 03:14:05 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.7.19</generator>
	<item>
		<title>キミはNativeScriptを知っているか？Angular2でネイティブモバイルアプリが書けるぞ！</title>
		<link>/albatrosary/20691/</link>
		<pubDate>Fri, 09 Sep 2016 02:42:17 +0000</pubDate>
		<dc:creator><![CDATA[佐川 夫美雄]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Angular2]]></category>
		<category><![CDATA[NativeScript]]></category>

		<guid isPermaLink="false">/?p=20691</guid>
		<description><![CDATA[連載： Web技術でアプリ開発2016 (4)Web技術でアプリ開発2016特集・第4弾は、JavaScript（およびTypeScript）によるクロスプラットフォーム開発が可能ながらネイティブと同様の実行速度を得られ...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/web-based-apps-2016/" class="series-391" title="Web技術でアプリ開発2016" data-wpel-link="internal">Web技術でアプリ開発2016</a> (4)</div><p>Web技術でアプリ開発2016特集・第4弾は、JavaScript（およびTypeScript）によるクロスプラットフォーム開発が可能ながらネイティブと同様の実行速度を得られる、<a href="http://www.telerik.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Telerik</a>社の<a href="https://www.nativescript.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">NativeScript</a>を取り上げたいと思います。</p>

<p>NativeScriptは、Angular2とも組み合わせて使うことができる、現在注目のフレームワークです。本記事では、XMLによるUI定義を行う従来の開発手法だけではなく、Angular2（ただし、RC4という少し古いバージョン）と組み合わせてモバイルアプリを開発する方法まで網羅してご紹介します。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/09/NativeScript_logo.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/09/NativeScript_logo.png" alt="NativeScript_logo" width="300" height="300" class="alignnone size-full wp-image-20730" srcset="/wp-content/uploads/2016/09/NativeScript_logo.png 300w, /wp-content/uploads/2016/09/NativeScript_logo-150x150.png 150w, /wp-content/uploads/2016/09/NativeScript_logo-207x207.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<h1>NativeScriptの概要</h1>

<p><a href="https://www.nativescript.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">NativeScript 2.0</a>は、JavaScriptとCSSを使用し、ネイティブのiOSとAndroidのアプリを構築するためのフレームワークです。ネイティブで実行されるパフォーマンスとUXを提供し、その結果、ネイティブプラットフォームのレンダリングエンジンを使ってUIを構築します。WebViewsでのUIレンダリングはしていません。</p>

<p>NativeScriptには<a href="https://www.npmjs.com/package/tns-core-modules" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">tns-core-modules</a>というコアモジュールがあり、上記に述べたJavaScriptからネイティブへの変換を行っています。NativeScriptのgithubリポジトリを見ると「0.9.0」のリリースが「5 Mar 2015」なので、約1年とちょっとの歳月が経過していることになります。現時点での最新バージョンは「2.2.1」です。</p>

<p>NativeScriptでAngular2を利用する場合には、まず、Angular2のテンプレート（@Component.template）に、NativeScriptで提供しているディレクティブを記述します。そして、上記で説明したtns-core-modulesと<a href="https://www.npmjs.com/package/nativescript-angular" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">nativescript-angular</a>を利用してNativeScriptがビルドを行い、iOSやAndroidのネイティブコードを生成します。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/09/4bd44303086f2a767d223e68d2da08ae.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/09/4bd44303086f2a767d223e68d2da08ae-300x129.png" alt="nativescript-angular" width="300" height="129" class="alignnone size-medium wp-image-20694" srcset="/wp-content/uploads/2016/09/4bd44303086f2a767d223e68d2da08ae-300x129.png 300w, /wp-content/uploads/2016/09/4bd44303086f2a767d223e68d2da08ae.png 640w, /wp-content/uploads/2016/09/4bd44303086f2a767d223e68d2da08ae-207x89.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>「NativeScript with Angular2」の最初の「v0.3.0」がリリースされたのが今年8月初旬で、最新は「v0.3.1」です。</p>

<p>この記事では、macOS上での開発を前提に解説をしています。</p>

<h1>インストール</h1>

<p>インストール手順は<a href="http://docs.nativescript.org/start/quick-setup" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">quick-setup</a>にも書かれている通り、あまり複雑なところはありません。しかし、もしAndroid SDKをはじめて利用する場合には少し戸惑うと思います（私もNativeScriptのあまりやさしいとはいえないエラーメッセージにちょっと苦しみました）ので、順を追って説明します。</p>

<ul>
<li>ステップ1: Rubyのインストール</li>
<li>ステップ2: Node.jsのインストール</li>
<li>ステップ3: NativeScript CLIのインストール</li>
<li>ステップ4: iOSとAndroid開発に必要なもののインストール</li>
</ul>

<h2>ステップ1: Rubyのインストール</h2>

<p>NativeScriptをビルドするとき、Rubyを利用します。Rubyのバージョンは2.2以降が必要ですが、macOSにデフォルトでインストールされているRubyは古いため、<code>Homebrew</code>を使って最新バージョンをインストールします。最新のRubyが入っている方は読み飛ばして下さい。</p>

<h3>Homebrewのインストール</h3>

<p><a href="http://brew.sh/index_ja.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Homebrew</a>はRubyを使いインストールし、インストール後環境変数を定義します。</p>

<p></p><pre class="crayon-plain-tag">$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
$ brew update
$ echo 'export PATH=/usr/local/bin:$PATH' &gt;&gt; .bash_profile
$ source .bash_profile</pre><p></p>

<h3>rbenvとruby-buildのインストール</h3>

<p>brewを使って<a href="https://github.com/rbenv/rbenv" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">rbenv</a>と<a href="https://github.com/rbenv/ruby-build" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ruby-build</a>をインストールします。rbenvを使ってRubyのバージョン管理を行います。ruby-buildはrbenvのプラグインで、異なるバージョンのRubyをコンパイルし、インストールするためのものです。</p>

<p></p><pre class="crayon-plain-tag">$ brew install rbenv ruby-build
$ echo 'eval "$(rbenv init -)"' &gt;&gt; ~/.bash_profile
$ source ~/.bash_profile
$ rbenv --version
$ rbenv install -l
$ rbenv install 2.2.3
$ rbrnv version
$ rbenv global 2.2.3
$ ruby -v
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-darwin15]
$</pre><p></p>

<h2>ステップ2: Node.jsのインストール</h2>

<p><code>Node.js</code>はv4.0.0以降を利用する必要があります。<code>rbenv</code>と同様にバージョン管理システムをインストールします。<code>Node.js</code>のバージョン管理システムには<a href="https://github.com/hokaccha/nodebrew" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">nodebrew</a>, <a href="https://github.com/marcelklehr/nodist" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">nodist</a>, <a href="https://github.com/creationix/nvm" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">nvm</a>, <a href="https://github.com/coreybutler/nvm-windows" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">nvm-windows</a>などいくつかありますが、筆者は<code>nodebrew</code>を好んで利用しています。</p>

<h3>nodebrew のインストール</h3>

<p>curlを使ってインストールを行います。インストールが完了するとパスを追加するようにメッセージが表示されますので、.bash_profile に登録してください。</p>

<p></p><pre class="crayon-plain-tag">$ curl -L git.io/nodebrew | perl - setup
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' &gt;&gt; .bash_profile
$ source .bash_profile</pre><p></p>

<h3>Node.jsのインストール</h3>

<p>続いて、Node.jsをインストールします。<code>nodebrew ls-remote</code>コマンドを使ってバージョンを確認し、<code>nodebrew install-binary</code>コマンドを使ってNode.jsのインストールを行います。利用するバージョンを動かす場合には<code>nodebrew use</code>コマンドを実行します。</p>

<p>今回、Node.jsのバージョンとしては<code>v5.12.0</code>を利用しました。</p>

<p></p><pre class="crayon-plain-tag">$ nodebrew ls-remote
$ nodebrew install-binary v5.12.0
$ nodebrew use v5.12.0
$ node -v
v5.12.0
$</pre><p></p>

<h2>ステップ3: NativeScript CLIのインストール</h2>

<p>いよいよNativeScriptのインストールです。<code>npm</code>コマンドを使って<code>nativescript</code>をグローバルインストールします。<code>nativescript</code>はスカッフォールディング（コード雛形の自動生成）を提供するモジュールで、<code>tns</code>コマンドによって実行されます。</p>

<p><code>tns</code>コマンドを実行して、インストールが正しく行われているか確認しましょう。参考までに<code>tns</code>コマンドで出力される内容は<code>tns --help</code>と同じ内容です。<code>tns</code>コマンドでは主に</p>

<ul>
<li>テンプレートからプロジェクトの生成</li>
<li>プロジェクトへの生成プラットフォーム(iOS, Android)の追加</li>
<li>JavaScriptからネイティブへのビルド</li>
<li>エミュレータの実行</li>
</ul>

<p>を行います</p>

<p></p><pre class="crayon-plain-tag">$ npm install nativescript -g
$ tns
# NativeScript
┌─────────┬─────────────────────────────────────────────────────────────────────┐
│ Usage   │ Synopsis                                                            │
│ General │ $ tns  [Command Parameters] [--command ]                            │
│ Alias   │ $ nativescript  [Command Parameters] [--command ]                   │
└─────────┴─────────────────────────────────────────────────────────────────────┘

・・・

$</pre><p></p>

<h2>ステップ4: iOSとAndroid開発に必要なもののインストール</h2>

<h3>JDKのインストール</h3>

<p>JDKはバージョンが8以降のものをインストールしてください。インストールが完了したら、<code>.bash_profile</code>に設定を登録してください。</p>

<p></p><pre class="crayon-plain-tag">$ echo 'export JAVA_HOME=$(/usr/libexec/java_home)' &gt;&gt; .bash_profile
$ source .bash_profile</pre><p></p>

<h3>Android開発環境のインストール</h3>

<p>Android SDKをHomebrewからインストールし、変数<code>ANDROID_HOME</code>を定義します.</p>

<p></p><pre class="crayon-plain-tag">$ brew install android-sdk
$ echo 'export ANDROID_HOME=/usr/local/Cellar/android-sdk/24.4' &gt;&gt; .bash_profile
$ echo 'export PATH=$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools' &gt;&gt; .bash_profile
$ source .bash_profile</pre><p></p>

<h4>Androidエミュレータのインストール</h4>

<p>android-sdkのインストールが終わったら、実際に利用するエミュレータを定義します。<code>android-sdk</code>がインストールされているディレクトリへ移動し、<code>andorid avd</code>を実行することで設定を行います。<code>android-sdk</code>以下のディレクトリ構成は次の通りです。</p>

<p></p><pre class="crayon-plain-tag">$ cd /usr/local/Cellar/android-sdk/24.4
$ tree -L 1
.
├── INSTALL_RECEIPT.json
├── README
├── add-ons -&gt; ../../../var/lib/android-sdk/add-ons
├── bin
├── build-tools
├── etc
├── extras -&gt; ../../../var/lib/android-sdk/extras
├── platform-tools
├── platforms -&gt; ../../../var/lib/android-sdk/platforms
├── samples -&gt; ../../../var/lib/android-sdk/samples
├── sources -&gt; ../../../var/lib/android-sdk/sources
├── system-images -&gt; ../../../var/lib/android-sdk/system-images
├── temp -&gt; ../../../var/lib/android-sdk/temp
└── tools</pre><p></p>

<p>Androidエミュレータを高速化するためのハードウェア支援環境「Intel Hardware Accelerated Execution Manager (Intel® HAXM) 」を事前にインストールします。次のスクリプトを実行してください。</p>

<p></p><pre class="crayon-plain-tag">$ cd /usr/local/Cellar/android-sdk/24.4/extras/intel/Hardware_Accelerated_Execution_Manager
$ sudo ./silent_install.sh</pre><p></p>

<p>完了したら、<code>android avd</code>を起動し、事前にエミュレータ定義を登録します。</p>

<p></p><pre class="crayon-plain-tag">$ cd /usr/local/Cellar/android-sdk/24.4/tools
$ ./android avd</pre><p></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/09/08745f58e1623aad624c9c147ce67bdf.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/09/08745f58e1623aad624c9c147ce67bdf-300x226.png" alt="android avd" width="300" height="226" class="alignnone size-medium wp-image-20697" srcset="/wp-content/uploads/2016/09/08745f58e1623aad624c9c147ce67bdf-300x226.png 300w, /wp-content/uploads/2016/09/08745f58e1623aad624c9c147ce67bdf.png 640w, /wp-content/uploads/2016/09/08745f58e1623aad624c9c147ce67bdf-207x156.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>この設定を忘れると<a href="https://github.com/NativeScript/android-runtime/issues/533" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">「Cannot read property &#8216;targetNum&#8217; of undefined」というエラーが出ます</a>。</p>

<p>参考までに、今回利用しているエミュレータは次のように定義しています。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/09/92e741b3229f54ad2ccec77a5d994344.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/09/92e741b3229f54ad2ccec77a5d994344-300x250.png" alt="スクリーンショット 2016-09-06 14.11.30" width="300" height="250" class="alignnone size-medium wp-image-20698" srcset="/wp-content/uploads/2016/09/92e741b3229f54ad2ccec77a5d994344-300x250.png 300w, /wp-content/uploads/2016/09/92e741b3229f54ad2ccec77a5d994344.png 640w, /wp-content/uploads/2016/09/92e741b3229f54ad2ccec77a5d994344-207x173.png 207w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>

<p>よくあるトラブルとしては、Dockerを起動しているようなら終了させておくのが無難です。Dockerが利用しているポートとエミュレータが利用するポートがぶつかり、実行できないことがあります。</p>

<h3>iOS開発環境のインストール</h3>

<p>macOSを利用されていれば、iOSのエミュレータを利用するのは容易だと思います。</p>

<h4>Command Line Tools for Xcode</h4>

<p></p><pre class="crayon-plain-tag">$ sudo gem install xcodeproj
$ sudo gem install cocoapods
$ brew install xcproj</pre><p></p>

<p>だいぶ長くなりましたが、これで開発環境の設定は完了です。尚、tnsコマンドには<code>tns doctor</code>というコマンドがあります。環境設定などうまくできているかのチェックができますので、一通り終わった後に実行し、漏れがないかを確認します。</p>

<p></p><pre class="crayon-plain-tag">$ tns doctor
Verifying CocoaPods. This may take more than a minute, please be patient.
  ◡ Installing iOS runtime.tns-ios@2.2.1 ../../../../../../var/folders/ts/n268b_qx2j7g3ykzkqlj3jt00000gn/T/nativescript-check-cocoapods11686-1391-akcqo6/node_modules/tns-ios
  ◝ Verifying CocoaPods. This may take some time, please be patient..
Your components are up-to-date.

No issues were detected.
$</pre><p></p>

<h1>NativeScriptで作るHello World</h1>

<p>ここではNativeScriptを使ってHello World的なアプリケーションを作成します。手順は</p>

<ol>
<li>プロジェクトの作成</li>
<li>プラットフォームのインストール</li>
<li>エミュレータの実行</li>
</ol>

<p>です。NativeScriptでのアプリケーション作成には<code>tns</code>コマンドを使います。</p>

<p>今、プロジェクトを<code>MyFirstNativeScriptApp</code>としますので、iOSとAndroidアプリケションの両方を作成する場合にはiOSとAndroidのプラットフォーム用ライブラリをインストールしエミュレートを起動します。</p>

<p></p><pre class="crayon-plain-tag">$ cd ~
$ tns create MyFirstNativeScriptApp
$ cd MyFirstNativeScriptApp
$ tns platform add android
$ tns platform add ios
$ tns run android --emulator
$ tns run ios --emulator</pre><p></p>

<p>Androidエミュレータでの実行結果</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/09/MyFirstNativeScriptApp-Android.gif" data-wpel-link="internal"><img src="/wp-content/uploads/2016/09/MyFirstNativeScriptApp-Android.gif" alt="MyFirstNativeScriptApp-Android" width="200" height="300" class="alignnone size-medium wp-image-20720" /></a></p>

<p>iOSエミュレータでの実行結果</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/09/MyFirstNativeScriptApp-iOS.gif" data-wpel-link="internal"><img src="/wp-content/uploads/2016/09/MyFirstNativeScriptApp-iOS.gif" alt="MyFirstNativeScriptApp-iOS" width="200" height="300" class="alignnone size-medium wp-image-20721" /></a></p>

<p><code>tns create MyFirstNativeScriptApp</code>で作成されたファイルを確認します。</p>

<p></p><pre class="crayon-plain-tag">$ tree -L 2
.
├── app
│   ├── App_Resources
│   ├── app.css
│   ├── app.js
│   ├── main-page.js
│   ├── main-page.xml
│   ├── main-view-model.js
│   ├── package.json
│   └── references.d.ts
├── node_modules
│   ├── babel-traverse
│   ├── babel-types
│   ├── babylon
│   ├── lazy
│   ├── tns-core-modules
│   └── tns-core-modules-widgets
├── package.json
└── platforms
    ├── android
    └── ios</pre><p></p>

<p>このアプリケーションで特に重要なファイルがありますので、簡単に説明します。</p>

<ul>
<li>app.js</li>
<li>main-page.xml</li>
<li>main-page.js</li>
<li>main-view-model.js</li>
</ul>

<p><code>app.js</code>はアプリケーションが一番最初にロードするエントリーポイントで、このファイルからアプリケーション<code>main-page.js</code>の呼び出しを行っています。</p>

<p></p><pre class="crayon-plain-tag">// app.js
var application = require("application");
application.start({ moduleName: "main-page" });</pre><p></p>

<p></p><pre class="crayon-plain-tag">// main-page.js
var createViewModel = require("./main-view-model").createViewModel;

function onNavigatingTo(args) {
  var page = args.object;
  page.bindingContext = createViewModel();
}
exports.onNavigatingTo = onNavigatingTo;</pre><p></p>

<p><code>main-page.xml</code>は画面をXMLで定義し、関連する処理を<code>main-view-model.js</code>に定義してます。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- main-page.xml --&gt;
&lt;Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="onNavigatingTo"&gt;
  &lt;StackLayout&gt;
    &lt;Label text="Tap the button" class="title"/&gt;
    &lt;Button text="TAP" tap="{{ onTap }}" /&gt;
    &lt;Label text="{{ message }}" class="message" textWrap="true"/&gt;
  &lt;/StackLayout&gt;
&lt;/Page&gt;</pre><p></p>

<p></p><pre class="crayon-plain-tag">// main-view-model.js
var Observable = require(&quot;data/observable&quot;).Observable;

function getMessage(counter) {
  if (counter &lt;= 0) {
    return &quot;Hoorraaay! You unlocked the NativeScript clicker achievement!&quot;;
  } else {
    return counter + &quot; taps left&quot;;
  }
}

function createViewModel() {
  var viewModel = new Observable();
  viewModel.counter = 42;
  viewModel.message = getMessage(viewModel.counter);

  viewModel.onTap = function() {
    this.counter--;
    this.set(&quot;message&quot;, getMessage(this.counter));
  }

  return viewModel;
}

exports.createViewModel = createViewModel;</pre><p></p>

<h2>テンプレートを使って簡単なアプリケーションを作成する</h2>

<p>NativeScriptには、テンプレートを使ってプロジェクトを生成する機能があります。</p>

<p></p><pre class="crayon-plain-tag">$ tns create [Project Name] --template [Template Name]</pre><p></p>

<p>繰り返しになりますが、テンプレートを作成した後「プラットフォームのインストール」「エミュレータの実行」を行うとエミュレートで実行確認ができます。</p>

<p>このテンプレートはnpmに登録されています。が、まだあまり多くのテンプレートは定義されていないようです。その中から開発時に利用できそうなものを幾つかピックアップしました。具体的なコードは各テンプレートを使ってコードを生成し確認していただけると幸いです。</p>

<h3>タブを使ったアプリケーション</h3>

<p></p><pre class="crayon-plain-tag">$ tns create MyNextGreatApp --template tns-template-tab-navigation</pre><p></p>

<p>タブ切り替えのテンプレート部分は<code>TabView</code>タグを使い、各タブで表示する内容は<code>TabViewItem</code>で定義しています。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- main-page.xml --&gt;
&lt;Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="pageLoaded"&gt;
  &lt;TabView&gt;
    &lt;TabView.items&gt;
      &lt;TabViewItem title="First"&gt;
        &lt;TabViewItem.view&gt;
          &lt;StackLayout class="tab-content"&gt;
            &lt;Label text="First View" class="title"/&gt;
            &lt;Label text="This is the content of the first tab." textWrap="true"/&gt;
          &lt;/StackLayout&gt;
        &lt;/TabViewItem.view&gt;
      &lt;/TabViewItem&gt;
      &lt;TabViewItem title="Second"&gt;
        &lt;TabViewItem.view&gt;
          &lt;StackLayout class="tab-content"&gt;
            &lt;Label text="Second View" class="title"/&gt;
            &lt;Label text="This is the content of the second tab." textWrap="true"/&gt;
          &lt;/StackLayout&gt;
        &lt;/TabViewItem.view&gt;
      &lt;/TabViewItem&gt;
    &lt;/TabView.items&gt;
  &lt;/TabView&gt;
&lt;/Page&gt;</pre><p></p>

<p>Androidエミュレータでの実行結果</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/09/MyNextGreatApp-Android.gif" data-wpel-link="internal"><img src="/wp-content/uploads/2016/09/MyNextGreatApp-Android.gif" alt="MyNextGreatApp-Android" width="200" height="300" class="alignnone size-medium wp-image-20722" /></a></p>

<p>iOSエミュレータでの実行結果</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/09/MyNextGreatApp-iOS.gif" data-wpel-link="internal"><img src="/wp-content/uploads/2016/09/MyNextGreatApp-iOS.gif" alt="MyNextGreatApp-iOS" width="200" height="300" class="alignnone size-medium wp-image-20723" /></a></p>

<h3>一覧と詳細を表示するアプリケーション</h3>

<p></p><pre class="crayon-plain-tag">$ tns create MyMasterDetailApp --template tns-template-master-detail</pre><p></p>

<p>一覧と明細は<code>GridLayout</code>を使って表示する場所を定義し、一覧部分を表示するテンプレートは<code>ListView</code>を使っています。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- main-page.xml --&gt;
&lt;Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="pageLoaded"&gt;
  &lt;GridLayout rows="auto, *"&gt;
    &lt;Label text="Items Page" class="title" /&gt;

    &lt;ListView items="{{ items }}" itemTap="listViewItemTap" row="1"&gt;
      &lt;ListView.itemTemplate&gt;
        &lt;Label text="{{ title }}" class="listItem" /&gt;
      &lt;/ListView.itemTemplate&gt;
    &lt;/ListView&gt;
  &lt;/GridLayout&gt;
&lt;/Page&gt;</pre><p></p>

<p>明細部分は<code>details-page.xml</code>でレイアウトを定義していて、具体的な内容の表示には<code>details-view.xml</code>を使っています。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- details-page.xml --&gt;
&lt;Page xmlns="http://schemas.nativescript.org/tns.xsd"
      xmlns:app="."
      navigatedTo="pageNavigatedTo"&gt;
  &lt;app:details-view /&gt;
&lt;/Page&gt;</pre><p></p>

<p></p><pre class="crayon-plain-tag">&lt;!-- details-view.xml --&gt;
&lt;StackLayout  xmlns="http://schemas.nativescript.org/tns.xsd"&gt;
  &lt;Label text="{{ title }}" class="detail-title"/&gt;
  &lt;Label text="{{ info }}" class="info" textWrap="true"/&gt;
&lt;/StackLayout&gt;</pre><p></p>

<p>Androidエミュレータでの実行結果</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/09/MyMasterDetailApp-Android.gif" data-wpel-link="internal"><img src="/wp-content/uploads/2016/09/MyMasterDetailApp-Android.gif" alt="MyMasterDetailApp-Android" width="200" height="300" class="alignnone size-medium wp-image-20716" /></a></p>

<p>iOSエミュレータでの実行結果</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/09/MyMasterDetailApp-iOS.gif" data-wpel-link="internal"><img src="/wp-content/uploads/2016/09/MyMasterDetailApp-iOS.gif" alt="MyMasterDetailApp-iOS" width="200" height="300" class="alignnone size-medium wp-image-20717" /></a></p>

<h3>サイドメニュー付きアプリケーション</h3>

<p></p><pre class="crayon-plain-tag">$ tns create MyDrawerApp --template nativescript-template-drawer</pre><p></p>

<p>サイドメニュー付きアプリケーションを作成する場合には、サイドメニュー<code>drawer-content.xml</code>を定義し、メニューをクリックしたときの画面をそれぞれ定義しています。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- drawer-content.xml --&gt;
&lt;grid-layout class="drawer-content"&gt;
  &lt;stack-layout&gt;
    &lt;label text="Home" tap="navigate" class="{{ selectedPage == 'home' ? 'selected' : '' }}" /&gt;
    &lt;label text="About" tap="navigate" class="{{ selectedPage == 'about' ? 'selected' : '' }}" /&gt;
    &lt;label text="Settings" tap="navigate" class="{{ selectedPage == 'settings' ? 'selected' : '' }}" /&gt;
  &lt;/stack-layout&gt;
&lt;/grid-layout&gt;</pre><p></p>

<p>Androidエミュレータでの実行結果</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/09/MyDrawerApp-Android.gif" data-wpel-link="internal"><img src="/wp-content/uploads/2016/09/MyDrawerApp-Android.gif" alt="MyDrawerApp-Android" width="200" height="300" class="alignnone size-medium wp-image-20724" /></a></p>

<p>iOSエミュレータでの実行結果</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/09/MyDrawerApp-iOS.gif" data-wpel-link="internal"><img src="/wp-content/uploads/2016/09/MyDrawerApp-iOS.gif" alt="MyDrawerApp-iOS" width="200" height="300" class="alignnone size-medium wp-image-20725" /></a></p>

<h1>NativeScriptとAngular2を組み合わせる</h1>

<p>ここからが本記事の一番のポイント、「Angular2を使ったNativeScriptアプリケーション」に入ります。準備が長くて申し訳ありません！</p>

<p><a href="https://www.npmjs.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">npm</a>にはいくつかのAngular2を利用したNativeScriptのテンプレートがありますが、今回は<a href="http://docs.nativescript.org/angular/tutorial/ng-chapter-1#11-install-nativescript-and-configure-your-environment" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">NativeScriptのチュートリアル</a>を参考に、githubリポジトリーからテンプレートをcloneしたものを利用します。</p>

<h2>NativeScript with Angular2で作るHello World</h2>

<p>まずはリポジトリ<code>https://github.com/NativeScript/sample-Groceries</code>をcloneします。clone後、<code>angular-start</code>をcheckoutすると、NativeScript with Angular2で開発するための最も基本的な構成を得ることができます。</p>

<p></p><pre class="crayon-plain-tag">$ git clone https://github.com/NativeScript/sample-Groceries.git
$ cd sample-Groceries
$ git checkout angular-start
$ tree -L 2
├── app
│   ├── App_Resources
│   ├── app.component.ts
│   ├── app.css
│   ├── app.routes.ts
│   ├── main.ts
│   ├── package.json
│   ├── pages
│   ├── platform.android.css
│   ├── platform.ios.css
│   ├── shared
│   └── utils
├── package.json
├── platforms
│   └── ios
├── references.d.ts
└── tsconfig.json
$ tns platform add ios
$ tns platform add android
$ tns run ios --emulator
$ tns run android --emulator</pre><p></p>

<p>Androidエミュレータでの実行結果</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/09/bd526adedcc1d8bc115334228f13f924.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/09/bd526adedcc1d8bc115334228f13f924-186x300.png" alt="HelloWorld-Android" width="186" height="300" class="alignnone size-medium wp-image-20732" srcset="/wp-content/uploads/2016/09/bd526adedcc1d8bc115334228f13f924-186x300.png 186w, /wp-content/uploads/2016/09/bd526adedcc1d8bc115334228f13f924.png 397w, /wp-content/uploads/2016/09/bd526adedcc1d8bc115334228f13f924-128x207.png 128w" sizes="(max-width: 186px) 100vw, 186px" /></a></p>

<p>iOSエミュレータでの実行結果</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/09/9c8a45b0a1b5bb63648952bde5c36faa.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/09/9c8a45b0a1b5bb63648952bde5c36faa-200x300.png" alt="Helloworld-iOS" width="200" height="300" class="alignnone size-medium wp-image-20733" srcset="/wp-content/uploads/2016/09/9c8a45b0a1b5bb63648952bde5c36faa-200x300.png 200w, /wp-content/uploads/2016/09/9c8a45b0a1b5bb63648952bde5c36faa.png 427w, /wp-content/uploads/2016/09/9c8a45b0a1b5bb63648952bde5c36faa-138x207.png 138w" sizes="(max-width: 200px) 100vw, 200px" /></a></p>

<p>NativeScriptではBootstrapに特別なメソッド<code>nativeScriptBootstrap</code>を利用します。具体的にエントリーポイント<code>main.ts</code>は次のように記述されます。</p>

<p></p><pre class="crayon-plain-tag">// main.ts
import {nativeScriptBootstrap} from "nativescript-angular/application";
import {AppComponent} from "./app.component";

nativeScriptBootstrap(AppComponent);</pre><p></p>

<p>Angular2では、NativeScriptのXMLを<code>@Component.template</code>にディレクティブとして定義します。ただ<code>@Component.template</code>ではXMLをそのまま利用できないので、少し書き換える必要があります。具体的には&lt;foo /&gt;を&lt;foo&gt;&lt;/foo&gt;に書き換えるといった作業です。</p>

<p>具体的にこのサンプルの場合、XML定義では</p>

<p></p><pre class="crayon-plain-tag">&lt;Label text='hello world' /&gt;</pre><p></p>

<p>ですが、Angular2ではコンポーネントとして定義します。</p>

<p></p><pre class="crayon-plain-tag">// app.component.ts
import {Component} from "@angular/core";

@Component({
  selector: "my-app",
  template: "&lt;Label text='hello world'&gt;&lt;/Label&gt;"
})
export class AppComponent {}</pre><p></p>

<p><code>Label</code>はHTMLタグではなくNativeScriptで定義されたディレクティブです。NativeScriptでは幾つかのUIコンポーネントを定義していますので一覧にまとめます。</p>

<h2>UIコンポーネントのマッピング</h2>

<p>NativeScriptのUIコンポーネントは、iOSやAndroidのウィジェットにマッピングさせています。ビルドするとNativeScript with Angular2で定義したコンポーネントがマッピングされたiOSやAndroidのウィジェット変換されます。具体的な利用方法に関しては、<a href="http://docs.nativescript.org/angular/ui/components" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Native Script UI Components</a>を見ていただきたいと思います。</p>

<table>
<thead>
<tr>
  <th>NativeScript with Angular2</th>
  <th>Android</th>
  <th>iOS</th>
</tr>
</thead>
<tbody>
<tr>
  <td>Button</td>
  <td>android.widget.Button</td>
  <td>UIButton</td>
</tr>
<tr>
  <td>Label</td>
  <td>android.widget.TextView</td>
  <td>UILabel</td>
</tr>
<tr>
  <td>TextField</td>
  <td>android.widget.EditText</td>
  <td>UITextField</td>
</tr>
<tr>
  <td>TextView</td>
  <td>android.widget.EditText</td>
  <td>UITextView</td>
</tr>
<tr>
  <td>SearchBar</td>
  <td>android.widget.SearchView</td>
  <td>UISearchBar</td>
</tr>
<tr>
  <td>Switch</td>
  <td>android.widget.Switch</td>
  <td>UISwitch</td>
</tr>
<tr>
  <td>Slider</td>
  <td>android.widget.SeekBar</td>
  <td>UISlider</td>
</tr>
<tr>
  <td>Progress</td>
  <td>android.widget.ProgressBar</td>
  <td>UIProgressView</td>
</tr>
<tr>
  <td>ActivityIndicator</td>
  <td>android.widget.ProgressBar</td>
  <td>UIActivityIndicatorView</td>
</tr>
<tr>
  <td>Image</td>
  <td>android.widget.ImageView</td>
  <td>UIImageView</td>
</tr>
<tr>
  <td>ListView</td>
  <td>android.widget.ListView</td>
  <td>UITableView</td>
</tr>
<tr>
  <td>HtmlView</td>
  <td>android.widget.TextView</td>
  <td>UILabel</td>
</tr>
<tr>
  <td>WebView</td>
  <td>android.webkit.WebView</td>
  <td>UIWebView</td>
</tr>
<tr>
  <td>TabView</td>
  <td>android.support.v4.view.ViewPager</td>
  <td>UITabBarController</td>
</tr>
<tr>
  <td>SegmentedBar</td>
  <td>android.widget.TabHost</td>
  <td>UISegmentedControl</td>
</tr>
<tr>
  <td>DatePicker</td>
  <td>android.widget.DatePicker</td>
  <td>UIDatePicker</td>
</tr>
<tr>
  <td>TimePicker</td>
  <td>android.widget.TimePicker</td>
  <td>UIDatePicker</td>
</tr>
<tr>
  <td>ListPicker</td>
  <td>android.widget.NumberPicker</td>
  <td>UIPickerView</td>
</tr>
</tbody>
</table>

<h2>NativeScript + Angular2でHello World</h2>

<p>はじめに作成した「NativeScriptで作るHello World」のAngular2版のテンプレートがあります。アプリケーションの動きはまったく同じですがAngular2で書かれています。</p>

<p></p><pre class="crayon-plain-tag">$ tns create MyNgNativeScriptApp --template tns-template-hello-world-ng 
$ cd MyNgNativeScriptApp
$ tns platform add android
$ tns platform add ios
$ tns run android --emulator
$ tns run ios --emulator</pre><p></p>

<p>テンプレート部分を見比べると、XMLで書かれていたテンプレートコードがAngular2スタイルで記載されていることが理解でき、結果見通しのよいコードになっています。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- app.component.html --&gt;
&lt;StackLayout&gt;
  &lt;Label text="Tap the button" class="title"&gt;&lt;/Label&gt;
  &lt;Button text="TAP" (tap)="onTap()"&gt;&lt;/Button&gt;
  &lt;Label [text]="message" class="message" textWrap="true"&gt;&lt;/Label&gt;
&lt;/StackLayout&gt;</pre><p></p>

<p></p><pre class="crayon-plain-tag">// app.component.ts
import {Component} from "@angular/core";

@Component({
  selector: "my-app",
  templateUrl: "app.component.html",
})
export class AppComponent {
  public counter: number = 16;

  public get message(): string {
    if (this.counter &gt; 0) {
      return this.counter + " taps left";
    } else {
      return "Hoorraaay! \nYou are ready to start building!";
    }
  }
    
  public onTap() {
    this.counter--;
  }
}</pre><p></p>

<h2>Todosアプリケーション</h2>

<p>NativeScriptのサイトには、より多く機能が実装されたチュートリアル<a href="http://docs.nativescript.org/angular/tutorial/ng-chapter-0" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Building Apps with NativeScript and Angular 2</a>を提供しています。完成したアプリケーションは先ほどと同じリポジトリ<code>https://github.com/NativeScript/sample-Groceries</code>にありますので、是非見て下さい。</p>

<p></p><pre class="crayon-plain-tag">$ git clone https://github.com/NativeScript/sample-Groceries.git NgTodosNative
$ cd NgTodosNative
$ tns platform add ios
$ tns platform add android
$ tns run ios --emulator
$ tns run android --emulator</pre><p></p>

<p>Androidエミュレータでの実行結果</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/09/sample-Groceries-Android.gif" data-wpel-link="internal"><img src="/wp-content/uploads/2016/09/sample-Groceries-Android.gif" alt="sample-Groceries-Android" width="200" height="300" class="alignnone size-medium wp-image-20727" /></a></p>

<p>iOSエミュレータでの実行結果</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/09/sample-Groceries-iOS.gif" data-wpel-link="internal"><img src="/wp-content/uploads/2016/09/sample-Groceries-iOS.gif" alt="sample-Groceries-iOS" width="200" height="300" class="alignnone size-medium wp-image-20728" /></a></p>

<p>サンプルコードを読むと、NativeScriptで利用するnativeScriptBootstrapの使い方やNativeScript用のルーティング設定が記載されていたりとAngular2の特徴を活かした実装になっています。</p>

<p>今回は、環境設定からはじまり、NativeScriptを使ったもの、NativeScript wit Angular2へと進め、Hello World的なアプリケーションを動かすところまでをテンプレートを使いながら簡単に説明させていただきました。</p>

<h1>最後に</h1>

<p>NativeScriptの事例がないかと探してみましたが<a href="https://www.nativescript.org/showcases" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">NativeScript Showcases</a>にいくつかありました。このアプリケーションがAngular2をベースにしたものかはわかりませんが、NativeScriptを使ったものです。</p>

<p>NativeScriptのXMLで定義したUIコンポーネントが、コンパイル時にiOS、Androidのウィジェットにそれぞれマッピングされネイティブアプリにコンパイルされます（ちょっと古いですがXSLTを思い出しました）。Angular2の@Component.templateを利用することでNativeScriptがUIコンポーネントの定義を解釈し、ネイティブコードの生成を行っています。</p>

<p>ただし、NativeScript with Angular2用に作成したコンポーネントとNativeScriptを使わない通常のAngular2のコンポーネントとの相互再利用性は低いです。ですが、慣れたAngular2の構造を利用しTypeScript(もしくはJavaScript)で書けるというのは非常に興味が湧くところです。</p>

<p><strong>編集部よりお詫び</strong><br />
<small><strong>
2016/9/9 18:30 編集部が付けた以前のタイトルは、一部の方を不快にさせる可能性があるとの判断のもと、記事タイトルを変更いたしました。
執筆者の佐川さん、及び以前のタイトルを不快に感じた多くの方々に、深くお詫び申し上げます。
</strong></small></p>
]]></content:encoded>
		
		<series:name><![CDATA[Web技術でアプリ開発2016]]></series:name>
	</item>
	</channel>
</rss>
