NFC + Flutter のメモ

#Introduction
関連するサービスでNFCを利用する必要があり、色々と調べていました。POCを作る場合ブラウザで使えると便利だなと思っていましたが、「ブラウザでNFCが使えるChrome 81ベータ」はまだ開発版でのみの提供だそうで、一般の人が使うにはアプリ実装が必要そう。
iOS/Androidを両対応させるためにnfc_in_flutterというpluginを使ってみるメモと、NFCに関係するちょっとした覚書です。

#Flutterで使えるNFCライブラリ

Flutterで使えるNFCライブラリはいくつか存在しているようですが、
https://pub.dev/packages?q=nfc
を見ると
iOS13のCoreNFCで実装されたWriteまでに対応しているpluginとなると選ぶ必要がありそうです。
今回は、iOSのread/write対応しているnfc_in_flutterを使ってみました。

- nfc_in_flutter
Flutter plugin to read and write NFC tags on both Android and iOS. Currently it only supports reading NDEF formatted tags.

- flutter_nfc_reader
A nfc reader plugin for iOS and Android. This plugin allow you to trigger NFC native reading session on device.

- nfc_manager
A Flutter plugin to manage the NFC features. Supported on both Android and iOS.

- flutter_nfc_kit
Plugin to provide NFC functionality on Android and iOS, including reading metadata and transceive layer 3 & 4 data with NFC tags / cards

- nfc_io
A new flutter plugin to help developers looking to use internal hardware inside Android devices (For now, iOS coming soon) for reading NFC tags.

- flutter_nfc_plugin
Flutter NFC plugin project. Allowing to start you app within an NFC tag.


#NFCの種類
NFC-A(Mifare) ISO/IEC 14443-3 Type A ...海外のカードなど
NFC-B ISO/IEC 14443-3 Type B ...マイナンバー、運転免許証
NFC-F JIS X 6319-4 ... Suicaなど(FeliCa用のHCE) (Android7.0以降)

#iOS/AndroidのNFC対応状況
Androidでは、4.4以降でAPIが用意されている、さらにNFC-Fを入れても、7.0以上で対応可能。
iOSで実装する場合は、iOS13前後で下記のような違いがあるため、確認が必要。

+ iOS13以前は、NFCのreadのみで、writeはできない
+ NDFEフォーマットのみに対応
+ NFCのUIDにはアクセスできない
+ アプリケーションは、iPhoneはXSとXRよりも最新のモデルが必要
* iPhone7モデルより新しいモデルでのみ
+ NFCチップのプロトコルに直接アクセスはできない
Peer2Perrのタグエミュレーションへのアクセスはできない
NFCのロッキングやミラrーリング、カウンターなどのオプションにはアクセスできない

(参考)
https://gototags.com/blog/apple-expands-nfc-on-iphone-in-ios-13/

#タグ

https://www.amazon.co.jp/gp/product/B079JZF91Z/ref=ppx_yo_dt_b_asin_title_o08_s00?ie=UTF8&psc=1

を購入しました。NTAG215。


#手順

iOSのinfo.plistなどに追記を行います

##ios側の設定

###1-0.Runner.xcworkspaceをXCodeで開く
<img width="204" alt="スクリーンショット 2020-04-27 15.01.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/af3ba57a-bdab-2e1e-53f3-ef608f8c8516.png">

###1-1.+Capability -> 「Near Field Communication Tag Reading」
<img width="862" alt="スクリーンショット 2020-04-27 14.51.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/1a38e152-8290-bb9b-cc1c-d1b74bed2af1.png">

###1-2.Info.plist -> 「NFCReaderUsageDescription」を追加
<img width="849" alt="スクリーンショット 2020-04-27 14.53.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/3c294b1d-df75-ee22-5b70-b92642238457.png">

	<key>NFCReaderUsageDescription</key>
	<string>For interacting with NFC tags</string>


###1-3.Runner.entitlementsに追記する

```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.developer.nfc.readersession.formats</key>
	<array>
		<string>NDEF</string>
		<string>TAG</string>
	</array>
</dict>
</plist>
```

##実装

```pubspec.yaml
dependencies:
  nfc_in_flutter: ^2.0.4

```

最低限これだけの記述でRead

```read.dart
      _stream = NFC
          .readNDEF(alertMessage: "NFCを読み込みますよー")
          .listen((NDEFMessage message) {
        for (NDEFRecord record in message.records) {
          print(record.payload);
        }
```

最低限これだけの記述でWrite


#HCEの対応は?
ホストカードエミュレーションの概要
https://developer.android.com/guide/topics/connectivity/nfc/hce?hl=ja

iOS側の制限でHCEの対応はできない様子。
https://github.com/flutter/flutter/issues/35960

>iPhone's NFC hardware is complete but iOS limits it. For example, the wallet app(Apple Pay) obviously works in card emulation mode. Apple at this moment doesn't want others to have the ability to create an NFC wallet app.


#Conclusion

NFCを使って、単純なおもちゃのようなものを作るのであれば、簡単にPOCを作ることはできそうですが、
お財布携帯みたいなモノを作りたいとなった場合、HCEなどの対応状況など今後も継続してみていく必要があるかと思いました。
例えば、「Appleが折れてまでApplePayにSuicaを例外対応させた理由　https://pipitchoice.jp/sony-apple/
」の記事にもありますが、現状のシェアや、Apple側の戦略にも密接に繋がっている様子。
今回は以上になります。