📡

【iOS】Core NFC入門 - NDEFメッセージの読み込み

2024/01/29に公開


Core NFCはNFCタグに書き込まれているデータの読み書きを行う機能を提供するフレームワークです。Core NFCを使用することで、NFCタグから読み込んだデータを画面に表示したり、アプリ内で入力したデータをNFCタグに書き込むことができます。
本記事では、Core NFCを使用して、NFCタグに書き込まれているNDEFフォーマット形式メッセージ (以降からNDEFメッセージと呼びます)の読み込みを行う方法について説明します。
本記事を最後までお読みいただくことで、NFCタグに書き込まれているNDEFメッセージの読み込み機能を実装することができるようになります。

事前知識

実装方法の説明を行う前に、Core NFC周りでよく出てくるキーワードについて説明します。

NFC

短距離無線通信技術の一種で、近距離でデバイス同士が通信するための技術です。デバイス間が物理的に接触するか、非常に近い距離にある場合に通信が行われます。NFCはNear Field Communicationの略称です。

NFCタグ

NFCを使用してデータを送受信するためのデバイスです。NFCに対応しているiPhoneをNFCタグにかざすだけで、NFCタグに書き込まれているデータを読み込んだり、NFCタグにデータを書き込むことができます。

NDEF

NFCでデータを交換するための標準的なフォーマットです。この標準的なフォーマットが定義されていることで、異なるアプリケーションやデバイス間で同じ形式のデータをやり取りすることができます。 NDEFはNFC Forumで定義されています。
https://nfc-forum.org

事前準備

NFCタグの準備

今回は以下のNFCタグを使用します。
https://www.switchbot.jp/products/switchbot-nfc-tag

Entitlementの追加

[Signing & Capabilities] -> [+Capability]から、「Near Field Communication Tag Reading」を追加します。

info項目の編集

info項目一覧のKeyに「Privacy - NFC Scan Usage Description」を追加し、対応するValueにNFCタグを検出する理由を記載します。

実装

NFCタグの検出

NFCNDEFReaderSession は、NDEFフォーマットに対応したNFCタグを検出するためのリーダーセッションクラスです。このクラスを使用して、NDEFフォーマットに対応したNFCタグを検出します。

NFCNDEFReaderSessionreadingAvailable で、アプリを起動しているiPhoneがNFCタグを検出する機能をサポートしているかどうかを確認することができます。

init(delegate:queue:invalidateAfterFirstRead:)NFCNDEFReaderSession オブジェクトを初期化します。引数にはNFCタグ検出時にコールされるデリゲートメソッドの委譲先、デリゲートメソッドがディスパッチされるキュー、最初にNFCタグをスキャンすることに成功した後、リーダーセッションを自動的に無効にするかどうかをBool 値で指定します。

alertMessage でNFCタグ検出処理が開始する際に表示される、ハーフモーダルに表示するメッセージを指定します。
begin()でリーダーセッションが開始し、NFCタグ検出処理が行われます。この時、iPhoneをNFCタグにかざすことを促すハーフモーダルが表示されます。

NFCNDEFReaderSessionDelegate プロトコル

NFCNDEFReaderSession のイニシャライザで指定した委譲先のクラスを、NFCNDEFReaderSessionDelegate プロトコルに準拠させます。
NFCNDEFReaderSessionDelegate プロトコルには、NFCタグ検出時の様々なリーダーセッションイベントを処理するためのデリゲートメソッドが定義されています。
https://developer.apple.com/documentation/corenfc/nfcndefreadersessiondelegate

NFCタグ検出後の処理を実装する前に、NFCNDEFReaderSessionDelegate プロトコルで定義されているデリゲートメソッドを確認しましょう。

readerSessionDidBecomeActive(_:)
readerSession(_:didDetectNDEFs:)
readerSession(_:didDetect:)
readerSession(_:didInvalidateWithError:)

readerSessionDidBecomeActive(_:)

リーダーセッションがアクティブになった時にコールされるメソッドです。

readerSession(_:didDetectNDEFs:)

リーダーセッションがNFCタグを検出した時にコールされるメソッドです。NDEFメッセージの読み込み機能のみを実現したい時に定義します。readerSession(_:didDetect:) を定義しても、NDEFメッセージの読み込み機能を実現することができますが、readerSession(_:didDetectNDEFs:)を使用した方が、短いコードで読み込み機能を実現することができます。

readerSession(_:didDetect:)

リーダーセッションがNFCタグを検出した時にコールされるメソッドです。
NDEFメッセージの読み込み機能に加えて、書き込み機能を実現したい時に定義します。書き込み機能の実装方法については、別の記事で説明していますので必要に応じてご参照ください。

readerSession(_:didInvalidateWithError:)

リーダーセッションが無効になった時にコールされるメソッドです。何らかのエラーが発生し、リーダーセッションが中断された時や、リーダーセッションが完了したときにコールされます。

NDEFメッセージの読み込み

NDEFメッセージを読み込む処理は、readerSession(_:didDetectNDEFs:)readerSession(_:didDetect:) のいずれかで定義します。

readerSession(_:didDetectNDEFs:) の定義

NDEFメッセージの読み込み機能のみを実現したい時は、readerSession(_:didDetectNDEFs:) を定義します。引数のmessages からNFCタグに書き込まれているNDEFメッセージを抽出します。

NFCNDEFMessage は、NDEFメッセージを表現するクラスです。NFCNDEFMessagerecordsNFCNDEFPayload の配列が格納されており、NFCNDEFPayloadtypeNameFormat でペイロードのタイプを取得することができます。URIやテキストデータが格納されているペイロードタイプは.nfcWellKnown です。
ペイロードのタイプはNFCTypeNameFormat で以下のように定義されています。

ペイロードタイプが.nfcWellKnownNFCNDEFPayload オブジェクトから、テキストデータやURIを取得することができます。

NFCタグ検出中に表示されるハーフモーダルは、NFCTagReaderSessioninvalidate() で閉じることができます。invalidate(errorMessage:) を使用すると、ハーフモーダルに警告マークと引数に指定したメッセージを表示した後に、ハーフモーダルを閉じることができます。

readerSession(_:didDetect:) の定義

NDEFメッセージの読み込み機能に加えて、書き込み機能を実現したい時は、readerSession(_:didDetect:) を定義します。
引数のtags でタグを受け取り、NFCNDEFReaderSessionconnect(to:completionHandler:) でタグをリーダーセッションに接続します。

NFCNDEFTagqueryNDEFStatus(completionHandler:) で検出したタグのステータスを確認し、タグがNDEFメッセージの読み込みをサポートしていることを確認した後に、NDEFメッセージの読み込み処理を行います。

タグのステータスはNFCNDEFStatus で以下のように定義されています。

.notSupported は、NFCタグがNDEFフォーマットに対応していないことを、.readWrite は、NDEFメッセージの読み書きをサポートしていることを、.readOnly は、NDEFメッセージの読み込みのみ対応していることを示します。つまり、ndefStatus.readWrite.readOnly の時に、NDEFメッセージの読み込み処理を行うことができます。

NFCNDEFTagreadNDEF(completionHandler:) で、NFCNDEFMessage オブジェクトを取得します。

取得したNFCNDEFMessage オブジェクトをString 型に変換し、View 側に渡すことでNDEFメッセージを画面に表示することができるようになります。

今回はCore NFCを使用して、NFCタグに書き込まれているNDEFメッセージを読み込む方法について説明しました。次回は、NFCタグにNDEFメッセージを書き込む方法について説明します。

サンプルコード

https://github.com/NAOYA-MAEDA-DEV/CoreNFCSampler.git

参考資料

・Core NFC Enhancements
https://developer.apple.com/videos/play/wwdc2019/715/

Discussion