Core NFCの整理記事(2)

前回の記事ではCore NFCに関してできることなどを整理してみました。

NFCタグへデータを読み書きする事ができる事がわかったので今回はサンプルコードを見つつ最小限で実装してみます。
サンプルコードに関しては以下のドキュメントにあります。

サンプルコードはUIKitで構成されているが後々SwiftUIでも使用できるようにNFCタグへの読み書き機能は切り出して実装していきます。
以下実装手順です。

1. 準備

TARGETS -> +Capability -> Near Field Communication Tag Readingを追加

追加後、info.plistにPrivacy - NFC Scan Usage Descriptionを追加し、適当な説明を記載

2. 実装

Core NFCをimportして実際に読み取る実装を行う

import CoreNFC

final class NFCSession: NSObject, NFCNDEFReaderSessionDelegate {
    private var session: NFCNDEFReaderSession?
 
    func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {

    }
    
    func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {

    }
    
    func beginScanning() {
        guard NFCNDEFReaderSession.readingAvailable else {
                   return
               }
               session = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: false)
               session?.begin()
    }
}

func readerSession…に関してはNFCNDEFReaderSessionDelegateを準拠した時点で必須のメソッドとなり自動で生成されます。
とりあえず空にしておきます。
重要なのはbegin()を実行しているbeginScanning() で、これさえ叩けばNFCを実装してみる最初の一歩である、Scan画面を表示させることができます。

適当に画面を作って、ボタンタップなどでbeginScanning()を叩けば以下の画面がでます。

以上がCore NFCを実装する最初の基本的な実装手順です。
beginScanning内の実装に関しては以下の通り。

NFCNDEFReaderSession.readingAvailable

デバイスがそもそもNFCを使用できるか判断してBoolで返却

NFCNDEFReaderSession

NDEFタグを検出するためのリーダー セッションでsession = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: false)で初期化してます。

queueがnilの場合はコールバックはメインスレッド/キューで実行されます。
invalidateAfterFirstReadは初めにNDEF タグが正常に読み取られた後にセッションを自動的に無効にするかをBoolで指定でき、trueなら読み取りが完了したらセッションが自動的に無効となり、終了します。
falseならセッションが自動で無効とならず、連続で読み取りが可能です。
セッションを終了したい時は表示されているハフモーダル?画面のキャンセルをタップしてセッションを無効にするかタイムアウトするまで待つことでセッションを終了することができます。以下

上記はinvalidateAfterFirstReadをfalseにした状態の様子です。

session?.alertMessageを追加するとScanを開始した時に表示される画面に表示する文言を定義することができます。

session?.alertMessage = "NFCタグに近づけてください"

UIを変更できるAPIは今のところalertMessageのみのようです。
とりあえず最小限の実装はできたのでここまで。

いいねと思えたらよろしくお願いします😋