NFCタグを読み込めるiOSアプリを作ろうとしてつまづいた話

# はじめに
こちらの記事は[フリューアドベントカレンダー](https://qiita.com/advent-calendar/2024/furyu)19日目の記事になります。  

こんにちは。  
ピクトリンク事業部開発部の里形と申します。 

先日、とあるお店でスマホに物理デバイスを近づけてスタンプを押すアプリを見て、とても面白かったため自身でも実現してみたいと思いました。  
おそらくNFCタグを利用して作られていると考えたため、今回はNFCタグをiPhoneで読み込めるアプリを実装してみようとしましたが...問題が発生したため、今回はその問題と解決方法に関して解説しようと思います。
結論から申しますと、Core NFCというライブラリを使って実装する際は**Apple Developer Programに加入することが必須**となっていたことが原因でした。

まずは、 NFCに関連する内容を説明し、その後にどのような問題が発生したかを説明して行きます。

# NFC関係の説明
## NFCとは
NFCはNear Field Communicationの略で、日本語では近距離無線通信と呼ばれるものです。
ISOが規定している近距離無線通信規格のことをさし、対応している端末や機器同士を近づけるだけで、認証やデータ通信を行うことができます。
また、カードやタグなど電源を持たない機器に対しても読み込みと書き込み両方の処理を行える点が強みです。
身近な例としては、交通系ICカードと改札の関係などが挙げられます。

## Core NFCとは
iOSやiPadOSなどの端末でNFC関係の実装をする際は、Appleが提供するCoreNFCというライブラリを使うことが一般的です。

https://developer.apple.com/documentation/corenfc

Core NFCを使用するとNFC Data Exchange Format（NDEF）を含んだ5種類のTypeのタグに書き込みおよび読み込みを行うことができます。
また、Core NFCを含んだアプリを使うにはNFCをサポートした端末が必須になります。
iOSに関して言えば、iOS13以上を搭載したiPhone7以降の機種にあたります。

## NDEFとは
先ほど述べた通りNFCには複数のデータ形式が存在しており、それらのタグを共通化して使用するために規定されたデータ形式がNDEFと呼ばれています。
電源を持たないタグなどのNFCデバイスでは、読み取りに合わせてデータを変形させることはできないため、互換性を保つために使用するデータはNDEFの形式を利用することが推奨されています。

https://nfc-forum.org/build/specifications

## Human Interface Guideline(HIG)に記載されている注意点
HIGに記載されている注意点としては以下の3つが記載されています。
### スキャンするデバイスを接触するように促さない
NFCタグは非接触デバイスのため、端末に直接触れる必要はありません。
そのため、「スキャンする」や「かざす」などの接触する要素が含まれない言葉を使うべきと述べられています。

### ユーザーに馴染みのある言葉を使う
NFCあるいは近距離無線通信などの言葉を聞いたことがないユーザーを考慮して、ほとんどのユーザーが理解できる日常用語で説明するべきと述べられています。
例えば、「NFCタグをスキャンしてください」ではなく、「ICカードをスキャンしてください」などの表現にするなどです。

### スキャンシートの説明文は簡潔にする
Core NFCを使用した実装では、NFCを読み取る時にスキャンシートと呼ばれるハーフモーダルが表示されます。
このスキャンシートにより、タグを読み取るタイミングを明示したり、対象を明確にしたりできます。
そのため、スキャンシートにはわかりやすく簡潔で適切な文章を表示させることが推奨されています。

https://developer.apple.com/design/human-interface-guidelines/nfc

# Core NFCを使う上での注意点
ここからは、私が実際にCore NFCを用いた実装をする中でつまづいた点を説明していきます。
Core NFCを含めたアプリを実機でビルドするためには、TARGETのCapabilityにNear Field Communication Tag Readingを設定する必要があります。
Capabilityは以下の画像に表示されている **+ Capability** のボタンから設定ができます。

<figure class="figure-image figure-image-fotolife mceNonEditable" title="キャプショn"><p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989508/a0fad71c-16df-95bb-63ac-cc3ea9ec6d6b.png" width="348" height="400" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p></figure><br/>

ボタンを押すと、下記のような画面が表示され、Near Field Communication Tag Readingの項目を追加できます。
<figure class="figure-image figure-image-fotolife mceNonEditable" title="キャプショn"><p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989508/93889d96-b026-e852-6234-4f3f2335bfdd.png" width="348" height="400" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p></figure><br/>

しかし、画像の下側に表示されているエラーの通り、development teamに所属していない状態では使用することができません。
使用するためには、Provisioning ProfileにNear Field Communication Tag Readingを使用する設定を追加しなければならないからです。
Provisioning ProfileはApple Developerのサイトで設定をする必要があり、Certificates, Identifiers & ProfilesのIdentifiersの項目で設定ができます。
設定の画面は下記の画像のような形になっており、Capabilitiesの項目内に存在しています。
<figure class="figure-image figure-image-fotolife mceNonEditable" title="キャプショn"><p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989508/86ccb74a-e3a2-42b2-1240-37d11c864d99.png" width="348" height="400" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p></figure><br/>

しかし、ここでも問題点がありました。
通常のApple Developerとしてdevelopment teamに所属しているだけでは、Near Field Communication Tag Readingの選択肢は表示されなくなっています。
その理由は、Apple Developerのメンバーシップの種類によって利用できる機能が異なっているためです。

https://developer.apple.com/jp/help/account/reference/supported-capabilities-ios/

そのため、Core NFCを使用した開発を行うには、有料プログラムのメンバーになる必要があります。
そのほかにもSiriやSign in with Appleなど、多くの機能がメンバーシップ加入者のみ利用できる機能になっています。
実装したいアプリがある場合は、一度上記のリファレンスをチェックしてみることをお勧めします。

# まとめ
iOSアプリでNFCリーダーを実装するためにCore NFCを利用することが多いと思いますが、動作確認をするためにはApple Developer Programのメンバーシップに加入する必要があります。
今回、私は実装まで行ったのですが、利用できる機能制限に気づかなかったため本記事では紹介することが叶いませんでした。
個人でアプリをリリースする機会があれば、実装したコードが正しく動くか確認してみたいと思います。

私のような悲しいできことが起こらないためにも、実装前の方にこの記事が目につくことを祈っています。