2
Help us understand the problem. What are the problem?

posted at

【Flutter】結局、url_launcherはどう実装すべきなのか。

url_launcher を 6.0.20 -> 6.1.2 にアップしたところ launchcanLaunch が Deprecated になっていたため書き直したが、挙動が変わったため修正。

元のコード

  await canLaunch("アプリのカスタムURLスキーム")
    ? await launch("アプリのカスタムURLスキーム")
    : await launch("ウェブのURL");

このコードに問題があったことは認識していて、Androidの場合、特定のアプリにおいては想定している経路では処理されていない。

twitter などのURLスキームはアプリをインストールして必要な設定をしても canLaunchfalse を返してくる場合があり、ウェブブラウザでURLを起動される。
結果的に、ディープリンクとしてサポートしているアプリが起動されていた。

そのため、canLaunch を使用せずに、try catch で実装していたこともあったが最近は canLaunch を使用していた。

書き直したが挙動が変わってしまったコード

  await canLaunchUrlString("アプリのカスタムURLスキーム")
    ? await launchUrlString("アプリのカスタムURLスキーム")
    : await launchUrlString("ウェブのURL");

どうやら、起動モードなどの引数を省略した場合、該当の URL を WebView で表示するようになってしまったようだ。

引数などを設定することも考えたが、ドキュメントに以下の記述があった。

Checking supported schemes

However, canLaunchUrl can return false even if launchUrl would work in some circumstances (in web applications, on mobile without the necessary configuration as described above, etc.), so in cases where you can provide fallback behavior it is better to use launchUrl directly and handle failure. For example, a UI button that would have sent feedback email using a mailto URL might instead open a web-based feedback form using an https URL on failure, rather than disabling the button if canLaunchUrl returns false for mailto.

ということで、 try catch で実装することにした。

修正したコード

  try {
    var launched = await launchUrlString("アプリのカスタムURLスキーム");
    if (!launched) {
      await launchUrlString("ウェブのURL");
    }
  } catch (e) {
    await launchUrlString("ウェブのURL");
  }

これ、 catch しているのは、Android で起動が失敗している場合の対応で、 launched で判断しているのが iOS で起動が失敗している場合の対応。。。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
2
Help us understand the problem. What are the problem?