Help us understand the problem. What is going on with this article?

NFC には A, B, F… がある【iOS Core NFC】

Core NFC Advent Calendar 2019、私としては2回目の記事になります。

iOS 13 で大幅に機能が追加され、実用的になった Core NFC ですが、そもそも NFC には大きく3つのタイプがあります。

3つの通信規格

この記事でいう NFC の3つのタイプとは、

  • NFC-A
  • NFC-B
  • NFC-F

のことを指します。また、NFC-A には MIFARE、NFC-F には FeliCa という呼称もあります。

記事タイトルと噛み合いませんが、この記事は Core NFC Advent Calendar に属するので NFC のより詳しい説明はこちらの Qiita 記事「NFC関係用語と解説」が詳しいです。

これら3つのタイプにあうプロトコルが Core NFC では提供されており、読み書きしたいタグ(カード)の規格がどのタイプなのかに合わせてコーディングしていくことになります。

それぞれのカードがどのタイプなのか

では、日本で使われているカードが上に挙げたどのタイプなのか一部列挙します。

  • NFC-A (MIFARE)
    • taspo
    • いわゆる NFC Pay
  • NFC-B
    • 運転免許証
    • パスポート
    • マイナンバーカード
    • 在留カード
    • いわゆる NFC Pay
  • NFC-F (FeliCa)
    • 交通系ICカード(Suica、PASMO、ICOCA、…etc.)
    • 電子マネーカード(SF)(楽天Edy、nanaco、WAON、…etc.)
    • 電子マネー(SF 以外)(QUICPay、iD、…etc.)

Core NFC - Tag Types

さて、Apple Developer Documentation を確認すると、Tag Types の項目は以下のようになっていることがわかります(抜粋)。

以上のプロトコルは先に上げた各 Type に対応します。

  • NFC-A (MIFARE) ⇔ protocol NFCMiFareTag or protocol NFCISO7816Tag
  • NFC-B ⇔ protocol NFCISO7816Tag
  • NFC-F (FeliCa) ⇔ protocol NFCFeliCaTag

Core NFC には protocol NFCISO15693Tag も存在し、RFID にも対応します。

使い方

この Core NFC Advent Calendar 2019 にはこれから実際にいろいろなカードを読み取ってみるというテーマの記事が公開予定なので、詳細はそちらに譲るとして、各 NFC Tag を iPhone が検出したときにどのようにデータが渡ってくるかを示します。

// class に NFCTagReaderSessionDelegate を継承させる

var readerSession: NFCTagReaderSession?

// ...

func scan() {
    self.readerSession = NFCTagReaderSession(pollingOption: [.iso14443, .iso15693, .iso18092], delegate: self, queue: nil)
    self.readerSession?.alertMessage = "Hold your iPhone near an NFC tag."
    self.readerSession?.begin()
}

// ...

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

    switch tags.first! {
    case let .iso7816(iso7816Tag):
        // iso7816Tag: NFCISO7816Tag
        break
    case let .feliCa(feliCaTag):
        // feliCaTag: NFCFeliCaTag
        break
    case let .iso15693(iso15693Tag):
        // iso15693Tag: NFCISO15693Tag
        break
    case let .miFare(miFareTag):
        // miFareTag: NFCMiFareTag
        break
    @unknown default:
        return
    }

    // ...

}

まずは NFCTagReaderSession を初期化します。上記サンプルでは .iso14443.iso15693.iso18092が指定されています。その後、NFCTagReaderSessionbegin() を呼び出すことで iPhone が NFC の読み取りモードになります。
スクリーンショット 2019-11-29 21.53.12.png
無事に iPhone が NFC Tag を見つけると NFCTagReaderSessionDelegatefunc tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) が呼び出されるので、switch文を使ってどのプロトコルに合う NFCTag が検出されたかを判定します。NFCTag は以下のように定義されています。

@available(iOS 13.0, *)
public enum NFCTag {
    case feliCa(NFCFeliCaTag)
    case iso7816(NFCISO7816Tag)
    case iso15693(NFCISO15693Tag)
    case miFare(NFCMiFareTag)

    public var isAvailable: Bool { get }
}

各カードがどの NFCTag であるかを特定できたら、その後は NFCTagReaderSessionconnect(to:completionHandler:) を使ってタグにアクセスしていきます。

次回以降はいよいよ実際のカードをどのようにして読み取っていくかを紹介します。

参照

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away