ionicでハイブリッドアプリを作る手順

#目標
ionicで簡単な家計シミュレーションアプリを作ります。
そのための手順として、以下をまとめる予定です。

- ionic環境構築
- DBアクセス
- ページ遷移（ここまでできれば８割方作りたいアプリが作れるのでは？と思ってます）
- デザイン周り
 - カレンダーを実装する
- ionic viewを使って実機で動作確認

#ionic環境構築

##nvmインストール
ionicはnode6.x系以上であればOKだけど、なぜか4.x系となっていた。。。
複数のバージョンをインストールしていたらしい。

```
$ nvm ls
->       v4.8.2
        v6.11.3
         system
default -> v4.8.2
node -> stable (-> v6.11.3) (default)
stable -> 6.11 (-> v6.11.3) (default)
iojs -> N/A (default)
lts/* -> lts/boron (-> v6.11.3)
lts/argon -> v4.8.4 (-> N/A)
lts/boron -> v6.11.3
```

##nvmを切り替える

```
$ nvm use v6.11.3
Now using node v6.11.3 (npm v3.10.10)
```

##ionicのインストール

###【参考サイト】
https://html5experts.jp/rdlabo/22296/

http://ionicframework.com/docs/intro/installation/

http://eiua-memo.tumblr.com/post/107811280833/ionicでハイブリッドアプリを作るionicのインストール-実機で起動

```
$ npm install -g ionic cordova
```

##バージョン確認

```
$ ionic --version
3.12.0
```

##ionicプロジェクトを作る

いろいろ聞かれます。
各質問の内容は後で追記します。

```
$ ionic start myapp
? What starter would you like to use: tabs

? The directory myapp contains file(s) that could conflict. Would you like to overwrite the directory with this new project? Yes
✔ Creating directory ./myapp - done!
[INFO] Fetching app base (https://github.com/ionic-team/ionic2-app-base/archive/master.tar.gz)
✔ Downloading - done!

[INFO] Fetching starter template tabs (https://github.com/ionic-team/ionic2-starter-tabs/archive/master.tar.gz)
✔ Downloading - done!
✔ Updating package.json with app details - done!
✔ Creating configuration file ionic.config.json - done!
[INFO] Installing dependencies may take several minutes!
> npm install
✔ Running command - done!
> git init

? Connect this app to the Ionic Dashboard? Yes
> ionic link
Log into your Ionic account
If you don't have one yet, create yours by running: ionic signup

? Email: XXXXXXXX@YYYY.ZZZ

? Password: [hidden]
> ionic ssh setup
[INFO] Looks like you haven't configured your SSH settings yet.

? How would you like to connect to Ionic Pro? Automatically setup new a SSH key pair for Ionic Pro
[INFO] The automatic SSH setup will do the following:
       1) Generate a new SSH key pair with OpenSSH (will not overwrite any existing keys).
       2) Upload the generated SSH public key to our server, registering it on your account.
       3) Modify your SSH config (../.ssh/config) to use the generated SSH private key for our server(s).

? May we proceed? Yes
> ionic ssh generate /Users/XXXX/.ssh/ionic/XXXXXXX
[INFO] Created ../.ssh/ionic directory for you.

[INFO] You will be prompted to provide a passphrase, which is used to protect your private key should you lose it. (If
       someone has your private key, they can impersonate you!) Passphrases are recommended, but not required.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
[OK] A new pair of SSH keys has been generated!
     Private Key (../.ssh/ionic/XXXXXXX): Keep this safe!
     Public Key (../.ssh/ionic/XXXXXXX.pub): Give this to all your friends!
[INFO] Next steps:
       - Add your public key to Ionic: ionic ssh add ../.ssh/ionic/XXXXXXX.pub
       - Use your private key for secure communication with Ionic: ionic ssh use ../.ssh/ionic/XXXXXXX
> ionic ssh add /Users/XXXX/.ssh/ionic/XXXXXXX.pub --use
[OK] Your public key (XXXXXX:XXXXXXXXXX) has been added to Ionic!
> ionic ssh use /Users/XXXX/.ssh/ionic/XXXXXXX
--- /Users/XXXX/.ssh/config

+++ /Users/XXXX/.ssh/config
@@ -1,0 +1,4 @@
\ No newline at end of file
+Host git.ionicjs.com
+    IdentityFile /Users/XXXX/.ssh/ionic/XXXXXXX
+    Port XX
+

? May we make the above change(s) to '../.ssh/config'? Yes
[OK] Your active Ionic SSH key has been set to /Users/XXXX/.ssh/ionic/XXXXXXX!
[OK] SSH setup successful!
✔ Looking up your apps - done!

? Which app would you like to link Nevermind
[INFO] Not linking app.
> git add -A
> git commit -m "Initial commit" --no-gpg-sign

Next Steps:
Go to your newly created project: cd ./myapp
Then, push your code to the Ionic Dashboard: git push ionic master
```

##ディレクトリ構成と各ファイルの役割
以下サイトがわかりやすかったです。
引用元：http://diaki-h.hatenablog.com/entry/2017/06/06/155829

>**src/pages/**
>ここに各ページを構成するフォルダが入ります。現在はhomeというフォルダが入っているのがわかります。 その中に入っているファイルを見てみます。
>$ ls src/pages/home/
>home.html   home.scss   home.ts
>基本的に一つのページは、要素を記述する.htmlスタイルを記述する .scss命令を記述する .tsファイルで構成されます。
>
>**src/assets/**
>ここにアプリ内で使用する画像などを置きます。
>
>**src/theme/variables.scss**
>アプリ全体に適用されるフォント、カラーなどを設定しています。最初のうちはあまりいじることはないでしょう。
>
>**src/app/**
>app.component.ts アプリを起動したら最初に呼び出されるコンポーネントです。このコンポーネントの下に各ページのコンポーネントがぶら下がっているイメージでいます。
>
>**app.html**
>app.component.tsで読み込んでいます。htmlのエントリポイントという認識でいいと思います。(本当はindex.htmlだが)
>
>**app.module.ts**
>アプリ内で、どのファイルをコンポーネント(ページ)として読み込むのかを宣言するファイルです。 ページだけではなく全てのモジュールをここに記述します。 デフォルトでは、MyAppというコンポーネントがroot指定されているのがわかります。
>
>**main.ts**
>いじらないので割愛
>
>**app.scss**
>Ionicのコンポーネントのスタイルを変えたい場合など、ここにスタイルを記述します。アプリ全体に適用されます。
>
>**www/**
>ionic serveなどで、各ファイルをコンパイルしてまとめられた結果がこのファイル以下に入っています。 ブラウザはこのフォルダ以下のファイルを読み込んで実行しています。
>
>**config.xml**
>アプリの情報、設定を記述するファイル
>
>**package.json**
>nodeモジュールの依存関係を記述するファイル


##プロジェクト起動

```
$ ionic serve
[INFO] Starting app-scripts server: --address 0.0.0.0 --port 8100 --livereload-port XXXXX --dev-logger-port XXXXX -
       Ctrl+C to cancel
[20:39:13]  watch started ...
[20:39:13]  build dev started ...
[20:39:13]  clean started ...
[20:39:13]  clean finished in 4 ms
[20:39:13]  copy started ...
[20:39:13]  transpile started ...

[20:39:16]  transpile finished in 3.46 s
[20:39:16]  preprocess started ...
[20:39:16]  deeplinks started ...
[20:39:16]  deeplinks finished in 20 ms
[20:39:16]  preprocess finished in 21 ms
[20:39:16]  webpack started ...
[20:39:16]  copy finished in 3.78 s
[20:39:26]  webpack finished in 10.13 s
[20:39:26]  sass started ...
[20:39:28]  sass finished in 1.47 s
[20:39:28]  postprocess started ...
[20:39:28]  postprocess finished in 14 ms
[20:39:28]  lint started ...
[20:39:28]  build dev finished in 15.16 s
[20:39:28]  watch ready in 15.32 s
[20:39:28]  dev server running: http://localhost:8100/

[INFO] Development server running!
       Local: http://localhost:8100
       External: http://XXX.XXX.XX.X:8100

[20:39:32]  lint finished in 4.56 s
```

↓勝手にブラウザが開きます
![スクリーンショット 2017-09-24 20.40.11.png](https://qiita-image-store.s3.amazonaws.com/0/186221/36531788-629d-dbee-7b53-7f1adcc4342c.png)

##DBアクセスを実装する

webstorageを使うか、クラウドDBを使うか悩みましたが、妻と家計簿データをシェアしたいと思い、クラウドDBを使うことにしました。

IonicのStorageプラグインの使い方
https://qiita.com/noanoamn/items/ca849856de341bb3b8a6

Firebaseなるものがあるらしい。。。
http://tech.pjin.jp/blog/2017/03/02/make-firebase-board-1/

今回はFirebaseを使うことにしました。

###Firebase導入

####Firebaseとは？
MBaaSの一つ。リアルタイム共有データベースで、ローカルとサーバーのDBがリアルタイムで同期します。

####lonic2にFirebaseプラグインをインストールする手順
以下参考。
https://www.joshmorony.com/building-a-crud-ionic-2-application-with-firebase-angularfire/

```
$ npm install @ionic/app-scripts@latest --save-dev
$ npm install angularfire2 firebase --save
```

####FirebaseのDBからデータを取得し、画面表示する

以下参考。

https://stackoverflow.com/questions/43772474/no-provider-for-angularfiredatabase-angularfireauth
https://github.com/angular/angularfire2/blob/master/docs/version-4-upgrade.md

インポート部分。
angularfire2からAngularFireをインポートできなくなっているらしいので注意。

```ts:app.module.ts
import { AngularFireModule } from 'angularfire2';
import { AngularFireDatabaseModule } from 'angularfire2/database';
```

例えばFirebaseのtalksテーブルから値を取得したい場合は、

```ts:home.ts
export class HomePage {
  talks: FirebaseListObservable<any>;

  constructor(af: AngularFire) {
    af.database.list('/talks');
  }
}
```

ではなく、

```ts:home.ts
export class HomePage {
  talks: FirebaseListObservable<any>;

  constructor(db: AngularFireDatabase) {
    db.list('/talks');
  }
}
```

と書くらしいです。

####ソートの実装

たとえば連番（カラム名：seqとする）の昇順でソートしたい場合は、

```ts:home.ts
export class HomePage {
  talks: FirebaseListObservable<any>;

  constructor(db: AngularFireDatabase) {
    db.list('/talks' , {
      query {
        orderByChild: 'seq'
      }
    });
  }
}
```

と書くようです。

ソートについては別記事でもまとめています。
[【Firebase】日付順にソートする方法](https://qiita.com/irohamaru/items/99b26a9d604cb141203a)

##ページ遷移の実装方法

鋭意執筆中

#デザイン周り

##カレンダーを実装する

今回はionic2-date-pickerを使うことにしました。
https://github.com/shangyilim/ionic2-date-picker

書いてある通りに実装したらうまくいったはず。

![スクリーンショット 2017-09-27 1.25.46.png](https://qiita-image-store.s3.amazonaws.com/0/186221/e491b074-95fc-9a31-e119-16545aebb343.png)

カレンダー実装部分は別記事でまとめました。
[【ionic2】カレンダーの実装](https://qiita.com/irohamaru/items/b7d10d3f25185eac6f32)

# ionic viewを使って実機で動作確認
App Storeにアプリを公開しなくてもionic viewを使えばすぐに実機で動作確認できます。
これは便利。
https://qiita.com/bohebohechan/items/71de7474db86c989586d

ionic buildでエラーが出たので以下対応。
https://github.com/ionic-team/ionic-app-scripts/issues/1001

```
$ npm install promise-polyfill --save-exact
```

コミットはできたが、**BUILD FAILED**となっていたので以下対応。

```
$ npm install --save-dev @angular/tsc-wrapped

// angularfireのバージョンを4.x系に変更
// firebaseのバージョンアップ
$ npm i --save angularfire2@latest
$ npm install firebase@4.0.0

// ビルド実行
$ npm run build

// gitにコミット
$ git add .
$ git commit -m "initial commit"
$ git push ionic master
```


#その他メモ

##ionic serveがエラーとなってしまった場合はプラグインを追加

筆者はnodeのバージョンが古かったためにエラーが起こったようなので、nodeを切り替えて解決しました。一応備忘録として残しておきます。

```
$ npm install typescript -g
$ npm install -g　@ionic/app-scripts@^1.3.1
$ npm install -g　@ionic/cli-plugin-ionic-angular@1.0.0-rc.2
```

###日本語の入ったURLをそのままコピーしたいとき

参考サイトの一部のURLに日本語が入っていたのでメモ
https://qiita.com/ntoreg/items/4a97304dd2861b64a8b6