yasudacloudの日記

札幌に住むソフトウェアエンジニア

NFCのシールとカードで遊んでみた

先日Amazonで注文したNFCのチップが入ったシールとカードが届いたのでエンジニア目線でレビューしたいと思います。販売業者からの回し者ではございません。NFC初心者です。

購入したのはこちら、白の無地で薄いカードとシールなので素朴な感じです。

Amazon | ctunk nfcタグ NTAG213 144バイト (10枚入り, シールタイプ) | ctunk | スマートメディア 通販

Amazon | NFCカード NTAG215カード 白無地 ホワイトカード 10枚セット | 番号札・荷札 | 文房具・オフィス用品

NFCシールの商品情報

上記のAmazonのページに書いてありますが、

・シール型の容量は144バイト

・「できること」にURL、Bluetooth、アラーム設定など

・読み取り、書き込み回数それぞれ 100,000回まで

・読み書き距離 0.5cm〜5cm

とあります。

他には説明書記載のサポートページに「中国で大量製造してるため不良品が一定数混じることがある」ということで不良品時の対応が明記されていて手厚い印象を受けます。

NFCカードの商品情報

・サイズは一般的なクレジットカードとほぼ全く同じ

・厚みはクレカ1.5枚分くらい(体感的に)

・容量は540バイト

・1度書き込むと再書き込みできないとレビューにある(後ほど検証)

・読み込み回数は不明

・生産、販売企業が不明(販売は日本企業っぽい)

iPhoneをシールにかざすとこんな感じでローカルPUSH通知として表示されるようです。

iOSで読み取り・書き込みする

まず、NFCシールに容量144バイトとあるのでぴったり144バイト書き込みできるかを検証します。書き込みはこちらのアプリで行うと手っ取り早いですが、デバッグしたり意図的にエラーを出したいので自分で実装処理を書きます。XCodeで新規iOS Appを作成してSwiftで書いていきます。

NFCの実装は以下が参考になります。Info.plistの記述をお忘れなく。

Apple Developer Documentation

市販のNFCタグを買って遊んでみた – 野生のプログラマZ

 

まず、何気なく"abcd"という文字列を書き込んでみます。

let text = "abcd"

let textData = text.data(using: String.Encoding.utf8)!

let emptyData = Data(count: 0)

let payLoad = NFCNDEFPayload(format: .nfcWellKnown, type: emptyData, identifier: emptyData, payload: textData)

書き込み後にもう一度読み取るとpayload "abcd"が返ってきて4バイトであることを確認しました。次に、同じやり方で上限の"abcd..."と144文字(144バイト)にして書き込もうとすると、

2022-09-04 00:00:02.206776+0900 nfc_example[74191:14361212] [CoreNFC] 00000002 83a290e0 -[NFCNDEFReaderSession setAlertMessage:]:93  (null)

Optional(Error Domain=NFCError Code=402 "Insufficient space on NDEF tag" UserInfo={NSLocalizedDescription=Insufficient space on NDEF tag})

早速、容量が足りない旨のエラーが出ました。エラー原因について調べていきます。

なぜ上限144バイト書き込めないのか

タグの書き込み時に呼び出しているNFCNDEFTagクラスのqueryNDEFStatus()のコールバック引数capacity: Int にヒントがありそうです。

CoreNFCのAPIリファレンスを読むと

capacity indicates the maximum NDEF message size in bytes that can be store on the tag

とあり、capacityにはメッセージサイズの上限が格納されるようです。そしてデバッグログで見てみるとcapacity、つまりNFCシールのmessage部は137 バイトでした。

前述のtextDataを早速137バイトにして書き込みますが、こちらも上限値を超えてエラーになります。さすがにNFCの仕様を読まないと詰みそうなのでいくつか読み漁ります。

https://artfinex.co.jp/wp/wp-content/themes/artfinex/data/rfid/05.pdf

https://qiita.com/shimosyan/items/ed21fb6984240baa7397

http://sweet.ua.pt/andre.zuquete/Aulas/IRFID/11-12/docs/NFC%20Data%20Exchange%20Format%20(NDEF).pdf

どうやらmessage部はpayloadだけでなく前述のコードで使用しているtypeやidentifier、formatのサイズも含まれるようです。PCやスマホのストレージも記載通り64GBとか256GB使えるわけではないのと同じですね。

各パラメータを色々試したところ、最終的にNFCNDEFMessageのlength <= capacity が真の場合に書き込みが成功することがわかりました。

カードの方が容量多いのでギリギリまでデータを書き込んでみましたが、数十バイトの読み込みと比べると体感的にちょっと遅いかな?というくらいでした。

まとめ

wifiの読み込みがうまくいきませんでした。AndroidだとNFCタッチするだけでwifiの接続が出来るっぽいのですが、iPhoneだと即接続は無理なのかも・・?

ただ、アイディア次第でめちゃくちゃ便利なアイテムに化けそうです。他業種の友人にこういうのあるよって紹介すると結構反応良かったたので何か始めようかなーと色々考えちゃいます。

趣味要素が強めのプログラミングは楽しい♪( ´θ`)ノ