LIFFでQRコードリーダーを実装する


対象読者

LIFFでQRコードリーダーを実装しようとして画面に表示されなかったデベロッパー向けです。
LIFFを実機で確認できるまでの全体のフローを知りたい方は、他の記事を参考にしてください。
また、実際に実装した際にNuxt.jsを用いたため、jsをベースにこの後も話を進めます。

LIFFのバージョン

liff.getVersion()

> 2.6.0

今回詰まった点

QRコードリーダーを実装する際は、以下の2つの機能を実装する必要があります。

  1. デバイスのカメラの映像をスクリーンに表示する
  2. JavaScriptのQRコードスキャンのライブラリを用いて画像にQRコードがあるかを判別する

1.の実装をするにはWebRTCというAPIのnavigator.mediaDevices.getUserMedia()というメソッドを用いる必要があります。今回発生した問題はまさにここで、iPhoneでLINEを開いて確認してみると、なんとLIFFブラウザではこのAPIが対応しておらず表示がされません。ただ、Androidのスマートフォンで見てみると、LIFFブラウザでも問題なく動作しました。調べてみると、LIFFブラウザはiOSとAndroidでそれぞれ別のWebViewが使われおり(下参照)、iOSのWKWebViewがWebRTCに対応していなかったようです。

iOS:12.0以降。WKWebView (opens new window)が使用されます。
Android:5.0以降
LINE:v9.14.0以降

解決方法

解決方法は至ってシンプルで、QRコードリーダーのページのみ、WebRTCに対応しているブラウザで開く、これだけです。
navigator.mediaDevices.getUserMedia()のブラウザの対応状況はIEを見ないフリをすれば、全てに対応しています。

ただし、 iOSのChromeやfirefoxは、WKWebviewが使われており、先に述べた理由から、正常に動きませんでした。
そのため、スマホを利用する前提のアプリケーションを想定する場合は、どのブラウザがWebRTCに対応しているかを確認して要件を決めた方がいいと思います。

(注)なお、iOS14.3からChromeとFireFoxでgetUserMedia()が利用できるようになったようです。

 LIFFブラウザからWebブラウザを開く方法

LIFFブラウザからWebブラウザを立ち上げるには、liff.openWindow()メソッドを使用します。(ドキュメント参照

toQRCodeReader() {
  // LIFFブラウザで立ち上げていた場合
  if (liff.isClient) {
    liff.openWindow({
      url: URL,           // full path
      external: true      // true: 外部ブラウザで開く
    })
  // それ以外
  } else {
    this.$router.push(PATH)
  }
}

 WebブラウザからLIFFブラウザを開く方法

ドキュメントに記載のある通り、liff.openWindow()メソッドの外部ブラウザでの利用は、保証対象外です。そのため、jsの通常のページ遷移を行う必要があります。

location.href=URL

注意点としてはここに書くURLはアプリのフルパスではなく、LIFF URLになります。URLの詳しい設定方法はドキュメントを参考にしてください。こうすることでページ遷移をするときに、ポップアップが出て、LINEで開くかを聞いてくれるようになります。(ただ、AndroidのChromeではポップアップが出ずにそのままブラウザ内で遷移しました。要検証かもです)

以上で正常に動くQRコードリーダーが実装できます。

補足 : QRコードリーダーの実装

「以上でQRコードリーダーが実装できます。」って言ってるけどQRコード実装の部分の説明全然ないやん。と思われた方用に。
実際に実装する際に参考した記事を貼っておきます。

[HTML5] QRコードリーダーを作成する
Webの技術だけで作るQRコードリーダー