ENGINEER BLOG

ENGINEER BLOG

WebNFCを使ってみる

こんにちは、イノベーション本部の朝日です。

最近の社内システムを開発していたときにNFCを触る機会がありました。
最初はNFCへの書き込みにNFC Toolsなどを使っていたのですが、大量に書き込む必要が出てきたためサクっと自作できないか調べたところ最近ではWebNFCというブラウザのJavaScriptで操作できる機能があることがわかったため、使ってみることにしました。

はじめに

本記事執筆時点では、WebNFCは使える環境がかなり限定的でAndroidのChromeでしか使えません。
Can I use…MDN Web Docsなどで最新状況を確認してください。

またドキュメントについてもまだドラフトのようなのでこちらを参照してください。

Android Chromeのリモートデバッグ

今回のWebNFCはPCのChromeでサポートされていないため、動作を確認するにはAndroidのChrome上で動かす必要があります。
Android端末をUSBでPCに接続し、PCのChromeでchrome://inspect/#devicesにアクセスすることで、Console等の確認ができます。

サンプルコード

ほとんどMDNのExamplesの通りですが、主要部分だけ抽出して記載しています。

書き込み

const ndef = new NDEFReader();

await ndef.write("Hello, NFC!");

【解説】
①NDEFReaderをnewします。
②NDEFReaderのwriteメソッドのパラメータに書き込みたい内容をセットして実行します。

これだけでNFCへの書き込みができてしまいます。

ここではテキストを書き込みましたが、URL等他のデータタイプを書き込みたい時は、MDNのExamplesを参照して、適切なパラメータを設定したオブジェクトをwriteメソッドに渡します。

NFC write sampleを実行して正常にNFCタグに書き込めると

write

のように"write success!"と出るはずです。
※上記サンプルではブラウザ外でNFCの読み取りイベントが発生しないように、次の「読み取り」で触れるscanメソッドも実行しています。

読み取り

const ndef = new NDEFReader();

await ndef.scan();

ndef.onreading = (e) => {
    for (const record of e.message.records) {
        console.log("recordType=" + record.recordType);
        if (record.recordType == 'text') {
            const decoder = new TextDecoder();
            const data = decoder.decode(record.data);
            console.log("data=" + data);
        }
    }
}

【解説】
①NDEFReaderをnewします。
②NDEFReaderのscanメソッドを実行します。
③onreadingイベントリスナーに読み取った時の処理を記述します。

以上で、NFCタグを読み込むたびにonreadingイベントが実行されるようになります。

onreadingイベント引数のmessageNDEFMessageオブジェクトになっていて、さらにその中のrecordsNDEFRecordのリストになっています。
あとはそれぞれのrecordTypeでデータ種別を判別して、dataをデコードしたりして中身のデータを取得してください。
今回はrecordTypeがtextの時に中身をTextDecoderでデコードして表示しています。

NFC read sampleを使って先ほど書き込みしたNFCタグを読んでみると、

read

のように確認できます。

個人的にはまったポイント

httpsでないと使えない

最初Visual Studio CodeのLive Server拡張経由で表示させてテストしようとしてたのですが、ReferenceError: NDEFReader is not definedというエラーがでて動作しませんでした。
WebNFC非対応のPCのChromeで実行した時と同じメッセージなのでわかりにくいのですが、どうもhttpsアクセスが必要なようで、自己証明書を使ってSSL化すると使えるようになりました。

iframe内では使えない

今回触っていて気づいたのですが、WebNFCはiframe内では使えないようです。
いつもはJavaScriptのデモはJSFiddleを使っているのですが、iframeが使われているためかscanのタイミングで
InvalidStateError: Failed to execute 'scan' on 'NDEFReader': Web NFC can only be accessed in a top-level browsing context.
と怒られてしまいます。
自分で確認してみたい人はこちらからどうぞ。

さいごに

今回はこの技術を活用してNFCタグを連続して書き込みするツールを自作して手間を減らしました。
最近はブラウザでできることが増えてきているので機会があればまた色々と触ってみたいですね。
短いですが、今回はこんなところで。