UEQareer Advent Calendar 2016の19日目のエントリーです。
皆さん、こんにちは!
レッドインパルスのたかけんです。
今回は、技術系の記事です。よろしくお願いします!
Contents
作ったもの

ストップウォッチアプリです。
ソースコードは、こちら
機能はスタート・ストップ・リセットのみの単純な仕様です。
注目すべき点
僕は、Webアプリの開発経験がメインで、スマートフォンアプリを作った経験はほとんどありません。しかし、今回使用するOnsen UIやCordovaといったツールを駆使することで、Web技術のみでスマートフォンアプリを作ることができます。
環境
- Mac OSX
- Node.js v7.2.0
- npm 3.10.9
ストップウォッチアプリの実装
ベースになるプロジェクトの作成
今回は、Reactを使って実装します。ReactはシンプルなViewライブラリです。フルスタックのフレームワークのようにアプリケーションの雛形を生成する機能はありません。
そこでweb上に公開されている雛形プロジェクト(ボイラープレートと呼ばれる)をベースに実装していきます。
今回は、react-simple-boilerplateを使用します。
[bash gutter=”false”] git clone git@github.com:nolotz/react-simple-boilerplate.gitcd react-simple-boilerplate
tree .
├── LICENSE
├── README.md
├── build
├── index.html
├── package.json
├── server.js
├── src
│ ├── App.jsx
│ └── index.jsx
├── styles
│ ├── application.scss
│ └── home.scss
└── webpack.config.js
[/bash]
このような構成になっています。ブラウザ上で、実行してみましょう。
[bash gutter=”false”] npm installnpm start
[/bash]

ローカルサーバが立ち上がり、雛形アプリがブラウザから確認できました。ここから、色々と手を加えていきましょう。
Onsen UIの導入
スマートフォンアプリ用のUIライブラリ「Onsen UI」をインストールします。Reactで使いたいので、以下、2つのライブラリをnpmからインストールします。
[bash gutter=”false”] npm install –save onsenui react-onsenuireact-simple-boilerplate@1.0.0 /xxx/react-simple-boilerplate
├── onsenui@2.0.5
├── UNMET PEER DEPENDENCY react@15.2.1
├── UNMET PEER DEPENDENCY react-dom@15.2.1
└── react-onsenui@1.1.0
npm WARN react-onsenui@1.1.0 requires a peer of react@^15.3.2 but none was installed.
npm WARN react-onsenui@1.1.0 requires a peer of react-dom@^15.3.2 but none was installed.
[/bash]
ボイラープレートのreactのバージョンが古いようで、アラートがでました。package.json内のバージョンを修正し、再度インストールします。
[bash gutter=”false”] npm install –save onsenui react-onsenuinpm install –save-dev file-loader
[/bash]
webpackでファイルの読み込みに必要なfile-loaderも合わせてインストールしました。
webpack.config.jsの修正
詳細は今回作成したアプリが公開されているGitHubのリポジトリ確認してください。Onsen UIや独自に作成したスタイルをインポートできるように設定します。
コンポーネントの作成
src/App.jsxを編集していきましょう。
[js gutter=”false”] import React, {Component} from ‘react’;import {Page, Toolbar, ToolbarButton, Icon} from ‘react-onsenui’;
import ‘./../node_modules/onsenui/css/onsen-css-components.css’;
import ‘./../node_modules/onsenui/css/onsenui.css’;
import ‘./style.scss’;
[/js]
使用するライブラリ、CSS、SASSをインポートします。
style.scssはの中身は割愛しますが、ボタンやフォント等をカスタマイズ用のスタイルです。
Math.floor(sec / 60) +
‘:’ +
(‘0’ + (sec % 60).toFixed(2)).slice(-5)
[/js]
秒をストップウォッチに表示する文字列に変換するオブジェクトを作成します。
[js] class App extends Component {constructor(props) {
super(props);
this.state = {
secondsElapsed: 0,
};
this.incrementer = null;
this.isCounting = false;
}
handleStartClick() {
if (!this.isCounting) {
this.incrementer = setInterval( () =>
this.setState({
secondsElapsed: this.state.secondsElapsed + 0.01
})
, 10);
this.isCounting = true;
}
}
handleStopClick() {
clearInterval(this.incrementer);
this.isCounting = false;
}
handleResetClick() {
clearInterval(this.incrementer);
this.setState({
secondsElapsed: 0,
});
this.isCounting = false;
}
render() {
return (
<Page contentStyle={{backgroundColor: ‘#efeff5′}}>
<Toolbar>
<div className=’center’>ストップウォッチ</div>
<div className=’right’>
<ToolbarButton>
<Icon icon=’ion-navicon, material:md-menu’></Icon>
</ToolbarButton>
</div>
</Toolbar>
<div style={{marginTop: ‘50%’, textAlign: ‘center’}}>
<h1 className=’stopwatch-timer’>{formattedSeconds(this.state.secondsElapsed)}</h1>
</div>
<div className=’stopwatch’>
<Button className=’start-btn’ onClick={this.handleStartClick.bind(this)}>start</Button>
<Button className=’stop-btn’ onClick={this.handleStopClick.bind(this)}>stop</Button>
<Button onClick={this.handleResetClick.bind(this)}>reset</Button>
</div>
</Page>
);
}
}
[/js]
ここがコンポーネントの作成になります。コンストラクタに必要なプロパティを新たに追加しています。incrementerは、時間を図るオブジェクトの代入先です。isCountingは、計測状態を論理値で保持します。
その下に、各ボタンのクリック時に実行されるメソッドをそれぞれ定義しています。renderメソッドは、Onsen UIに従ってpageコンポーネントの中に、toolber・時間表示・ボタンのコンポーネントを定義しています。
<button type=’button’ {…props} className={‘btn ‘ + props.className } />;
[/js]
ボタンのコンポーネントは、汎用的になるように別途、定義しました。
Cordovaでアプリ化
Cordovaは、webアプリをスマホのアプリにラッピングするツールです。
HTML・CSS・JSだけで、JavaやSwiftを使わずiOSやAndroidアプリを作成できます。
cordova create cordova-stopwatch
cd cordova-stopwatch
tree .
.
├── config.xml
├── hooks
│ └── README.md
├── platforms
├── plugins
└── www
├── css
│ └── index.css
├── img
│ └── logo.png
├── index.html
└── js
└── index.js
[/bash]
wwwの中は、自動生成されたファイルが入っています。
今の中身は削除して、先ほど作ったアプリのファイルを追加します。
編集したボイラープレートの直下でwebpackコマンドを使います。
[bash gutter=”false”] webpackHash: 12bdad5d6ae1efd8d742
Version: webpack 1.14.0
Time: 5891ms
Asset Size Chunks Chunk Names
assets/ionicons.dd4781d1acc57ba4c4808d1b44301201.ttf 189 kB [emitted] assets/fontawesome-webfont.25a32416abee198dd821b0b17a198a8f.eot 76.5 kB [emitted] assets/fontawesome-webfont.c8ddf1e5e5bf3682bc7bebf30f394148.woff 90.4 kB [emitted] assets/fontawesome-webfont.1dc35d25e61d819a9c357074014867ab.ttf 153 kB [emitted] assets/fontawesome-webfont.d7c639084f684d66a1bc66855d193ed8.svg 392 kB [emitted] assets/ionicons.19e65b89cee273a249fba4c09b951b74.eot 121 kB [emitted] assets/fontawesome-webfont.e6cf7c6ec7c2d6f670ae9d762604cb0b.woff2 71.9 kB [emitted] assets/ionicons.2c159d0d05473040b53ec79df8797d32.woff 67.9 kB [emitted] assets/ionicons.aff28a207631f39ee0272d5cdde43ee7.svg 334 kB [emitted] assets/Material-Design-Iconic-Font.a4d31128b633bc0b1cc1f18a34fb3851.woff2 38.4 kB [emitted] assets/Material-Design-Iconic-Font.d2a55d331bdd1a7ea97a8a1fbb3c569c.woff 50.3 kB [emitted] assets/Material-Design-Iconic-Font.b351bd62abcd96e924d9f44a3da169a7.ttf 99.2 kB [emitted] bundle.js 3.81 MB 0 [emitted] main
[0] multi main 40 bytes {0} [built] + 280 hidden modules
tree bundle
bundle
├── assets
│ ├── Material-Design-Iconic-Font.a4d31128b633bc0b1cc1f18a34fb3851.woff2
│ ├── Material-Design-Iconic-Font.b351bd62abcd96e924d9f44a3da169a7.ttf
│ ├── Material-Design-Iconic-Font.d2a55d331bdd1a7ea97a8a1fbb3c569c.woff
│ ├── fontawesome-webfont.1dc35d25e61d819a9c357074014867ab.ttf
│ ├── fontawesome-webfont.25a32416abee198dd821b0b17a198a8f.eot
│ ├── fontawesome-webfont.c8ddf1e5e5bf3682bc7bebf30f394148.woff
│ ├── fontawesome-webfont.d7c639084f684d66a1bc66855d193ed8.svg
│ ├── fontawesome-webfont.e6cf7c6ec7c2d6f670ae9d762604cb0b.woff2
│ ├── ionicons.19e65b89cee273a249fba4c09b951b74.eot
│ ├── ionicons.2c159d0d05473040b53ec79df8797d32.woff
│ ├── ionicons.aff28a207631f39ee0272d5cdde43ee7.svg
│ └── ionicons.dd4781d1acc57ba4c4808d1b44301201.ttf
└── bundle.js
[/bash]
必要なファイルが出力されます。
bundleフォルダの中身とindex.htmlをまるごとcordovaプロジェクトのwww直下にコピーします。
cordova run android
[/bash]
今回は、Androidアプリにラッピングします。
実機を接続していれば実機に、無い場合はエミュレータにアプリがインストールされます。
ストップウォッチアプリができました!!
まとめ
web技術を使って、JavaやSwiftを使うことなく、スマホアプリが作れました。Cordova以外にも、スマートフォンアプリ開発においては、XamarinやReact Nativeなどのクロスプラットフォームのツールが現れて、技術的にも盛り上がっています。
それぞれメリット・デメリットがあるので、作りたいアプリの要求条件や自分のスキルを考慮して、適切なツールを選択することが重要ですね。今後も、こういった技術系の記事もドンドン発信していこうと思いますので、よろしくお願いします!