iOS13のCoreNFCを使ってみた。


CoreNFCって?

iOS11とiPhone7以降の端末でNFCタグを読み込むことはできるようになりました。でも、扱えたのはシールなんかでよくあるNFCタグの読み取りだけで、みんなが使いたいICカードはダメだったんですね。
しかし2019年のiOS13では(まだ一部の制限はあるとはいえ)ICカードも読み書きできるようになったんです。その機能をアプリ開発者に公開しているインターフェイスがCoreNFCです。
iOS13とXcode11の正式版が公開されたので、ちょっと使ってみました。

開発環境

そしてその機能使うには
・iPhoneとしてはiPhone7以降
・開発環境としてはXcode11
が必要になります。
もちろん、シミュレータでは動作しません。

準備

Xcode11のプロジェクト設定の「Signing & Capabilities」->「+Capability」ボタンを押します。(グレーっぽい色なのでDisable状態かと思いきや押せます。)

そして「Near Field Communication Tag Reading」をダブルクリックして追加します。

実装

まずはライブラリを読み込みます。

import CoreNFC

実装するクラスにCoreNFCのリード用デリゲートNFCTagReaderSessionDelegateを追加します。
メソッドは3つですので、全て実装しましょう。

func tagReaderSessionDidBecomeActive(_ session: NFCTagReaderSession) {
}
func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
}
func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) {
}

次にNFCを読み込むセッションのオブジェクトを生成します。
この時、読み込むNFCカードがType A/BかType Fかで引数が変わります。とは言え、ヘッダに情報が記載されているので迷うことはないですね。
Type A/B

let session = NFCTagReaderSession(pollingOption: .iso14443, delegate: self)

Type F

let session = NFCTagReaderSession(pollingOption: .iso18092, delegate: self)

オブジェクトを生成したらもう実行するだけです。
メッセージも追加しておきます。

session.alertMessage = "スキャン中"
session.begin()

終了処理も追加しておきましょう。例ってことで、読み込みが成功した時に呼ぶようにしてみます。

func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
    session.invalidate()
}

NFC

これでNFCが使えるようになっていればすごく楽にアプリが作れるんですが、ここからちょっとした手間がかかります。
プロジェクトの設定で「info」タブを開きます。
Type A/Bを扱いたいときは「ISO7816 application identifiers for NFC Tag Reader Session」
Type Fを扱いたいときは「ISO18092 system codes for NFC Tag Reader Session」
を追加します。
そして、追加したものにさらにItemを追加します。
ここが一番つまずいたところなんですが、Type A/BならAID、Type FならSystem Codeを設定する必要があります。
しかもその値はカードの仕様によって違うので結構大変です。
最も簡単にこの値を知りたかったらAndroidアプリで調べちゃうのがオススメです。
Type Fなら0003FE00を入れておけば大体いけるみたいです。

実行

ちょっと面倒なこともありましたが、実行するとこんな画面が表示され、iPhone本体裏面ちょっと上あたりにカードを当てると読み取ることができます。

まとめ

CoreNFC自体はとっても簡単に扱えることがわかりました。
でも、実際にICカードを読むにはカード自体の仕様を知る必要がありますし、まだまだこれからですね。