【Flutter】人気なパッケージの使い方 〜url_launcher編〜

## まえがき
2020年入ってからFlutterの勉強を初めてきました。
今後いろんなパッケージをもっと勉強していきたいと思ってるので、人気なものをアウトプットとして記事にしていきたいと思います。

今回は**url_launcher**と言うパッケージを紹介します。

これまで載せた記事
- [shared_preferencesの紹介](https://qiita.com/ryota47/items/bc381f85080dbf4b2454)
- [url_launcherの紹介](https://qiita.com/ryota47/items/0cd30257f063c06df1b8)←今これ
- [flutter_slidable](https://qiita.com/ryota47/items/6ed90ce011ea6aaa8698)


## url_launcher
アプリから指定したURLを開くためのパッケージ
URLの開き方は、3つあります。
- アプリ内で開く
- ブラウザに遷移して開く
- ユニバーサルリンクでアプリに直接遷移(iOSのみ)

それぞれのサンプルを用意しました。

他にも電話、SMS、メールもできるみたいですが、今回はそれらは扱いません。
電話はあまり使うイメージがないのと、SMSとメールはよくわからなかったでの、、、

## サンプル

![url_launcher.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311390/a92d9dbb-b30b-d589-51bd-9f9998ccf938.gif)


```dart
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'dart:core';

class SampleUrlLauncher extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _SampleUrlLauncher();
}

class _SampleUrlLauncher extends State<SampleUrlLauncher> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('url_launcher'),
      ),
      body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
        children: [
          RaisedButton(
            child: Text('アプリ内でURLを開く'),
            onPressed: () {
              _launchInApp();
            },
          ),
          RaisedButton(
            child: Text('ブラウザでURLを開く'),
            onPressed: () {
              _launchInBrowser();
            },
          ),
          RaisedButton(
            child: Text('iOSのユニバーサルリンクを開く'),
            onPressed: () {
              _launchUniversalLinkIos();
            },
          ),
          RaisedButton(
            child: Text('5秒たったら閉じる'),
            onPressed: () {
              _launchInApp();
              Timer(
                const Duration(seconds: 5),
                () {
                  closeWebView();
                },
              );
            },
          ),
        ],
      )),
    );
  }

// アプリ内で開く
  _launchInApp() async {
    const url = 'https://pub.dev/packages/url_launcher';
    if (await canLaunch(url)) {
      await launch(
        url,
        forceSafariVC: true,
        forceWebView: true,
      );
    } else {
      throw 'このURLにはアクセスできません';
    }
  }

// ブラウザで開く
  _launchInBrowser() async {
    const url = 'https://pub.dev/packages/url_launcher';
    if (await canLaunch(url)) {
      await launch(
        url,
        forceSafariVC: false,
        forceWebView: false,
      );
    } else {
      throw 'このURLにはアクセスできません';
    }
  }

// ユニバーサルリンク
  _launchUniversalLinkIos() async {
    const url = 'https://www.youtube.com/';
    if (await canLaunch(url)) {
      await launch(
        url,
        forceSafariVC: false,
        forceWebView: false,
        universalLinksOnly: true,
      );
    } else {
      throw 'このURLにはアクセスできません';
    }
  }
}
```

## 説明

`RaisedButton`で各パターンを作りました。

- `canLaunch`：URLが開けるものかどうか判断するメソッド
- `launch`：URLを開くメソッド

また`launch`のなかで、そのリンクをどのように開くかを決めます。

- `forceSafariVC`：iOSでアプリ内かブラウザのどちらかでURLを開くか決める。`true`がアプリ内で開く。デフォルトでは`true`
- `forceWebView`：Androidでアプリ内かブラウザのどちらかでURLを開くか決める。`true`がアプリ内で開く。デフォルトでは`true`
- `universalLinksOnly`：URLがユニバーサルリンクとそうではない時のの挙動を決める。`forceSafariVC`が`false`の時のみ使える。(iOSのみ)
    - `false`
        - ユニバーサルリンクの時、ネイティブアプリ起動
        - ユニバーサルリンクではない時、ブラウザで開く
    - `true`
        - ユニバーサルリンクの時、アプリがデバイスにインストールされていればネイティブアプリ起動
        - ユニバーサルリンクでない時、`PlatformException`でエラーとなる。(アプリがインストールされてなくてもエラー)

ユニバーサルリンクとは、URLを開くと自動的にアプリが起動するリンクです！
YoutubeやInstagramなどでありますよね！
**若干true/falseでの挙動の違いが理解しにくいのでご注意を！**

また`closeWebView()`でアプリ内で開いたURLを閉じることができます。

```dart
RaisedButton(
  child: Text('5秒たったら閉じる'),
  onPressed: () {
    _launchInApp();
    Timer(
      const Duration(seconds: 5),
      () {
        closeWebView();
      },
    );
  },
),
```

こちらのコードで`Timer`を使い5秒後に`closeWebView()`が動くようにしました。
したがって、ボタンを押すと`_launchInApp()`よりURLが開きそれから5秒後に閉じて元の画面に戻ります。

今回は使ってませんが、`launch`には`statusBarBrightness`というiOS上でURLを開いた後にアプリのステータスバーの明るさを設定するものもあります。

- `Brightness.dark`
- `Brightness.light`

で設定します。

## 使える場面

利用規約やリンクが変動しないときに使えるかな