ionic ネットワーク接続を確認する 【Capacitor】

#はじめに
追加情報として、[Ionic アプリ起動時にオフラインなら警告を出す（Capacitor）](https://qiita.com/kokogento/items/2699e4c2a6f4f0f2aca0)もあります。
##環境
[Capacitor](https://capacitor.ionicframework.com/docs/getting-started/with-ionic/) + ionic4

##概要
アプリで可能な限り欲しい機能の１つである**インターネット接続の検出。**
オフラインになると「ネット接続を確認してね〜」って出るアレ。

公式は[こちら](https://capacitor.ionicframework.com/docs/apis/network/)


#capacitorのNetwork APIを入れる
home.page.tsを使ってやっていく。

以下を追加。

```typescript:home.page.ts
import { Plugins, NetworkStatus } from '@capacitor/core';
const { Network } = Plugins;

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
  status: NetworkStatus;
  constructor() { }

  ionViewDidEnter() {
    this.getStatus();
  }
  async getStatus() {
    try {
      this.status = await Network.getStatus();
    } catch (error) { 
      console.log('エラー ', error);
    }
  }
}
```

htmlで確認できるようにする。

```html:home.page.html
<ion-content>
  <div class="ion-padding">
    <p> Network Status: {{status | json}} </p>
  </div>
</ion-content>
```

オンライン状態なら`connected:true`、オフライン状態なら`connected:false`と表示される。

#オフラインならアラートを出す
接続状態の検出はできた。

次はよくあるアレを実装する。

```typescript:home.page.ts
import { AlertController } from '@ionic/angular';
import { Plugins, NetworkStatus } from '@capacitor/core';
const { Network } = Plugins;

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {
  status: NetworkStatus;
  constructor(private alertCtrl: AlertController) { }

  ionViewDidEnter() {
    this.getStatus();
    this.startListenNetwork();
  }

  ionViewWillLeave() {
    this.stopListenNetwork();
  }

  async getStatus() {
    try {
      this.status = await Network.getStatus();
    } catch (error) {
      console.log('エラー ' + error);
    }
  }

  startListenNetwork() {
    this.listener = Network.addListener('networkStatusChange', (status) => {
      if (!status.connected) {
        this.networkAlert();
      }
    });
  }

  stopListenNetwork() {
    if (this.listener) {
      this.listener.remove();
    }
  }

  async networkAlert() {
    const alert = await this.alertCtrl.create({
      header: '接続エラー',
      message: 'インターネット接続がオフラインです。。インターネット接続を確認して下さい！',
      buttons: ['OK']
    });
    await alert.present();
  }
}
```

Wi-Fiをオフにして確認する。

<img width="246" alt="スクリーンショット 2019-10-27 18.34.08.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/29f034ee-de7b-327b-9fe8-35f2b6494bc8.jpeg">

こんな感じで表示されれば成功！！:relaxed:

###ちなみに、**Androidの場合は権限の設定が必要**なんだとか。

※私の場合はデフォルト？で設定されてました。

`AndroidManifest.xml`に以下を追加

```xml:AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
```

これによって、アプリが現在のネットワークに関する情報にアクセス可能となる。

`AndroidManifest.xml`はAndroid Studioを開いて以下の場所で確認できる。

<img width="390" alt="スクリーンショット 2019-10-28 17.13.22.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/299a9405-639a-4a5a-b3d2-82985e497f0e.jpeg">

#Serviceを使って実行させる
アプリのページ数が少ないなら、さっきの感じで`xxx.page.ts`に書いてもいい。
**でもページ数が多くなると、すべてのページに書くのは面倒だ。**

よってServiceにまとめる。

```typescript:home.service.ts
import { AlertController } from '@ionic/angular';
const { Network } = Plugins;

@Injectable({
  providedIn: 'root'
})
export class HomeService {
  status: NetworkStatus;
  listener: any;

 constructor(
    private alertCtrl: AlertController
  ) { }

 // ネット接続の状態を取得
  async getStatus() {
    try {
      this.status = await Network.getStatus();
    } catch (error) {
      console.log('エラー ' + error);
    }
  }

  // ネット接続の確認を開始
  startListenNetwork() {
    this.listener = Network.addListener('networkStatusChange', (status) => {
      if (!status.connected) {
        this.networkAlert();
      }
    });
  }

  // ネット接続の確認を終了
  stopListenNetwork() {
    if (this.listener) {
      this.listener.remove();
    }
  }

  async networkAlert() {
    const alert = await this.alertCtrl.create({
      header: '接続エラー',
      message: 'インターネット接続がオフラインです。。インターネット接続を確認して下さい！',
      buttons: ['OK']
    });
    await alert.present();
  }
}
```

serviceから注入して使う。

```typescript:home.page.ts
constructor(
    private homeService: HomeService,
  ) 

ionViewDidEnter() {
    this.homeService.getStatus();
    this.homeService.startListenNetwork();
  }

  ionViewWillLeave() {
    this.homeService.stopListenNetwork();
  }
```

これで`homeService`をimportするだけで、すべてのページで使える。