url_launcher を 6.0.20 -> 6.1.2 にアップしたところ launch
と canLaunch
が Deprecated になっていたため書き直したが、挙動が変わったため修正。
元のコード
await canLaunch("アプリのカスタムURLスキーム")
? await launch("アプリのカスタムURLスキーム")
: await launch("ウェブのURL");
このコードに問題があったことは認識していて、Androidの場合、特定のアプリにおいては想定している経路では処理されていない。
twitter
などのURLスキームはアプリをインストールして必要な設定をしても canLaunch
が false を返してくる場合があり、ウェブブラウザでURLを起動される。
結果的に、ディープリンクとしてサポートしているアプリが起動されていた。
そのため、canLaunch
を使用せずに、try
catch
で実装していたこともあったが最近は canLaunch
を使用していた。
書き直したが挙動が変わってしまったコード
await canLaunchUrlString("アプリのカスタムURLスキーム")
? await launchUrlString("アプリのカスタムURLスキーム")
: await launchUrlString("ウェブのURL");
どうやら、起動モードなどの引数を省略した場合、該当の URL を WebView で表示するようになってしまったようだ。
引数などを設定することも考えたが、ドキュメントに以下の記述があった。
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 で起動が失敗している場合の対応。。。